如何在" glibc检测到*** free():无效指针"上强制中止

时间:2020-03-06 14:54:08  来源:igfitidea点击:

在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安装处理程序。我们可以在处理程序中设置断点或者故意触发核心转储。