【问题标题】:How to force abort on "glibc detected *** free(): invalid pointer"如何强制中止“glibc检测到*** free():无效指针”
【发布时间】:2010-09-14 03:44:35
【问题描述】:

在Linux环境下,当出现“glibc检测到*** free():无效指针”错误时,如何识别是哪一行代码导致的?

有没有办法强制中止?我记得有一个 ENV var 来控制这个?

如何在gdb中为glibc错误设置断点?

【问题讨论】:

  • 我认为这个问题需要不同的答案取决于具体的系统,它不限于Linux(例如OpenBSD,OSX)。

标签: linux memory-management glibc


【解决方案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 使其生效?
      猜你喜欢
      • 2013-08-01
      • 2012-05-04
      • 1970-01-01
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      • 2016-03-27
      • 2016-03-28
      • 1970-01-01
      相关资源
      最近更新 更多