【问题标题】:GCC memory leak detection equivalent to Microsoft crtdbg.h?GCC内存泄漏检测相当于微软crtdbg.h?
【发布时间】:2010-12-18 04:22:25
【问题描述】:

在 Visual Studio 中使用 Microsoft MSVC 编译器开发通用 C++ 库多年后,我们现在将其移植到 Linux/Mac OS X(为我们祈祷)。我已经习惯并且非常喜欢 MSVC 中简单的内存泄漏检测机制:

#ifdef DEBUG
    #define _CRTDBG_MAP_ALLOC
    #define NEW   new( _NORMAL_BLOCK, __FILE__, __LINE__)
    #include <stdlib.h>
    #include <crtdbg.h>
#else
    #define NEW   new
#endif

每个内存分配都是使用这个 NEW 宏完成的。每当使用我们库的进程终止时,控制台上都会报告任何内存泄漏(尚未释放的块)以及最初分配内存的文件和行#。

我喜欢的部分是我不必主动“使用性能工具运行”或以其他方式表明我正在寻找泄漏。在常规开发过程中,每次进程终止时都会向我报告泄漏。

现在我们正在转向 GCC 世界,我发现内存泄漏检测工具(其中许多非常复杂)要求我明确指出我处于泄漏搜寻模式。我的 IDE 是 Xcode,我研究了一些分配/泄漏检测工具(如 Instruments 和 MallocDebug),但我承认我还没有花时间完全了解它们。我一直因为我必须提前指定我正在寻找泄漏而不是自动收到警报这一事实而感到厌烦。

我正在使用 Xcode 3.2,并且听说现在与静态分析工具进行了很好的集成,但我再次没有对此进行研究。我正在寻找一些关于我的选择的想法。 GCC 和/或 Xcode 中是否有类似的机制?是否有一个简单的第三方库或工具可以执行我所知道和喜爱的非常基本的功能?还是我应该接受它并学习新的做事方式?

【问题讨论】:

    标签: c++ c xcode gcc memory-leaks


    【解决方案1】:

    也许您可以使用Boehm garbage collector 作为泄漏检测工具:

    http://www.hpl.hp.com/personal/Hans_Boehm/gc/leak.html

    来自网站:

    #include "leak_detector.h"
    
    main() {
        int *p[10];
        int i;
        /* GC_find_leak = 1; for new collector versions not     */
        /* compiled with -DFIND_LEAK.               */
        for (i = 0; i < 10; ++i) {
        p[i] = malloc(sizeof(int)+i);
        }
        for (i = 1; i < 10; ++i) {
        free(p[i]);
        }
        for (i = 0; i < 9; ++i) {
        p[i] = malloc(sizeof(int)+i);
        }
        CHECK_LEAKS();
    }   
    

    (您会通过 stderr 收到通知)

    【讨论】:

    • 感谢您的建议。我无法在 Mac OS X 下成功构建 Boehm gc(6.8 版),阅读文档后发现一些可怕的陷阱(可疑的多线程支持、可疑的 C++ 支持)让我远离这个。跨度>
    【解决方案2】:

    我不知道有什么“内置”功能可以满足您的描述,但“推出您自己的”版本似乎并不难。您只希望您的调试 new 将指针、文件和行记录在 map&lt;void*, AllocationInfo&gt; 中,其中键是分配的指针,值 (AllocationInfo) 将是一些包含文件名、行号等的结构。您还需要定义一个自定义删除运算符来检查地图是否有被删除的指针。如果找到,则从地图中删除该条目。然后在进程关闭时发出地图的内容。

    我找到了a page where someone describes their own home-grown system that works like this

    【讨论】:

      【解决方案3】:

      您有多种选择。

      首先,也是最流行的,您可以在Valgrind 等工具下运行您的应用程序。这应该指出一些内存滥用,例如 NULL 指针读取和写入以及内存泄漏。 Valgrind 套件中有许多可用的工具,因此请务必查看它们。

      其次,您始终可以使用使用 LD_PRELOAD 技巧的库。基本上,LD_PRELOAD 技巧允许 DLL 注入,这意味着可以创建工具来帮助跟踪应用程序中的内存使用情况,而无需更改任何内容。您会发现dmallocefence 等工具在它们提供的调试工具中非常广泛。

      最后,最近的 GCC 版本包括一个名为 Mudflap 的工具。这基本上使用函数检测来包装与 dmalloc、efence 和 Valgrind 相同的内存函数的调用。该程序会明显变慢,并且可以在运行时进行调整,尽管它看起来仍然很有潜力。

      我已经使用了所有这三个,发现 Valgrind 非常有用。我也一直对使用 Mudflap 非常感兴趣,虽然我还不能。

      【讨论】:

      • 为 Valgrind +1。一开始的学习曲线有点陡峭,但不必重新编译真是太棒了。
      • 现在看起来 Mudflap 是 C 和“非常简单的 C++”,我很确定这会排除我们的 C++ 库。 Valgrind 看起来更有希望,但是你会一直在 Valgrind 下运行你的 DEBUG 配置,还是在寻找泄漏和其他内存错误时“偶尔”在 Valgrind 下运行它?我知道你可以做任何一个,但你的方法是什么?
      • 我通常在里程碑之前运行 Valgrind,例如演示或开发检查点。我这样做是因为自上一个里程碑以来出现的任何内存问题仍然存在,并且在进入每个里程碑时保持干净是件好事。一直运行它取决于您在开发过程中的重点(性能与深奥的泄漏)。培养对工具的认识非常重要;有些事情你必须压制,有些事情必须立即解决。
      【解决方案4】:

      您可能还会发现 MALLOC_CHECK_ 环境变量很有用。

      来自 malloc(3) 手册页:

      Linux libc(5.4.23 之后)和 glibc (2.x) 的最新版本包括一个 malloc() 实现,该实现可通过环境变量进行调整。当设置 MALLOC_CHECK_ 时,使用一种特殊的(效率较低的)实现,该实现旨在容忍简单的错误,例如使用相同参数的 free() 的两次调用,或单个字节的溢出(off-by-one 错误)。然而,并非所有此类错误都可以得到保护,并且可能导致内存泄漏。如果 MALLOC_CHECK_ 设置为 0,任何检测到的堆损坏都会被静默忽略;如果设置为 1,则在 stderr 上打印诊断消息;如果设置为 2,则立即调用 abort(3);如果设置为 3,则在 stderr 上打印诊断消息并中止程序。使用非零 MALLOC_CHECK_ 值可能很有用,否则崩溃可能会在很久以后发生,并且很难追查问题的真正原因。

      【讨论】:

        【解决方案5】:

        当我们开始移植到 Mac 时,我遇到了同样的问题。 “使用性能工具运行 -> 泄漏”是我发现的唯一一个,我对此并不感到兴奋……至少与 CRTDEBUG 相比。我知道有一些选择(正如其他人在这里所描述的那样),但最终由于我们是多平台的,我们使用 Windows 来查找漏洞。

        既然你提到了静态分析器。我们花了一些时间试图找出 hot 让它运行,直到我们发现它只支持 C 而不是 C++

        【讨论】:

        • 这正是我目前的经验。
        【解决方案6】:

        你应该看看“Cross-Platform Memory Leak Detector”,看起来很像 crtdbg.h 技术。

        【讨论】:

        • 很好的发现...+1 的问题和答案。
        【解决方案7】:

        一段时间以来,clang 和 gcc 都支持一些“清理程序”,包括泄漏清理程序。在编译期间启用时,编译器会检测代码以在运行时执行相应的检查。在 gcc 上,使用“-fsanitize=leak”启用泄漏清理器。见https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-04-16
          • 2012-07-16
          • 1970-01-01
          • 1970-01-01
          • 2012-01-22
          • 2015-02-28
          相关资源
          最近更新 更多