windbg诊断64位转储中的泄漏-!heap未显示内存增长

时间:2018-11-05 15:51:29

标签: windbg

我正在尝试调试64位C ++本机应用程序中的内存泄漏。该应用每秒通过7-10次泄漏1300个字节-通过普通的malloc()。

如果我使用WinDBG附加该进程并每60秒中断一次,则!heap不会显示分配的内存的任何增加。

我确实在该过程中启用了用户模式堆栈跟踪数据库:

gflags /i <process>.exe +ust

在WinDBG(已成功加载所有符号)中,我正在使用:

!heap -stat -h

但是即使我看到任务管理器和PerfMon跟踪中的“私人字节数”增加,当中断时,命令的输出也不会改变。

我知道,当分配较小时,它们转到HeapAlloc(),当分配较大时,它们转到VirtualAlloc。 !heap对HeapAlloc不起作用吗?

这个post似乎暗示也许使用DebugDiag可以工作,但是仍然归结为使用WinDBG命令来处理转储。尝试无济于事。

post还表示,对于64位应用程序,!heap命令已损坏。可能是这样吗?

是否存在用于诊断64位应用程序中泄漏的备用过程?

1 个答案:

答案 0 :(得分:0)

  

!!堆没有显示已分配的内存的任何增加。

这可能取决于您要查看的列以及堆管理器之前分配的内存量。

例如您的应用程序可能有100 MB的堆,其中只有64kB的某些块正在从“保留”列移至“已提交”列。如果内存是从一开始就提交的,那么使用普通的!heap命令根本看不到任何内容。

  

我确实在进程中启用了用户模式堆栈跟踪数据库

这将帮助您获取分配堆栈跟踪,但通常不会影响泄漏。

  

我知道,当分配较小时,它们转到HeapAlloc(),当分配较大时,它们转到VirtualAlloc。

是的,for allocations > 512k

  

!heap对HeapAlloc无效吗?

应该。而且由于C ++ malloc()new都使用Windows Heap管理器,所以它们迟早会导致HeapAlloc()

以下代码

#include <iostream>
#include <chrono>
#include <thread>

int main()
{
    // https://stackoverflow.com/questions/53157722/windbg-diagnosing-leaks-in-64-bit-dumps-heap-not-showing-memory-growth
    //
    // I am trying to debug a memory leak in a 64-bit C++ native application.
    // The app leaks 1300 bytes 7-10 times a second - via plain malloc().

    for(int seconds=0; seconds < 60; seconds++)
    {
        for (int leakspersecond=0; leakspersecond<8;leakspersecond++)
        {
            if (malloc(1300)==nullptr)
            {
                std::cout << "Out of memory. That was unexpected in this simple demo." << std::endl;
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(125));
        }
    }
}

编译为64位版本,并在WinDbg 10.0.15063.400 x64显示中运行

0:001> !heap -stat -h

Allocations statistics for
 heap @ 00000000000d0000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    514 1a - 8408  (32.24)
    521 c - 3d8c  (15.03)
[...]

及以后

0:001> !heap -stat -h

Allocations statistics for
 heap @ 00000000000d0000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    514 30 - f3c0  (41.83)
    521 18 - 7b18  (21.12)

即使未设置+ust

  

这是450万行代码。

那么您如何知道它通过普通的malloc()泄漏了1300个字节?