16

In Linux environment, when getting "glibc detected *** free(): invalid pointer" errors, how do I identify which line of code is causing it?

Is there a way to force an abort? I recall there being an ENV var to control this?

How to set a breakpoint in gdb for the glibc error?

4

4 回答 4

16

我相信如果你将环境设置MALLOC_CHECK_为 2,glibc 会abort()在检测到“free(): invalid pointer”错误时调用。请注意环境变量名称中的尾随下划线。

如果MALLOC_CHECK_为 1,glibc 将打印“free(): invalid pointer”(以及类似的 printfs 用于其他错误)。如果MALLOC_CHECK_为 0,glibc 将默默地忽略此类错误并简单地返回。如果MALLOC_CHECK_是 3 glibc 将打印消息然后调用abort(). 即它的位掩码。

您也可以mallopt(M_CHECK_ACTION, arg)使用 0-3 的参数进行调用,并获得与使用相同的结果MALLOC_CHECK_

由于您看到“free(): invalid pointer”消息,我认为您一定已经在设置MALLOC_CHECK_或调用mallopt(). 默认情况下 glibc 不打印这些消息。

至于如何调试它,安装处理程序SIGABRT可能是最好的方法。您可以在处理程序中设置断点或故意触发核心转储。

于 2008-09-30T02:38:47.413 回答
7

我建议你获得 valgrind:

valgrind --tool=memcheck --leak-check=full ./a.out

于 2008-09-30T02:26:17.520 回答
3

In general, it looks like you might have to recompile glibc, ugh.

You don't say what environment you're running on, but if you can recompile your code for OS X, then its version of libc has a free() that listens to this environment variable:

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.

The man page for free() on OS X has more information.

If you're on Linux, then try Valgrind, it can find some impossible-to-hunt bugs.

于 2008-09-30T00:20:19.977 回答
3

如何在gdb中设置断点?

(gdb) b 文件名:行号 // 例如 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));
于 2008-09-30T00:32:00.027 回答