windbg调试代码中内存泄漏的方法,记录如下:
第一种方法:
1. 运行:gflags -i testDlg.exe +ust (gflags -i testDlg.exe -ust)
2. 设置windbg 的调试符号。
3. 在windbg打开应用程序testDlg.exe
4. 运行一段时间,关闭应用程序。
5. 显示:
testDlgDlg.cpp(241) : {455} normal block at 0x000000000498A9B0, 100 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
testDlgDlg.cpp(240) : {454} normal block at 0x0000000004991A00, 1234 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
testDlgDlg.cpp(241) : {453} normal block at 0x0000000004989B70, 100 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
testDlgDlg.cpp(240) : {452} normal block at 0x00000000049914D0, 1234 bytes long.
6. 0:000> !heap -x 0x000000000498A9B0
Entry User Heap Segment Size PrevSize Unused Flags
-------------------------------------------------------------------------------------------------------------
000000000498a950 000000000498a980 0000000002cd0000 0000000002cd78c0 c0 - 28 LFH;busy
7. 0:000> !heap -p -a 000000000498a950
address 000000000498a950 found in
_HEAP @ 2cd0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
000000000498a950 000c 0000 [00] 000000000498a980 00098 - (busy)
7ffae83efe73 ntdll!RtlpCallInterceptRoutine+0x000000000000003f
7ffae83b440f ntdll!RtlpAllocateHeapInternal+0x0000000000078b8f
69e8f70d MSVCR100D!_heap_alloc_base+0x000000000000005d
69ea210d MSVCR100D!_heap_alloc_dbg_impl+0x000000000000028d
69ea1e19 MSVCR100D!_nh_malloc_dbg_impl+0x0000000000000039
69ea1d99 MSVCR100D!_nh_malloc_dbg+0x0000000000000049
69ea1d39 MSVCR100D!_malloc_dbg+0x0000000000000039
695e8fac mfc100ud!operator new+0x000000000000003c
695e907f mfc100ud!operator new[]+0x000000000000002f
695e879c mfc100ud!operator new[]+0x000000000000002c
*** WARNING: Unable to verify checksum for testDlg.exe
7ff66088281b testDlg!CtestDlgDlg::OnBnClickedButton1+0x000000000000005b
6983ea4b mfc100ud!_AfxDispatchCmdMsg+0x000000000000013b
6983f619 mfc100ud!CCmdTarget::OnCmdMsg+0x00000000000004e9
6989421b mfc100ud!CDialog::OnCmdMsg+0x000000000000004b
699a7a0f mfc100ud!CWnd::OnCommand+0x000000000000022f
8. 7ff66088281b 为汇编的对应的程序的地址。
看看是代码中的什么位置:
0:000> lsa 7ff66088281b
237:
238: void CtestDlgDlg::OnBnClickedButton1()
239: {
240: char *p = new char[1234];
> 241: char*p2 = new char[100];
242:
243: }
244:
245: UINT ThreadUploadFtp(void * pv)
246: {
看到了吧,用这个方法很好用。
第二种方法:
1. 打开gflag.exe 在windbg 运行testDlg.exe
2. !heap -s
************************************************************************************************************************
NT HEAP STATS BELOW
************************************************************************************************************************
NtGlobalFlag enables following debugging aids for new heaps:
stack back traces
LFH Key : 0xe3de123a684a4855
Termination on corruption : ENABLED
Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast
(k) (k) (k) (k) length blocks cont. heap
-------------------------------------------------------------------------------------
00000000022f0000 08000002 1220 544 1020 123 17 1 0 0 LFH
0000000000590000 08008000 64 4 64 2 1 1 0 0
00000000025d0000 08001002 260 36 60 1 1 1 0 0 LFH
0000000002990000 08001002 1280 140 1080 2 9 2 0 0 LFH
0000000004630000 08001002 260 48 60 2 4 1 0 0 LFH
-------------------------------------------------------------------------------------
3. 运行一会
4.再运行 !heap -s
************************************************************************************************************************
NT HEAP STATS BELOW
************************************************************************************************************************
NtGlobalFlag enables following debugging aids for new heaps:
stack back traces
LFH Key : 0xe3de123a684a4855
Termination on corruption : ENABLED
Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast
(k) (k) (k) (k) length blocks cont. heap
-------------------------------------------------------------------------------------
00000000022f0000 08000002 1220 544 1020 123 17 1 0 0 LFH
0000000000590000 08008000 64 4 64 2 1 1 0 0
00000000025d0000 08001002 260 36 60 1 1 1 0 0 LFH
0000000002990000 08001002 1280 144 1080 3 9 2 0 0 LFH
0000000004630000 08001002 260 48 60 2 4 1 0 0 LFH
-------------------------------------------------------------------------------------
5. !heap -stat -h 0000000002990000
heap @ 0000000002990000
group-by: TOTSIZE max-display: 20
size #blocks total ( %) (percent of total busy bytes)
204e 2 - 409c (19.00)
363c 1 - 363c (15.95)
506 4 - 1418 (5.91)
1034 1 - 1034 (4.77)
43c 3 - cb4 (3.74)
b34 1 - b34 (3.29)
52 1e - 99c (2.83)
234 4 - 8d0 (2.59)
83c 1 - 83c (2.42)
834 1 - 834 (2.41)
9c c - 750 (2.15)
704 1 - 704 (2.06)
5c 13 - 6d4 (2.01)
3c 18 - 5a0 (1.65)
e4 6 - 558 (1.57)
12c 4 - 4b0 (1.38)
6c 9 - 3cc (1.12)
58 b - 3c8 (1.11)
39c 1 - 39c (1.06)
98 6 - 390 (1.05)
这里有如果是小内存,可能排在后边,如果泄漏很多,一定在最上边的。
我程序里边在第三人维系位置。
6. !heap -flt s 506
_HEAP @ 22f0000
_HEAP @ 590000
_HEAP @ 25d0000
_HEAP @ 2990000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
00000000044c0f40 0053 0000 [00] 00000000044c0f70 00506 - (busy)
00000000044c1470 0053 0053 [00] 00000000044c14a0 00506 - (busy)
00000000044c19a0 0053 0053 [00] 00000000044c19d0 00506 - (busy)
unknown!noop
00000000044c1fa0 0053 0053 [00] 00000000044c1fd0 00506 - (busy)
_HEAP @ 4630000
7. 0:004> !heap -p -a 00000000044c0f70
address 00000000044c0f70 found in
_HEAP @ 2990000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
00000000044c0f40 0053 0000 [00] 00000000044c0f70 00506 - (busy)
7ffae83efe73 ntdll!RtlpCallInterceptRoutine+0x000000000000003f
7ffae83b440f ntdll!RtlpAllocateHeapInternal+0x0000000000078b8f
695df70d MSVCR100D!_heap_alloc_base+0x000000000000005d
695f210d MSVCR100D!_heap_alloc_dbg_impl+0x000000000000028d
695f1e19 MSVCR100D!_nh_malloc_dbg_impl+0x0000000000000039
695f1d99 MSVCR100D!_nh_malloc_dbg+0x0000000000000049
695f1d39 MSVCR100D!_malloc_dbg+0x0000000000000039
697b8fac mfc100ud!operator new+0x000000000000003c
697b907f mfc100ud!operator new[]+0x000000000000002f
697b879c mfc100ud!operator new[]+0x000000000000002c
*** WARNING: Unable to verify checksum for testDlg.exe
7ff6608827f5 testDlg!CtestDlgDlg::OnBnClickedButton1+0x0000000000000035
69a0ea4b mfc100ud!_AfxDispatchCmdMsg+0x000000000000013b
69a0f619 mfc100ud!CCmdTarget::OnCmdMsg+0x00000000000004e9
69a6421b mfc100ud!CDialog::OnCmdMsg+0x000000000000004b
69b77a0f mfc100ud!CWnd::OnCommand+0x000000000000022f
697168bf mfc100ud!CDialogEx::OnCommand+0x000000000000004f
69b75e9e mfc100ud!CWnd::OnWndMsg+0x000000000000007e
69b75ddb mfc100ud!CWnd::WindowProc+0x000000000000004b
69b71281 mfc100ud!AfxCallWndProc+0x00000000000001b1
69b718f0 mfc100ud!AfxWndProc+0x00000000000000e0
698e2367 mfc100ud!AfxWndProcBase+0x0000000000000057
7ffae7215c1d USER32!UserCallWinProcCheckWow+0x00000000000002bd
7ffae721522c USER32!SendMessageWorker+0x000000000000022c
7ffae7214f98 USER32!SendMessageW+0x00000000000000f8
7fface176459 COMCTL32!Button_ReleaseCapture+0x00000000000000a9
7fface1adf0c COMCTL32!Button_WndProc+0x00000000000004dc
7ffae7215c1d USER32!UserCallWinProcCheckWow+0x00000000000002bd
7ffae7215612 USER32!DispatchMessageWorker+0x00000000000001e2
7ffae7216db0 USER32!IsDialogMessageW+0x0000000000000280
69bbc340 mfc100ud!CWnd::IsDialogMessageW+0x0000000000000090
69b7e9e4 mfc100ud!CWnd::PreTranslateInput+0x0000000000000084
69a641b9 mfc100ud!CDialog::PreTranslateMessage+0x0000000000000139
看到了吧,实际上两种方法都是可以的。