Как принудительно прервать «обнаружен glibc *** free (): неверный указатель» - PullRequest
16 голосов
/ 30 сентября 2008

В среде Linux, когда появляется сообщение об ошибке «glibc обнаружено *** free (): неверный указатель», как определить, какая строка кода вызывает его?

Есть ли способ вызвать прерывание? Я помню, что был ENV var для управления этим?

Как установить точку останова в gdb для ошибки glibc?

Ответы [ 4 ]

16 голосов
/ 30 сентября 2008

Я полагаю, что если вы установите MALLOC_CHECK_ в 2, glibc вызовет abort(), когда обнаружит ошибку «free (): неверный указатель». Обратите внимание на заключительное подчеркивание в имени переменной среды.

Если MALLOC_CHECK_ равен 1, glibc выведет «free (): неверный указатель» (и аналогичные printfs для других ошибок). Если MALLOC_CHECK_ равно 0, glibc молча игнорирует такие ошибки и просто возвращает. Если MALLOC_CHECK_ равен 3, glibc напечатает сообщение и затем вызовет abort(). То есть это битовая маска.

Вы также можете вызвать mallopt(M_CHECK_ACTION, arg) с аргументом 0-3 и получить тот же результат, что и с MALLOC_CHECK_.

Поскольку вы видите сообщение «free (): неверный указатель», я думаю, что вы уже устанавливаете MALLOC_CHECK_ или вызываете mallopt(). По умолчанию glibc не печатает эти сообщения.

Что касается отладки, установка обработчика для SIGABRT, вероятно, является наилучшим способом продолжения. Вы можете установить точку останова в своем обработчике или преднамеренно вызвать дамп ядра.

7 голосов
/ 30 сентября 2008

Я рекомендую вам получить valgrind:

valgrind --tool = memcheck --leak-check = full ./a.out

3 голосов
/ 30 сентября 2008

Как установить точку останова в GDB?

(gdb) b имя файла: белье // например b main.cpp: 100

Есть ли способ вызвать прерывание? Я помню, что был ENV var для управления этим?

У меня сложилось впечатление, что оно прервано по умолчанию. Убедитесь, что у вас установлена ​​отладочная версия.

Или используйте libdmalloc5: «Снижение замены системных malloc', realloc ', calloc', free» и других процедур управления памятью, предоставляя мощные средства отладки настраивается во время выполнения. Эти средства включают в себя такие вещи, как отслеживание утечки памяти, обнаружение записи после забора, отчет о номере файла / строки и общая регистрация статистики. "

Добавьте это к вашей команде ссылки

-L/usr/lib/debug/lib -ldmallocth

GDB должен автоматически вернуть управление, когда glibc запускает прерывание.

Или вы можете настроить обработчик сигнала для SIGABRT, чтобы выгружать трассировку стека в fd (дескриптор файла). Ниже mp_logfile является ФАЙЛОМ *

void *array[512 / sizeof(void *)]; // 100 is just an arbitrary number of backtraces, increase if you want.
size_t size;

size = backtrace (array, 512 / sizeof(void *));
backtrace_symbols_fd (array, size, fileno(mp_logfile));
3 голосов
/ 30 сентября 2008

В общем, похоже, вам, возможно, придется перекомпилировать glibc, тьфу.

Вы не говорите, в какой среде вы работаете, но если вы можете перекомпилировать свой код для OS X, то его версия libc имеет функцию free (), которая прослушивает эту переменную среды:

MallocErrorAbort             If set, causes abort(3) to be called if an
                              error was encountered in malloc(3) or
                              free(3) , such as a calling free(3) on a
                              pointer previously freed.

Справочная страница free () на OS X содержит больше информации.

Если вы работаете в Linux, попробуйте Valgrind , он может найти ошибки, которые невозможно найти.

...