如何强制中止“glibc检测到*** free():无效指针”
Posted
技术标签:
【中文标题】如何强制中止“glibc检测到*** free():无效指针”【英文标题】:How to force abort on "glibc detected *** free(): invalid pointer" 【发布时间】:2010-09-14 03:44:35 【问题描述】:在Linux环境下,当出现“glibc检测到*** free():无效指针”错误时,如何识别是哪一行代码导致的?
有没有办法强制中止?我记得有一个 ENV var 来控制这个?
如何在gdb中为glibc错误设置断点?
【问题讨论】:
我认为这个问题需要不同的答案取决于具体的系统,它不限于Linux(例如OpenBSD,OSX)。 【参考方案1】:一般来说,看起来你可能需要重新编译 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,它可以找到一些不可能找到的错误。
【讨论】:
【参考方案2】:如何在gdb中设置断点?
(gdb) b 文件名:行号 // 例如b main.cpp:100
有没有办法强制中止?我记得有一个 ENV var 来控制这个?
我的印象是它默认中止了。确保您已安装调试版本。
或者使用libdmalloc5:"drop in替代系统的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));
【讨论】:
【参考方案3】:我建议你使用 valgrind:
valgrind --tool=memcheck --leak-check=full ./a.out
【讨论】:
您将进行多次运行,因此请让 valgrind 根据当前时间输出到文件名。 valgrind--tool=memcheck --leak-check=full --log-file=date +%s
-vg.txt ./a.out【参考方案4】:
我相信如果你将env MALLOC_CHECK_
设置为2,glibc 会在检测到“free(): invalid pointer”错误时调用abort()
。注意环境变量名称后面的下划线。
如果MALLOC_CHECK_
为 1,glibc 将打印“free(): invalid pointer”(以及其他错误的类似 printfs)。如果MALLOC_CHECK_
为0,glibc 将默默地忽略此类错误并简单地返回。如果MALLOC_CHECK_
是3 glibc 将打印消息然后调用abort()
。 IE。它是一个位掩码。
你也可以调用mallopt(M_CHECK_ACTION, arg)
,参数为0-3,得到与MALLOC_CHECK_
相同的结果。
既然您看到“free(): invalid pointer”消息,我想您一定已经在设置MALLOC_CHECK_
或调用mallopt()
。默认情况下,glibc 不会打印这些消息。
至于如何调试它,为SIGABRT
安装处理程序可能是最好的方法。您可以在处理程序中设置断点或故意触发核心转储。
【讨论】:
在哪里可以设置 MALLOC_CHECK 使其生效?以上是关于如何强制中止“glibc检测到*** free():无效指针”的主要内容,如果未能解决你的问题,请参考以下文章