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