【问题标题】:Memory leak detection in C/C++ compilerC/C++ 编译器中的内存泄漏检测
【发布时间】:2016-07-05 16:40:26
【问题描述】:

可以在 C/C++ 编译器中构建堆内存泄漏检测吗?例如,在最简单的形式中,在语义分析期间,它会简单地计算分配的内存段(new/malloc 或其他)和每个内存段的delete/free 调用。然后给出一个关于它的编译时警告。

【问题讨论】:

  • IIRC 有一些库可以这样做,malloc()/free() 是大多数 ABI 库中的弱绑定函数,因此可以将它们替换为您自己的版本,或者来自另一个库的版本。
  • 您有一些静态分析工具,例如 splint 可以这样做...但有些情况下您只能(轻松)确定运行时的内存泄漏(在这种情况下,您可能想查valgrind)
  • C++ 中的完美垃圾回收(=泄漏检测)相当于“停机问题”,因此一般无法解决。也就是说,有一些规则需要遵守,有一些你应该检查的可检测热点。如果是新代码,请尝试仅使用托管 ptrs,并且永远不要有没有 weak_ptr 的循环。如果是旧代码,请配置文件。如果你对代码有写访问权,你可能会做一些有趣的事情,比如在构造函数中将实例注册到全局数组并在析构函数中删除。在许多情况下,一个额外的基类就足够了。
  • 根据标题,我预计您会说您运行 gcc 到 valgrind 并发现内存泄漏或其他问题

标签: c++ c compiler-construction


【解决方案1】:

请参阅 C++ 核心指南,这是一个分析代码以查找与 GSL 标准的偏差的工具。该标准具有可静态执行的编码规则,可排除内存泄漏的可能性。

https://isocpp.org/blog/2015/09/bjarne-stroustrup-announces-cpp-core-guidelines

【讨论】:

    【解决方案2】:

    好吧,也许你可以尝试一下,但你应该考虑以下几点:

    • 您应该在整个程序模式下构建您的应用程序(在其他情况下您只能捕获非常琐碎的东西)。
    • 您应该对指针进行非常复杂的数据流分析 - 想象一下,您为某个对象分配了内存,然后将该指针分配给另一个对象。而且您在程序的任何地方都只释放其中一个。或者您可以将此指针放入某个容器中。
    • 大型应用程序中可能有数十万个指针。所以分析需要大量的内存和时间。远远超出用户的意愿。
    • 如果您进行了相当便宜和快速的分析,则将是不准确的。因此,您将不得不打印很多误报警告或只打印准确的警告,但对于大多数简单的事情

    因此,作为一项学术研究,可能会非常有趣,但在现实生活中,我怀疑是否有可能做出令人满意的质量分析。

    【讨论】:

      【解决方案3】:

      嗯,有 clang (LLVM) sanitizers。它们不是编译时的,而是向发出的程序添加运行时检测。

      一般来说,对于行为取决于输入的代码,完全静态地完成工作是不可能的。独立的静态分析工具有一些启发式方法来跟踪各种代码路径,这已经有点像动态了。

      仅检测代码并运行它(或像 valgrind 一样进行模拟)在概念上更简单,尽管它当然会减慢执行速度。

      【讨论】:

        【解决方案4】:

        我们的CheckPointer 工具检测 MS 或 GCC C 程序以查找运行时发生的各种指针管理错误。

        它会检测悬空指针,即超出它们起源的语言定义的内存区域的指针,包括指向堆栈内部区域的指针(这些是 Valgrind 无法找到的问题,因为它认为整个堆栈是引用的指针)。它还处理线程本地存储。

        它会在可以报告此类错误的最早时间报告错误,这使得查找原因变得相当简单。

        在运行结束时,它会生成一个已分配但未释放的存储块列表,以帮助追踪内存泄漏。

        【讨论】:

          猜你喜欢
          • 2021-09-01
          • 2010-09-08
          • 2011-05-12
          • 2011-02-18
          • 2011-03-29
          • 1970-01-01
          • 2022-01-11
          • 1970-01-01
          相关资源
          最近更新 更多