Сообщение приходит от функции Ptr2Block()
в tclThreadAlloc.c
(или есть что-то еще, что выдает такое же сообщение об ошибке; возможно, но маловероятно), которое является указателем потока в c, определяемым потоком (который широко используется внутри Tcl для уменьшения количества срабатываний глобальных блокировок). В частности, это бит:
if (blockPtr->magicNum1 != MAGIC || blockPtr->magicNum2 != MAGIC) {
Tcl_Panic("alloc: invalid block: %p: %x %x",
blockPtr, blockPtr->magicNum1, blockPtr->magicNum2);
}
Проблема? Эти нули должны быть MAGIC
(что равно 0xEF
). Это указывает на то, что что-то перезаписало метаданные блока памяти - которые также должны включать размер блока, но это, скорее всего, горячий мусор - и целостности памяти программы больше нельзя доверять. Увы, на данный момент мы имеем дело с программой в неисправном состоянии, где поломка произошла некоторое время назад; место, где произошла пани c, это просто место, где обнаружение ошибки произошло, а не фактическое местоположение ошибки.
Дальнейшая отладка обычно выполняется сборка версии all с выключенными причудливыми распределителями памяти (в коде Tcl это делается путем определения символа PURIFY
при сборке) и последующим запуском результирующего кода, который, как мы надеемся, все еще имеет ошибку, с инструмент, подобный electricfence
или purify
(отсюда и название специального символа), чтобы увидеть, какой тип ошибок выходит за границы; они очень хорошо выслеживают подобные проблемы.