【问题标题】:Detect file handle leaks with Win32 C++使用 Win32 C++ 检测文件句柄泄漏
【发布时间】:2010-09-23 20:18:57
【问题描述】:

有没有办法在程序终止时检测文件句柄泄漏?

特别是我想确保我创建的所有句柄都在代码中被释放。

例如,我可能在某处有一个 CreateFile(),并且在程序终止时我想检测并确保它们都已关闭。

【问题讨论】:

    标签: c++ winapi visual-c++


    【解决方案1】:

    我用过windbg的!htrace命令。

    !htrace -enable
    !htrace -snapshot
    !htrace -diff
    

    让您比较两个执行点的句柄情况,帮助您定位泄漏句柄的分配点。

    对我来说效果很好。

    【讨论】:

    • 这会在快照之间提供已分配句柄的调用堆栈吗?
    【解决方案2】:

    windbg 或 ntsd 有一个 !handle 扩展名,可以告诉您应用程序打开了哪些句柄。我想您可以在程序的末尾放置一个断点并将句柄转储到那里。

    您还可以在 powerdbg (http://www.codeplex.com/powerdbg) 中执行某些操作来自动执行此过程。

    当然,这假设您的时间比购买解决方案便宜:)

    【讨论】:

      【解决方案3】:

      我推荐这个工具Memory Validator

      非常好。

      【讨论】:

        【解决方案4】:

        正如 MadKeithV 所说,您可以使用 RAII 来发挥出色的效果。

        还有一种简单的方法(免费)是使用Visual Leak Detector。这并不完美,但可以确保您有 free'd/delete[]d/close'd 等。

        【讨论】:

          【解决方案5】:

          如果您买不起 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。

          【讨论】:

            【解决方案6】:

            另一个提示是 SysInternals FileMon (Link)。

            它向您显示文件系统活动,因此它应该支持您查找打开的句柄。

            【讨论】:

              【解决方案7】:

              如果可以(即如果它不是一个庞大的遗留代码库,则您正在修复错误)您应该考虑使用 RAII 成语来环绕您的文件句柄。 通过在构造函数中“获取”文件句柄并在析构函数中释放它,您可以确保当您的 RAII 超出范围时,您的文件句柄也被很好地清理了。

              它与智能指针的原理相同,它是一个非常有用的概念,可以在您的工具箱中使用,以避免在 C++ 中出现此类问题。

              【讨论】:

                【解决方案8】:

                对文件句柄和类似资源使用智能指针。

                【讨论】:

                  【解决方案9】:

                  您也可以使用MS的Application Verifier。

                  【讨论】:

                  • 对文档的简要阅读并没有揭示任何有关句柄泄漏检测的信息。我错过了什么?
                  • 诀窍是代码必须在 dll 中,当它卸载时泄漏检测将拾取泄漏的句柄和泄漏的堆分配
                  【解决方案10】:

                  BoundsChecker 或其他类似程序会执行此操作。我还以为在VC6及以上的调试器下运行会报告泄漏列表。也许这是因为我总是有插件工具来做这种事情。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-06-10
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多