【问题标题】:Memory leak detection while running unit tests运行单元测试时的内存泄漏检测
【发布时间】:2010-09-15 04:56:44
【问题描述】:

我有一个带有一套单元测试的 Win32 C++ 应用程序。单元测试完成运行后,我希望自动生成关于任何未释放内存的可读报告。理想情况下,报告将有一个堆栈,其中包含每个未释放分配的文件和行号信息。最好让它们以一致的顺序生成,以便轻松区分它从一次运行到下一次运行。 (基本上,我想要 valgrind --leak-check=full 的结果,但在 Windows 上)。

我已经成功使用 UMDH 从正在运行的进程中获取此类信息,但该工具似乎只有在附加到现有进程时才有效。我希望每次运行单元测试时自动发生这种情况。

有没有工具可以做到这一点?如果是这样,我该如何使用它?

谢谢!

【问题讨论】:

    标签: c++ winapi memory-leaks


    【解决方案1】:

    为了获取此类信息,我们重写了 new/delete 和 malloc/free,提供了我们自己的堆实现,用于存储分配时的堆栈跟踪,并在堆被销毁时生成报告(以及添加哨兵以检测缓冲区溢出) .

    这是你第一次做的时候相当多的工作。 This guy 编写了一个免费软件工具来处理所有困难的部分 - 我自己还没有尝试过,但他对他如何编写它的解释在你自己动手时很有用。

    【讨论】:

      【解决方案2】:

      如果您使用的是 MSVC,可以使用 Microsoft 的 Debug heap 函数来生成您想要的报告,但它可能不像您希望的那样自动(您可能需要编写一些自定义代码):

      _CrtSetReportMode
      _CrtSetReportFile
      _CrtMemState    
      _CrtMemCheckpoint
      _CrtMemDumpStatistics
      _CrtSetReportFile
      _CrtSetDbgFlag
      

      【讨论】:

      • 你在一个更大的项目中打开了太多这些,事情就会慢下来
      【解决方案3】:

      您可以定义 DEBUG_NEW 并打开一些泄漏检测,您需要在包含任何系统包含文件之前定义它。它只使用 new 运算符检查泄漏,当然你必须重新编译你的代码,这样你就不能像 valgrind 那样附加它。

      在此处查看更多信息:

      http://msdn.microsoft.com/en-us/library/tz7sxz99(VS.80).aspx

      【讨论】:

        【解决方案4】:

        我尝试了 Mike B 指出的 CRT 调试堆函数,但最终我并不满足于仅仅获得泄漏内存的地址。获取 UMDH 提供的堆栈可以使调试速度更快。所以,现在在我的 main() 函数中 在我运行测试以获取堆快照之前和之后使用 CreateProcess 启动 UMDH。我还编写了一个简单的批处理文件来运行我的测试工具,然后对堆快照进行比较。因此,我启动批处理文件并一次性获取我的测试结果和一个包含所有未释放分配的完整堆栈的文本文件。

        UMDH 发现了很多误报,所以也许一些 CrtDebug 东西的混合体和我现在正在做的事情会是一个更好的解决方案。但就目前而言,我对我所拥有的感到满意。

        现在,如果我有办法检测我是否没有关闭任何句柄...

        【讨论】:

          【解决方案5】:

          我这样做过一次,但不是那么自动。我现在无法访问该代码,但这是我的想法:

          我使用了 Mike B 提到的debug functions(顺便说一句,它们只在调试中工作)。

          测试运行器将所有测试运行了两次,因为在第一次运行期间,内存被分配给全局变量。第二次,在每次测试之前和之后检查分配块的总数(我认为您可以在 setUp() 和 tearDown() 中进行)。如果数字不同,则意味着内存泄漏,并且测试失败并显示适当的消息。当然,如果测试本身失败,你应该保留它的错误信息。现在要找到泄漏点,我必须使用 pBlockHeader 读取上次分配的块分配编号,然后使用 _CrtSetBreakAlloc 在其上设置断点并再次运行。

          在此处了解更多信息:http://levsblog.wordpress.com/2008/10/31/unit-testing-memory-leaks/

          【讨论】:

            猜你喜欢
            • 2011-09-28
            • 1970-01-01
            • 2016-01-05
            • 1970-01-01
            • 1970-01-01
            • 2018-02-23
            • 2012-07-16
            • 1970-01-01
            • 2020-04-11
            相关资源
            最近更新 更多