【问题标题】:How to track memory leaks with umdh.exe in all heaps?如何使用 umdh.exe 在所有堆中跟踪内存泄漏?
【发布时间】:2010-10-17 07:29:40
【问题描述】:

我有一个 c++ windows 应用程序,每个事务都会泄漏内存。使用 perfmon,我可以看到每个事务的私有字节数都在增加,当应用程序空闲时,内存使用量是平稳的。

按照之前关于 stackoverflow 的答案,我使用了微软调试工具中的 umdh 来追踪一个内存泄漏。但是仍然存在更多泄漏,并且 umdh 的结果与我的 perfmon 结果不匹配。

第一个 umdh 仍然报告此泄漏,堆栈跟踪是:

+   36192 ( 2082056 - 2045864)    251 allocs    BackTraceCB
+       4 (    251 -    247)    BackTraceCB allocations

    ntdll!RtlAllocateHeapSlowly+00000041
    ntdll!RtlAllocateHeap+00000E9F
    MSVCR80!malloc+0000007A

这没有用,因为第一个调用是 malloc,它没有说明调用它的内容。我对这种泄漏表示怀疑,因为它在应用程序正在处理事务和空闲时都会报告。但是我可以清楚地看到空闲时没有内存泄漏。并且在处理事务时报告的内存泄漏与作为 perfmon 报告处理的事务不成比例。

umhd 没有显示任何其他泄漏,尽管我知道至少还有一个未显示。我刚刚从网上搜索得知一个 Windows 应用程序可以有多个堆。

  • 难道 umhd 只报告这些堆之一的内存使用情况?例如默认或crt 堆?
  • 如何跟踪其他堆中的内存使用情况?
  • 如何找出哪些 dll/模块正在使用其他堆?

由于我的选项不多了,我们将不胜感激地收到任何关于追踪此问题的指针。

【问题讨论】:

    标签: c++ memory-leaks


    【解决方案1】:

    对我来说,在 umdh 失败的情况下 - 另一个名为 LeakDiag 的免费 MS 工具成功了。它允许拦截比 umdh 更多的分配器类型,包括它所谓的“MPHeap 分配器”,I suspect 可能对您有用。如果你有空闲时间 - 我很好奇这是否真的有帮助..

    【讨论】:

      【解决方案2】:

      很抱歉回答我自己的问题,但我最终将问题归结为我是如何使用 Orbix 的。

      orbix 库似乎在 Windows 平台上使用自己的堆。这意味着大多数内存泄漏检测不适用于 orbix 中的泄漏,我尝试了 boundschecker 和 umhd.exe。

      为了隔离这个问题,我发现了一些代码可以转储应用程序中每个堆的内存:http://www.abstraction.net/content/articles/analyzing%20the%20heaps%20of%20a%20win32%20process.htm

      我用它来转储每个事务之前和之后的堆使用情况,然后在每 500 个事务之后,这表明每次都在增长同一个堆。然后我列出了这个堆中每个条目的地址。检查这些区域的内存,我发现它们包含 orbix 编组数据。有了这些信息,我终于找到了一些没有被清理的对象引用。

      【讨论】:

      • 问题中的堆栈跟踪原来是一个红鲱鱼。它被定期分配和释放,因此总是出现在报告的 delta umdh 中。泄漏原来是在不同的堆中。我找不到任何适用于特定于应用程序的受控堆的工具。我使用代码遍历所有堆并将其写入文件。一旦数据表明 orbix 是问题,我测试每个事务的每个 orbix 调用,直到发现内存泄漏。
      【解决方案3】:

      我过去常常进行代码审查以寻找内存泄漏。

      我一直在寻找的一些东西:

      1. 继承问题:基类不提供虚拟析构函数并且以多态方式使用。
      2. 在代码中搜索指针声明或指针分配(查找 * 声明、关键字 new 或 malloc 用法),并查看代码片段,以动态分配对象的生命周期为目标。

      当然,代码审查可能很耗时,具体取决于您必须审查的代码库。但是,如果您可以限制需要查找指针分配/使用的区域,它可能会有所回报。在我的大多数情况下都是如此。

      【讨论】:

        【解决方案4】:

        也许 umdh 无法为您的代码定位调试符号?这可以解释为什么堆栈跟踪不完整。确保您已使用符号构建它并且可以找到它们。

        【讨论】:

        • 谢谢。我相当确定我的应用程序的符号和 nt 符号已正确配置,因为当我修复第一次泄漏时,其他堆栈跟踪已正确显示。
        • 在这种情况下,我猜想分配来自外部库
        【解决方案5】:

        除非您的应用程序(或它使用的库)明确创建自己的堆,否则只需担心一个堆。大多数图书馆不这样做,所以我建议这不应该是你调查的主要途径。

        【讨论】:

        • 我们的应用程序同时使用了 orbix 和 oci (oracle),所以我想知道他们是否会做一些不寻常的事情。
        • 那些 Oracle 库已经存在并且每天被数百万人使用 - 我不认为在其中查找漏洞是一个好方法。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多