如何在" glibc检测到*** free():无效指针"上强制中止
在Linux环境中,当出现" glibc检测到*** free():无效指针"错误时,如何确定是哪一行代码引起的?
有办法强制中止吗?我记得有一个ENV变量来控制吗?
如何在gdb中为glibc错误设置断点?
解决方案
通常,我们可能不得不重新编译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,它会发现一些无法发现的错误。
How to set a breakpoint in gdb?
(gdb)b文件名:行号
//例如b main.cpp:100
Is there a way to force an abort? I recall there being an ENV var to control this?
我的印象是它默认中止。确保已安装调试版本。
或者使用libdmalloc5:"替换系统的malloc,realloc,calloc,free和其他内存管理例程,同时提供强大的调试功能
可在运行时配置。这些功能包括诸如内存泄漏跟踪,篱笆柱写检测,文件/行号报告和常规统计记录之类的东西。"
将此添加到链接命令
-L/usr/lib/debug/lib -ldmallocth
当glibc触发异常终止时,gdb应该自动返回控制权。
或者,我们可以为SIGABRT设置信号处理程序,以将stacktrace转储到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));
我建议我们使用valgrind:
valgrind --tool = memcheck --leak-check = full ./a.out
我相信,如果将" MALLOC_CHECK_"设置为2,则glibc在检测到" free():invalid指针"错误时会调用abort()
。注意环境变量名称中的下划线。
如果MALLOC_CHECK_
为1,则glibc将打印" free():无效的指针"(以及其他错误的类似printfs)。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。如果MALLOC_CHECK_
为0,则glibc将静默忽略此类错误并仅返回。如果MALLOC_CHECK_
为3,则glibc将打印消息,然后调用abort()
。 IE。它是一个位掩码。
我们还可以使用参数0-3调用mallopt(M_CHECK_ACTION,arg)
,并获得与MALLOC_CHECK_
相同的结果。
因为我们看到" free():无效指针"消息,所以我认为我们必须已经设置了" MALLOC_CHECK_"或者调用了" mallopt()"。默认情况下,glibc不打印这些消息。
至于调试方法,最好为SIGABRT安装处理程序。我们可以在处理程序中设置断点或者故意触发核心转储。