Debugging a memory leak using windbg without tracing a user stack

I have a full memory dump, but in this case I do not have a user stack trace database, I have modern characters and source binaries that come with a dump, as a rule I could use !heap -p -a address for viewing the call stack at the time of allocation, but this will not work without the user stack trace database.

My question is whether there is another way (albeit less direct) to get to the source of this memory leak.

  LFH Key : 0x0000005c2dc22701 Termination on corruption : ENABLED Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast (k) (k) (k) (k) length blocks cont. heap ------------------------------------------------------------------------------------- 00000000002e0000 00000002 3125248 3122792 3125248 282 378 197 0 7 LFH 0000000000010000 00008000 64 4 64 1 1 1 0 0 0000000000530000 00001002 1088 416 1088 51 10 2 0 0 LFH 0000000000490000 00001002 512 284 512 5 5 1 0 0 LFH 0000000000af0000 00001002 1088 248 1088 2 2 2 0 0 LFH 0000000000c00000 00001002 64 8 64 3 1 1 0 0 0000000000de0000 00001002 512 8 512 3 1 1 0 0 0000000000ac0000 00001002 31616 30356 31616 1810 42 6 0 0 LFH 00000000012c0000 00001002 512 8 512 2 1 1 0 0 0000000002140000 00001003 512 88 512 49 7 1 0 N/A 0000000001ab0000 00001003 512 8 512 5 1 1 0 N/A 00000000022f0000 00001003 512 8 512 5 1 1 0 N/A 0000000002490000 00001003 512 8 512 5 1 1 0 N/A 0000000000d40000 00001003 512 8 512 5 1 1 0 N/A 0000000002690000 00001003 512 8 512 5 1 1 0 N/A 0000000002860000 00001003 512 8 512 5 1 1 0 N/A 0000000002e90000 00001002 512 8 512 2 2 1 0 0 0000000002e10000 00001002 1536 556 1536 40 6 2 0 0 LFH 0000000001b90000 00011002 512 8 512 3 2 1 0 0 00000000033e0000 00001002 512 8 512 3 2 1 0 0 ------------------------------------------------------------------------------------- 

As you can see from this heap summary ( !heap -s Heap !heap -s ), the 00000000002e0000 heap has become quite large; upon closer inspection, you can see that 70% of the data is allocated in blocks of sizes 0x4058, 0x23d1 and 0x10d1 (this is definitely some kind of sample), therefore I'm sure I want to continue the study.

 heap @ 00000000002e0000 group-by: TOTSIZE max-display: 20 size #blocks total ( %) (percent of total busy bytes) 4058 1ea - 7b2870 (39.56) 23d1 1dc - 42989c (21.39) 10d1 1ed - 20627d (10.40) c51 1f4 - 180e34 (7.73) 307 25b - 7217d (2.29) 378 1f9 - 6d7b8 (2.20) 188 40e - 63570 (1.99) c0 59f - 43740 (1.35) 30 12c7 - 38550 (1.13) 28 147e - 333b0 (1.03) 140 22a - 2b480 (0.87) 138 231 - 2abb8 (0.86) 2340 11 - 25740 (0.75) 100 244 - 24400 (0.73) 120 1ea - 22740 (0.69) 78 456 - 20850 (0.65) 1010 12 - 12120 (0.36) 10188 1 - 10188 (0.32) 10008 1 - 10008 (0.32) 4000 4 - 10000 (0.32) 

My problem is that I do not know where to go from here, I previously followed the instructions found here with great success, but this time I do not have a user stack trace database, and I can not easily reproduce this template, but I know That memory dump contains a lot of useful information. I'm just not sure how to get to something meaningful from here, Windbg Experts? Memory dump analysts? Please advice.

