在Linux环境中,当获取“glibc *** free():无效指针”错误时,如何识别导致它的代码行?
有没有办法强迫中止?我记得有一个ENV var可以控制它吗?
如何在gdb中为glibc错误设置断点?
答案 0 :(得分:16)
我相信如果你将MALLOC_CHECK_
设为2,glibc会在检测到“free():invalid pointer”错误时调用abort()
。请注意环境变量名称中的尾随下划线。
如果MALLOC_CHECK_
为1,则glibc将打印“free():无效指针”(以及其他错误的类似printfs)。如果MALLOC_CHECK_
为0,glibc将默默忽略此类错误并返回。如果MALLOC_CHECK_
为3,则glibc将打印该消息,然后调用abort()
。即它是一个位掩码。
您也可以使用0-3的参数调用mallopt(M_CHECK_ACTION, arg)
,并获得与MALLOC_CHECK_
相同的结果。
由于您看到“free():无效指针”消息,我认为您必须已经设置MALLOC_CHECK_
或致电mallopt()
。默认情况下,glibc不会打印这些消息。
至于如何调试它,为SIGABRT
安装处理程序可能是最好的方法。您可以在处理程序中设置断点或故意触发核心转储。
答案 1 :(得分:7)
我建议你得到valgrind:
valgrind --tool = memcheck --leak-check = full ./a.out
答案 2 :(得分:3)
一般来说,看起来你可能不得不重新编译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.
OS X上free()的手册页有更多信息。
如果您使用的是Linux,请尝试Valgrind,它可以找到一些不可避免的错误。
答案 3 :(得分:3)
如何在gdb中设置断点?
(gdb)b filename:linenumber //例如b main.cpp:100
有没有办法强迫中止?我记得有一个ENV var可以控制它吗?
我的印象是它默认中止了。确保安装了调试版本。
或者使用libdmalloc5:“替换系统的malloc',
realloc',calloc',
free'和其他内存管理例程,同时提供强大的调试功能
可在运行时配置。这些设施包括内存泄漏跟踪,围栏后写入检测,文件/行号报告以及统计数据的一般记录。“
将此添加到您的链接命令
-L/usr/lib/debug/lib -ldmallocth
当glibc触发中止时,gdb应自动返回控制。
或者您可以为SIGABRT设置信号处理程序,以将堆栈跟踪转储到fd(文件描述符)。下面,mp_logfile是一个FILE *
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));