我参与了各种C ++项目(主要使用MSVC6到MSVC10),我们最近发现了一些句柄泄漏(CreateThread
函数给出的线程句柄)。我怀疑还有很多其他手柄也被泄露了,我想整合一个测试,证明我们的夜间测试结果没有泄漏手柄。
我的想法是开发一个DLL,用于检测相关的kernel32.dll函数(CreateThread,OpenProcess,CreateProcess和其他十几个函数)以及CloseHandle
函数。然后,对于每个获取的句柄,DLL将记忆回溯。在进程结束时,DLL将打印所有未关闭某种日志文件的句柄回溯,然后由测试框架解析。
这当然也会产生所有仍然可以访问的句柄的回溯(从技术上讲,它们没有泄漏 - 也许作者希望操作系统在进程终止时回收它们)但我猜是明确地关闭它们不会受伤 - 特别是因为我们已经为这些东西提供了一些不错的RAII包装器,我们就不会像我们应该那样使用它。
现在我想知道 - 这似乎是一种相当简单的方法;也许这里有人知道已经做过这个的图书馆?
答案 0 :(得分:3)
这绝对是可能的,但我认为还没有一个库可以做到这一点。
我认为,最简单的方法是使用Application Verifier。您可以从Microsoft的Debugging Tools for Windows获取它。将其配置为跟踪应用程序的句柄,在调试器中运行一些应用程序,然后在应用程序退出时转储句柄列表。
在没有Application Debugger的情况下,另一种方法是在应用程序退出之前设置断点或暂停。当应用程序暂停时,使用Process Explorer之类的东西获取所有打开句柄的列表。
出于您的目的,我认为后者将是更好的选择。我不确定任何使用调试输出的自动化工具。您可以使用WDK的某些功能来检索当前进程(或其他进程的)打开句柄的列表,但它有点复杂。
答案 1 :(得分:2)
Mark Russinovich在他的系列文章中解释了推动Windows的限制如何更好地处理handles以及如何跟踪句柄泄漏。
他提到了Windows调试器和应用程序验证程序,他正在解释如何使用它来跟踪句柄泄漏情况。
在同一页面中,他还提到了他着名的Process Explorer的一个简洁功能,它为创建/关闭句柄的进程闪烁绿色和红色。
答案 2 :(得分:1)
如果你已经阅读了推动Windows的极限文章,那么你会看到它提到了WinDbg!htrace扩展,我认为它满足了你对与句柄创建相关的相关kernel32.dll函数的第一个要求。
要自动调用!htrace,您可以将调试器引擎嵌入到测试工具中,或者可以使用类似PyDbgEng的内容来启动应用程序并调用!htrace扩展,然后在应用程序完成时收集堆栈。有一个使用PyDbgEng进行此类自动化的示例,但注册表函数位于http://pydbgeng.svn.sourceforge.net/viewvc/pydbgeng/trunk/PyDbgEng/Examples/RegMon.py?view=markup,但我认为您可以使用此示例来调用示例中的扩展名(dbg.idebug_control.CallExtension)。
答案 3 :(得分:1)
我们在目前的工作场所使用Memory Validator。它可以配置为跟踪每个内存分配,COM调用(和引用计数)和句柄。启动它,并让它启动验证所需的代码或附加到要验证的运行代码。从那时起,它正在跟踪您告诉它跟踪的任何资源。当代码退出时,它将报告其未跟踪的任何未解除分配的资源以及分配它们的位置。它是一种商业产品,但它有一个试用期,因此您可以测试它,看它是否满足您的需求。当我们在复杂情况下遇到麻烦的泄漏时,它对我和同事有所帮助,但它本身并不是一个神奇的解决方案。仍然需要遵循良好的泄漏狩猎技术,它只是为您提供有关哪些分配仍然存在以及它们来自何处的其他信息。
答案 4 :(得分:0)
我和Deleaker一起玩过,并且在记忆和处理泄漏方面取得了成功。它可以在Visual Studio中使用,也可以单独使用。来自Deleaker网站:
发生什么类型的泄漏并不重要,Deleaker会发现它们: 内存泄漏(由堆,虚拟内存或OLE分配器生成) 等),GDI泄漏,Windows USER对象泄漏和处理。“