如何强制中止“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():无效指针”的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 视频:强制中止缓冲

AppDomain.Unload() 如何中止线程?

退出、中止、休眠以进行调试?

如何确定一个软件的测试结束点

使用 memset() 获取“中止陷阱 6”

c#多线程