4

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

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

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

谢谢!

4

5 回答 5

4

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

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

于 2008-10-03T22:19:49.870 回答
1

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

_CrtSetReportMode
_CrtSetReportFile
_CrtMemState    
_CrtMemCheckpoint
_CrtMemDumpStatistics
_CrtSetReportFile
_CrtSetDbgFlag
于 2008-10-03T22:12:03.427 回答
0

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

在此处查看更多信息:

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

于 2008-10-03T22:45:05.967 回答
0

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

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

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

更多信息在这里: http: //levsblog.wordpress.com/2008/10/31/unit-testing-memory-leaks/

于 2008-10-04T19:25:36.120 回答
0

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

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

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

于 2008-10-04T22:45:32.797 回答