【发布时间】:2010-09-23 20:18:57
【问题描述】:
有没有办法在程序终止时检测文件句柄泄漏?
特别是我想确保我创建的所有句柄都在代码中被释放。
例如,我可能在某处有一个 CreateFile(),并且在程序终止时我想检测并确保它们都已关闭。
【问题讨论】:
标签: c++ winapi visual-c++
有没有办法在程序终止时检测文件句柄泄漏?
特别是我想确保我创建的所有句柄都在代码中被释放。
例如,我可能在某处有一个 CreateFile(),并且在程序终止时我想检测并确保它们都已关闭。
【问题讨论】:
标签: c++ winapi visual-c++
我用过windbg的!htrace命令。
!htrace -enable
!htrace -snapshot
!htrace -diff
让您比较两个执行点的句柄情况,帮助您定位泄漏句柄的分配点。
对我来说效果很好。
【讨论】:
windbg 或 ntsd 有一个 !handle 扩展名,可以告诉您应用程序打开了哪些句柄。我想您可以在程序的末尾放置一个断点并将句柄转储到那里。
您还可以在 powerdbg (http://www.codeplex.com/powerdbg) 中执行某些操作来自动执行此过程。
当然,这假设您的时间比购买解决方案便宜:)
【讨论】:
我推荐这个工具Memory Validator
非常好。
【讨论】:
正如 MadKeithV 所说,您可以使用 RAII 来发挥出色的效果。
还有一种简单的方法(免费)是使用Visual Leak Detector。这并不完美,但可以确保您有 free'd/delete[]d/close'd 等。
【讨论】:
如果您买不起 BoundsChecker 或类似工具...
我使用的一个技巧是用我自己的包装器替换CreateFile 等。除了返回句柄值之外,它们还会记录 __FILE__ 和 __LINE__ 以与每个句柄一起使用。您还需要包装 CloseHandle,以确保正确关闭的句柄不会引发误报。
很简单:
// StdAfx.h
#include <windows.h>
#undef CreateFile
#if defined(UNICODE)
#define CreateFile DbgCreateFileW
#else
#define CreateFile DbgCreateFileA
#endif
// etc.
然后在代码中的某处定义DbgCreateFileW 和DbgCreateFileA。
这假设您已经控制了相关的代码片段。如果没有,您可以使用(例如)Microsoft Detours 来做类似的事情(您需要许可证才能将其包含在已发布的产品中,但我相信它可以免费用于调试/测试/等)
但是,从长远来看,您应该考虑将代码转换为使用“智能”句柄类型,当它超出范围时会自动调用 CloseHandle。
【讨论】:
另一个提示是 SysInternals FileMon (Link)。
它向您显示文件系统活动,因此它应该支持您查找打开的句柄。
【讨论】:
如果可以(即如果它不是一个庞大的遗留代码库,则您正在修复错误)您应该考虑使用 RAII 成语来环绕您的文件句柄。 通过在构造函数中“获取”文件句柄并在析构函数中释放它,您可以确保当您的 RAII 超出范围时,您的文件句柄也被很好地清理了。
它与智能指针的原理相同,它是一个非常有用的概念,可以在您的工具箱中使用,以避免在 C++ 中出现此类问题。
【讨论】:
对文件句柄和类似资源使用智能指针。
【讨论】:
您也可以使用MS的Application Verifier。
【讨论】:
BoundsChecker 或其他类似程序会执行此操作。我还以为在VC6及以上的调试器下运行会报告泄漏列表。也许这是因为我总是有插件工具来做这种事情。
【讨论】: