Как принудительно отключить "обнаруженный 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));