Windows 使用windbg进行无用户堆栈跟踪的内存泄漏调试
我有一个完整的内存转储,但是在这个例子中,我没有一个用户堆栈跟踪数据库,我有最新的符号和原始的二进制文件,通常情况下,我能够使用Windows 使用windbg进行无用户堆栈跟踪的内存泄漏调试,windows,memory-leaks,windbg,memory-dump,Windows,Memory Leaks,Windbg,Memory Dump,我有一个完整的内存转储,但是在这个例子中,我没有一个用户堆栈跟踪数据库,我有最新的符号和原始的二进制文件,通常情况下,我能够使用!heap-p-a address在分配时查看调用堆栈,但如果没有用户堆栈跟踪数据库,这将无法工作 我的问题是,是否有另一种方法(尽管不是直接的方法)可以找到内存泄漏的根源 LFH Key : 0x0000005c2dc22701 Termination on corruption : ENABLED
!heap-p-a address
在分配时查看调用堆栈,但如果没有用户堆栈跟踪数据库,这将无法工作
我的问题是,是否有另一种方法(尽管不是直接的方法)可以找到内存泄漏的根源
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
-------------------------------------------------------------------------------------
正如您可以从这个堆摘要(!heap-s
)中看到的,heap0000000000 2e0000
已经变得相当大,仔细检查可以看到70%的数据分配在大小为0x4058、0x23d1和0x10d1的块中(这肯定是某种模式),因此我非常确定我想进一步研究这个问题
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)
我的问题是我不知道该怎么办,之前,我已经很成功地遵循了找到的说明,但这次我没有用户堆栈跟踪数据库,我无法轻松复制这种模式,但我知道内存转储包含很多有用的信息,我只是不知道如何从这里获得有意义的信息。Windbg专家?内存转储分析师?请给我一些建议
一些块,前几个字节
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......
用这个!heap-错误大小上的flt(记录到文件) 然后手动将内容转储到其中一些文件上,并尝试猜测它们包含什么类型的数据。 如果你幸运的话,它是C++对象,在第一个DWORD中有一个VTABLE地址,这使得它们很容易识别。 如果没有,请使用dc、dds命令并尝试找出内容 另一种方法是查找与您怀疑泄漏的类型具有相应大小的类型
============================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}!*"
Debug Diag memory leak rule在这种情况下是一种合适的方法,等待这么长时间进行小型转储只会确保您完全沉浸在数据中。@HansPassant不确定这是针对Lex还是我的,但转储周围的环境并不是我可以随意处理的,我只是想确定这个问题有多严重,如果真的严重的话。据我所知,这可能是一个孤立的事件。我尝试转储一些较大的块,发现一些模式,不知道数据,你能识别其中任何一个吗?尝试:ln 00000000`52474D45因为你的块以相同的64位指针开始,请检查此项。ln命令将列出最近的符号。try:ln 00000000`05254b80什么也没有发生:(我已经三次检查了符号是否成功加载。关于:!address 00000000`05254b80它将显示它是否是指向另一个堆块的指针。但是,我认为您在这里遇到了一个难题!
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'