Some blocks, the first couple of bytes

 0:000> dc 0000000005254b80 00000000`05254b80 52474d45 00000000 050f1c40 00000000 EMGR....@....... 00000000`05254b90 00000000 00000000 00000001 00000001 ................ 00000000`05254ba0 00000400 000003ff 0001d4c0 00000001 ................ 00000000`05254bb0 524d4954 00000000 051fcd10 00000000 TIMR............ 00000000`05254bc0 f7b315d0 000007fe 05254b80 00000000 .........K%..... 00000000`05254bd0 00000000 00000000 05254bd8 00000000 .........K%..... 00000000`05254be0 05254bd8 00000000 05254be8 00000000 .K%......K%..... 00000000`05254bf0 05254be8 00000000 05254bf8 00000000 .K%......K%..... 0:000> dc 00000000051ce640 00000000`051ce640 52474d45 00000000 04f1ab00 00000000 EMGR............ 00000000`051ce650 00000000 00000000 00000001 00000001 ................ 00000000`051ce660 00000400 000003ff 0001d4c0 00000001 ................ 00000000`051ce670 524d4954 00000000 05037070 00000000 TIMR....pp...... 00000000`051ce680 f7b315d0 000007fe 051ce640 00000000 ........@....... 00000000`051ce690 00000000 00000000 051ce698 00000000 ................ 00000000`051ce6a0 051ce698 00000000 051ce6a8 00000000 ................ 00000000`051ce6b0 051ce6a8 00000000 051ce6b8 00000000 ................ 0:000> dc 0000000004fdb1f0 00000000`04fdb1f0 52474d45 00000000 04f1b570 00000000 EMGR....p....... 00000000`04fdb200 00000000 00000000 00000001 00000001 ................ 00000000`04fdb210 00000400 000003ff 0001d4c0 00000001 ................ 00000000`04fdb220 524d4954 00000000 04ed6ba0 00000000 TIMR.....k...... 00000000`04fdb230 f7b315d0 000007fe 04fdb1f0 00000000 ................ 00000000`04fdb240 00000000 00000000 04fdb248 00000000 ........H....... 00000000`04fdb250 04fdb248 00000000 04fdb258 00000000 H.......X....... 00000000`04fdb260 04fdb258 00000000 04fdb268 00000000 X.......h....... 0:000> dc 0000000001e649b0 00000000`01e649b0 52474d45 00000000 00351270 00000000 EMGR....p.5..... 00000000`01e649c0 00000000 00000000 00000001 00000001 ................ 00000000`01e649d0 00000400 000003ff 0001d4c0 00000001 ................ 00000000`01e649e0 524d4954 00000000 01e64130 00000000 TIMR....0A...... 00000000`01e649f0 f7b315d0 000007fe 01e649b0 00000000 .........I...... 00000000`01e64a00 00000000 00000000 01e64a08 00000000 .........J...... 00000000`01e64a10 01e64a08 00000000 01e64a18 00000000 .J.......J...... 00000000`01e64a20 01e64a18 00000000 01e64a28 00000000 .J......(J...... 
+6
source share
1 answer

Use! heap -flt s on size (s) of violation (with logging to file)

Then manually unload the contents of some of them and try to guess what data they contain. If you're lucky, its C ++ objects with the vtable address in the first DWORD, which make them "easy" to recognize. If not, use the dc, dds commands and try to figure out what the content is.

Another approach is to search for types that are of the appropriate size for those you suspect of a leak.

 ============================Find symbols of spesific size=================================== 0:011> dt -v -s a4 <MyDll>!* Enumerating symbols matching <MyDll>!*, Size = 0xa4 Address Size Symbol 0a4 <MyDll>!NMDATETIMEFORMATW 0a4 <MyDll>!CWinApp 0a4 <MyDll>!CWinApp ==> Check all modules !for_each_module ".echo @#ModuleName;dt -v -s a4 ${@#ModuleName}!*" 

You can also try to find heap blocks that have a pointer to a suspected leak.

 0:008> !heap -srch 09C07058 _HEAP @ 02C90000 in HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state 0B7DA920: 002c : 002c [01] - 0B7DA928 (00000158) - (busy) diasymreader!Mod1::`vftable' 
+7
source

Source: https://habr.com/ru/post/953609/


All Articles