Windows调试——使用windbg查找内存泄露

内存泄露查找方法

C++程序员经常不注意内存使用的关闭,虽然此类问题不会导致程序逻辑问题,但随着时间的推移,内存占用量越来越多,最终导致程序崩掉。对服务端的程序,内存泄漏经常是致命的。
对于已经存在内存泄露的程序,可能Windbg查找内存泄露的代码。下面介绍如果通过Windbg查找内存泄露。

  1. Windbg 加载程序依赖库所用pdb文件。
  2. 挂载进程或者加载已生成的pdb文件
  3. 输入命令查看内存。

3.1 !heap –s 查看程序内存状况
0:000> !heap -s
NtGlobalFlag enables following debugging aids for new heaps:
stack back traces
LFH Key : 0x73ccd2bf
Termination on corruption : DISABLED
Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast

(k) (k) (k) (k) length blocks cont. heap

004e0000 08000002 4096 3968 4096 45 86 3 0 0 LFH
006f0000 08001002 1088 804 1088 40 3 2 0 0 LFH
002d0000 08001002 1280 292 1280 9 16 2 0 0 LFH
Virtual block: 05f10000 - 05f10000 (size 00000000)
Virtual block: 45fd0000 - 45fd0000 (size 00000000)
Virtual block: 466d0000 - 466d0000 (size 00000000)
Virtual block: 47310000 - 47310000 (size 00000000)
00b70000 08001002 250748 250044 250748 3122 925 58 4 9 LFH
00480000 08001002 256 148 256 6 1 1 0 0 LFH
04f80000 08001002 256 4 256 2 1 1 0 0
00bb0000 08011002 256 80 256 74 3 1 0 0
04ed0000 08001002 64 16 64 13 1 1 0 0
059e0000 08001002 64 4 64 2 1 1 0 0
05bd0000 08001002 64 4 64 2 1 1 0 0
05dc0000 08001002 256 4 256 1 2 1 0 0
04e40000 08001002 1280 300 1280 49 12 2 0 0 LFH
Virtual block: 6b310000 - 6b310000 (size 00000000)
Virtual block: 6b520000 - 6b520000 (size 00000000)
180f0000 08001002 1088 676 1088 267 5 2 2 23
18740000 08001002 7232 6236 7232 3956 49 13 0 26 LFH
External fragmentation 63 % (49 free blocks)
18b60000 08001002 1088 220 1088 24 8 2 0 0 LFH
04e30000 08001002 1088 148 1088 2 4 2 0 0 LFH

过一段时间再次通过!heap –s 查看程序内存状况。找出增长较快的内存块,如00b70000。

3.2 !heap -stat –h 查看00b70000内存详细情况
0:000> !heap -stat -h 00b70000
heap @ 00b70000
group-by: TOTSIZE max-display: 20
size #blocks total ( %) (percent of total busy bytes)
ea60 f88 - e382300 (57.83)
9c61334 1 - 9c61334 (39.75)
1b7730 1 - 1b7730 (0.44)
147254 1 - 147254 (0.32)
124f74 1 - 124f74 (0.29)
c de5e - a6c68 (0.17)
2000 41 - 82000 (0.13)
214 3d1 - 7ee54 (0.13)
28 2a67 - 6a018 (0.11)
42b0 14 - 535c0 (0.08)
1c 2914 - 47e30 (0.07)
2b70 14 - 364c0 (0.05)
14 29b4 - 34210 (0.05)
32000 1 - 32000 (0.05)
18 1ac1 - 28218 (0.04)
4 7df4 - 1f7d0 (0.03)
1d4c4 1 - 1d4c4 (0.03)
1740 14 - 1d100 (0.03)
2408 c - 1b060 (0.03)
208 cc - 19e60 (0.03)

