首页 文章

GCC内存泄漏检测相当于Microsoft crtdbg.h?

提问于
浏览
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中是否有类似的机制?是否有一个简单的第三方库或工具可以执行我所熟悉和喜爱的基本功能?或者我应该吮吸它并学习新的做事方式?

6 回答

  • 15

    你应该看看“Cross-Platform Memory Leak Detector”,看起来非常类似于crtdbg.h技术 .

  • 19

    您有多种选择 .

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

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

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

    我已经使用了所有三个并且发现Valgrind非常有用 . 我一直对使用Mudflap很感兴趣,尽管我还没有 .

  • 9

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

    来自malloc(3)手册页:

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

  • 3

    也许你可以使用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获得通知)

  • 4

    我似乎很难"roll your own"这个版本 . 你只需要你的调试new来记录指针,文件和行在 map<void*, AllocationInfo> 中,其中键是分配的指针,值( AllocationInfo )将是一些结构保存文件名,行号等 . 您还需要定义一个自定义删除操作符,用于检查映射是否删除指针 . 如果找到,则该条目将从 Map 中删除 . 然后在进程关闭时,您将发出映射的内容 .

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

  • 3

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

    既然你提到了静态分析仪 . 我们花了一些时间试图弄清楚它是否运行直到我们发现它只有C而不是C

相关问题