Как принудительно отключить "обнаруженный glibc *** free(): неверный указатель"

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

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

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

Ответы

Ответ 1

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

Если 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(): invalid pointer", я думаю, вы уже должны установить MALLOC_CHECK_ или вызвать mallopt(). По умолчанию glibc не печатает эти сообщения.

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

Ответ 2

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

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

Ответ 3

В общем, похоже, что вам придется перекомпилировать glibc, ugh.

Вы не говорите, в какой среде вы работаете, но если вы можете перекомпилировать свой код для 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, он может найти ошибки, недоступные для поиска.

Ответ 4

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

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

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

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

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

Добавьте это в свою команду связи

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

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

Или вы можете настроить обработчик сигнала для SIGABRT, чтобы сбрасывать stacktrace в 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));