3.3 !heap -flt s 查进程中size=ea60的所有内存
0:000> !heap -flt s ea60
_HEAP @ 4e0000
_HEAP @ 6f0000
_HEAP @ 2d0000
_HEAP @ b70000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
5272cc18 1d4f 0000 [00] 5272cc30 0ea60 - (busy)
537bc578 1d4f 1d4f [00] 537bc590 0ea60 - (busy)
537cbf98 1d4f 1d4f [00] 537cbfb0 0ea60 - (busy)
53862f20 1d4f 1d4f [00] 53862f38 0ea60 - (busy)
53871998 1d4f 1d4f [00] 538719b0 0ea60 - (busy)
53890608 1d4f 1d4f [00] 53890620 0ea60 - (busy)
538ace68 1d4f 1d4f [00] 538ace80 0ea60 - (busy)
538bb8e0 1d4f 1d4f [00] 538bb8f8 0ea60 - (busy)
538dcec8 1d4f 1d4f [00] 538dcee0 0ea60 - (busy)
53901af8 1d4f 1d4f [00] 53901b10 0ea60 - (busy)
53910570 1d4f 1d4f [00] 53910588 0ea60 - (busy)
5391efe8 1d4f 1d4f [00] 5391f000 0ea60 - (busy)
539b71a0 1d4f 1d4f [00] 539b71b8 0ea60 - (busy)
539c5c18 1d4f 1d4f [00] 539c5c30 0ea60 - (busy)
539d4690 1d4f 1d4f [00] 539d46a8 0ea60 - (busy)
539e3108 1d4f 1d4f [00] 539e3120 0ea60 - (busy)
539f1b80 1d4f 1d4f [00] 539f1b98 0ea60 - (busy)
53a005f8 1d4f 1d4f [00] 53a00610 0ea60 - (busy)
53a0f070 1d4f 1d4f [00] 53a0f088 0ea60 - (busy)
53a20f98 1d4f 1d4f [00] 53a20fb0 0ea60 - (busy)
53a2fa10 1d4f 1d4f [00] 53a2fa28 0ea60 - (busy)
53a4e6b8 1d4f 1d4f [00] 53a4e6d0 0ea60 - (busy)
53a66fa0 1d4f 1d4f [00] 53a66fb8 0ea60 - (busy)
53a75a18 1d4f 1d4f [00] 53a75a30 0ea60 - (busy)
71614e20 1d4f 1d4f [00] 71614e38 0ea60 - (busy)
71623898 1d4f 1d4f [00] 716238b0 0ea60 - (busy)
71632310 1d4f 1d4f [00] 71632328 0ea60 - (busy)
……………………………..
3.4 !heap -p –a 查看内存堆栈,定位泄露根源。
0:000> !heap -p -a 71614e38
address 71614e38 found in
_HEAP @ b70000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
71614e20 1d4f 0000 [00] 71614e38 0ea60 - (busy)
Trace: 5be4158
76f5dfa2 ntdll!RtlAllocateHeap+0x00000274
72873db8 MSVCR90!malloc+0x00000079
70e7b9dd BInterface!osip_malloc+0x0000000d
70e83f93 BInterface!sdp_message_to_str+0x00000073
70e3751f BInterface!CSdpParse::sdp_to_str+0x0000001f
70e14b06 BInterface!CUserAgent::DoStartStream+0x00000316
70e26e3b BInterface!BI_StartRealStream+0x000000fb

0:000> !heap -p -a 721acf68
address 721acf68 found in
_HEAP @ b70000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
721acf50 1d4f 0000 [00] 721acf68 0ea60 - (busy)
Trace: 5be4158
76f5dfa2 ntdll!RtlAllocateHeap+0x00000274
72873db8 MSVCR90!malloc+0x00000079
70e7b9dd BInterface!osip_malloc+0x0000000d
70e83f93 BInterface!sdp_message_to_str+0x00000073
70e3751f BInterface!CSdpParse::sdp_to_str+0x0000001f
70e14b06 BInterface!CUserAgent::DoStartStream+0x00000316
70e26e3b BInterface!BI_StartRealStream+0x000000fb

  1. 通过以上分析可以定位到BInterface相关接口导致内存泄露。

你可能感兴趣的