WinDbg定位内存泄露


一般我用两种方法:

1. 用Debug Diagnostic Tool的Leak监测分析功能,注意配置好PDB文件。

   DebugDiag 会生成完整的Leak Report。看看帮助很方便。

2. 用WinDBG的!heap扩展命令。注意要为你的程序打开Normal PageHeap。

http://support.microsoft.com/kb/286470

   然后当内存出现明显泄漏时用 !heap -l 命令分析内存。-l 参数使用类似Java/C#的Garbage Collection算法,这样能找到大部分在程序中没有被引用的HeapBlock。

   这是一个示例输出:

0:011> !heap -l
Searching the memory for potential unreachable busy blocks.
......
Heap 017a0000
Scanning VM ...
Scanning references from 3586 busy blocks (0 MBytes) ...
Entry           User         Heap            Segment        Size  PrevSize  Unused    Flags
-----------------------------------------------------------------------------
00253198  002531a0  00250000  00250000        b8        78        14  busy extra
00253250  00253258  00250000  00250000        78        b8        13  busy extra
00286a38  00286a40  00250000  00250000       b8        b8        15  busy extra
00286af0  00286af8  00250000  00250000        b8        b8        15  busy extra
00286ba8  00286bb0  00250000  00250000        b8        b8        15  busy extra
00286c60  00286c68  00250000  00250000        b8        b8        15  busy extra
00286d18  00286d20  00250000  00250000        b8        b8        15  busy extra
00286dd0  00286dd8  00250000  00250000        b8        b8        15  busy extra

   找到最常出现的Size值(这里是b8),一般就是持续泄漏的内存块大小。随便选一行,记下Entry地址(比如00286a3)。

   dt _DPH_BLOCK_INFORMATION 00286a3 + 8   //8 是HeapEntry结构的大小,跟在其后的就是PageHeap meta data,结构名是_DPH_BLOCK_INFORMATION.

   0:011> dt _DPH_BLOCK_INFORMATION 00286a3+ 8
ntdll!_DPH_BLOCK_INFORMATION
   +0x000 StartStamp       : 0xabcdaaaa
   +0x004 Heap             : 0x80151000
   +0x008 RequestedSize    : 0x7b
   +0x00c ActualSize       : 0xa3
   +0x010 FreeQueue        : _LIST_ENTRY [ 0x2e - 0x0 ]
   +0x010 TraceIndex       : 0x2e
   +0x018 StackTrace       : 0x00357140
   +0x01c EndStamp         : 0xdcbaaaaa

   看到StackTrace那行,这是相应的user mode stack trace database的地址。

0:011> dds 0x00357140
00357140  abcdaaaa
......
00357160  7c949d18 ntdll!RtlAllocateHeapSlowly+0x44
00357164  7c91b298 ntdll!RtlAllocateHeap+0xe64
00357168  004017fe 06_DebugDiag_MemoryLeak!MyHeapAlloc+0x1e [g:\debugging101\projects\06_debugdiag_memoryleak\06_debugdiag_memoryleak\06_debugdiag_memoryleak.cpp @ 11]
0035716c  0040182b 06_DebugDiag_MemoryLeak!WorkerThread+0x1b [g:\debugging101\projects\06_debugdiag_memoryleak\06_debugdiag_memoryleak\06_debugdiag_memoryleak.cpp @ 27]
00357170  7c80b683 kernel32!BaseThreadStart+0x37

   这就是上次通过Heap Manager函数操作这个HeapBlock的StackTrace,一般也就是分配这个Block的地方。

   希望可以帮到你。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: