Фатальная ошибка отладки - allo c: недопустимый блок: 0000000001F00AEF0: 0 0 - PullRequest
0 голосов
/ 12 февраля 2020

У меня есть GUI, написанный на R, который использует пакет Tcl / TK, а также C .dll, который также использует библиотеку Tcl. Я провел некоторое исследование по этому вопросу, и, похоже, оно связано с памятью. Я неопытный программист, поэтому я не уверен, где мне следует искать эту проблему с памятью. Каждый вызов malloc() имеет соответствие free() и то же самое с аналогичными Tcl_Alloc() и Tcl_Free(). Эту ошибку также очень трудно воспроизвести, поэтому я боюсь, что не смогу привести воспроизводимый пример, так как она носит, казалось бы, случайный характер. Однако существует одна закономерность: кажется, что это происходит только после закрытия программы, хотя это очень противоречиво.

Создавая этот пост, я надеюсь получить логический процесс, который следует предпринять при попытке отладить эту проблему в общем контексте в приложениях Tcl / Tk - C - R. Я не ищу решение, определяющее c моего кода, а скорее о том, о чем должен думать человек, сталкиваясь с этой проблемой.

1 Ответ

1 голос
/ 12 февраля 2020

Сообщение приходит от функции 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 (отсюда и название специального символа), чтобы увидеть, какой тип ошибок выходит за границы; они очень хорошо выслеживают подобные проблемы.

...