To investigate a memory leak in a crash dump (since I prefer by far UMDH for live processes).
The strategy is that objects of the same type are all allocated with the same size.
- Feed the
!heap -h 0
command to WinDbg's command line version cdb.exe (for greater speed) to get all heap allocations:
"C:\Program Files\Debugging Tools for Windows\cdb.exe" -c "!heap -h 0;q" -z [DumpPath] > DumpHeapEntries.log
- Use Cygwin to grep the list of allocations, grouping them by size:
grep "busy ([[:alnum:]]\+)" DumpHeapEntries.log \
| gawk '{ str = $8; gsub(/\(|\)/, "", str); print "0x" str " 0x" $4 }' \
| sort \
| uniq -c \
| gawk '{ printf "%10.2f %10d %10d ( %s = %d )\n", $1*strtonum($3)/1024, $1, strtonum($3), $2, strtonum($2) }' \
| sort > DumpHeapEntriesStats.log
- You get a table that looks like this, for example, telling us that 25529270 allocations of 0x24 bytes take nearly 1.2 GB of memory.
8489.52 707 12296 ( 0x3000 = 12288 )
11894.28 5924 2056 ( 0x800 = 2048 )
13222.66 846250 16 ( 0x2 = 2 )
14120.41 602471 24 ( 0x2 = 2 )
31539.30 2018515 16 ( 0x1 = 1 )
38902.01 1659819 24 ( 0x1 = 1 )
40856.38 817 51208 ( 0xc800 = 51200 )
1196684.53 25529270 48 ( 0x24 = 36 )
- Then if your objects have vtables, just use the
dps
command to seek some of the 0x24 bytes heap allocations in DumpHeapEntries.log to know the type of the objects that are taking all the memory.
0:075> dps 3be7f7e8
3be7f7e8 00020006
3be7f7ec 090c01e7
3be7f7f0 0b40fe94 SomeDll!SomeType::`vftable'
3be7f7f4 00000000
3be7f7f8 00000000
It's cheesy but it works :)