代码之家  ›  专栏  ›  技术社区  ›  Gene Goykhman

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

  •  25
  • Gene Goykhman  · 技术社区  · 16 年前

    在Visual Studio中使用微软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
    

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

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

    现在,我们正转向GCC领域,我发现内存泄漏检测工具(其中许多非常复杂)需要我明确指出我处于泄漏搜索模式。我的IDE是Xcode,我已经研究了一些分配/泄漏检测工具(如Instruments和MallocDebug),但我承认我还没有花时间完全了解它们。我一直被这样一个事实所困扰,即我实际上必须提前指定我正在查找泄漏,而不是自动得到警报。

    我使用的是Xcode 3.2,我听说现在有了与静态分析工具的漂亮集成,但我还没有研究过这个问题。我想知道我的选择是什么。GCC和/或Xcode中是否内置了类似的机制?是否有一个简单的第三方库或工具可以执行我所知道和喜爱的非常基本的功能?还是我应该接受它,学习新的做事方式?

    6 回复  |  直到 16 年前
        1
  •  20
  •   s1n    16 年前

    Valgrind . 这应该会指出一些内存滥用,例如空指针读写和内存泄漏。Valgrind套件中有许多可用的工具,所以一定要查看它们。

    其次,您可以始终使用使用 LD_PRELOAD dmalloc efence

    最后,最近的GCC版本包括一个名为 Mudflap

    我使用了这三种方法,发现Valgrind非常有用。我对使用Mudflap也很感兴趣,尽管我还没能做到。

        2
  •  18
  •   Cristian Adam    16 年前

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

        3
  •  10
  •   grigy    16 年前

    您还可能发现MALLOC\u CHECK\u环境变量很有用。

    从malloc(3)手册页:

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

        4
  •  4
  •   akosch    16 年前

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

        5
  •  3
  •   Laurence Gonsalves    16 年前

    我不知道有什么“内置”的东西能做到你所描述的,但看起来“推出你自己的”版本并不难。您只需要将新调试记录在 map<void*, AllocationInfo> 其中,键是分配的指针和值( AllocationInfo )将是一些保存文件名、行号等的结构。您还需要定义一个自定义删除运算符,用于检查映射以查找要删除的指针。如果找到,该条目将从映射中删除。然后在进程关闭时发出映射的内容。

    我发现 a page where someone describes their own home-grown system that works like this

        6
  •  3
  •   Nicholaz    16 年前

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

    因为你提到了静态分析器。我们花了一些时间试图找出热,直到它发现它运行C,但不是C++。

        7
  •  0
  •   Dirk Herrmann    6 年前

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