如何找内存泄露
先寫一段這樣的程序:
#include "stdafx.h"
#include <windows.h>
void AllocateMemory()?
{?
???? int* a = new int[2000];?
?? ? for(int i=0;i<2000;i++)
? {
??*a=0;
??a++;
? }
???? Sleep(1);?
}
int _tmain(int argc, _TCHAR* argv[])
{?? while(1)?
???? {?
??????? AllocateMemory();?
???? }?
???? return 0;?
}
然后打開windbg,attach上這個程序(非侵入),在DbgBreakPoint停止
輸入命令:!heap -s
? Heap???? Flags?? Reserv? Commit? Virt?? Free? List?? UCR? Virt? Lock? Fast?
??????????????????? (k)???? (k)??? (k)???? (k) length????? blocks cont. heap?
-----------------------------------------------------------------------------
00150000 00000002??? 1024???? 16???? 16????? 2???? 1???? 1??? 0????? 0?? L??
00250000 00001002????? 64???? 24???? 24???? 15???? 1???? 1??? 0????? 0?? L??
00260000 00008000????? 64???? 12???? 12???? 10???? 1???? 1??? 0????? 0??????
00380000 00001002????? 64???? 16???? 16????? 1???? 1???? 1??? 0????? 0?? L??
003a0000 00001002? 130112? 73260? 73260???? 33???? 7???? 1??? 0????? 0?? L??
-----------------------------------------------------------------------------
然后讓它繼續(xù)運(yùn)行,輸入g
過一會再將它break.
0:001> !heap -s
? Heap???? Flags?? Reserv? Commit? Virt?? Free? List?? UCR? Virt? Lock? Fast?
??????????????????? (k)???? (k)??? (k)???? (k) length????? blocks cont. heap?
-----------------------------------------------------------------------------
00150000 00000002??? 1024???? 16???? 16????? 2???? 1???? 1??? 0????? 0?? L??
00250000 00001002????? 64???? 24???? 24???? 15???? 1???? 1??? 0????? 0?? L??
00260000 00008000????? 64???? 12???? 12???? 10???? 1???? 1??? 0????? 0??????
00380000 00001002????? 64???? 16???? 16????? 1???? 1???? 1??? 0????? 0?? L??
003a0000 00001002? 130112? 97020? 97020???? 35???? 7???? 1??? 0????? 0?? L??
-----------------------------------------------------------------------------
然后再g,過一會再break.
0:001> !heap -s
? Heap???? Flags?? Reserv? Commit? Virt?? Free? List?? UCR? Virt? Lock? Fast?
??????????????????? (k)???? (k)??? (k)???? (k) length????? blocks cont. heap?
-----------------------------------------------------------------------------
00150000 00000002??? 1024???? 16???? 16????? 2???? 1???? 1??? 0????? 0?? L??
00250000 00001002????? 64???? 24???? 24???? 15???? 1???? 1??? 0????? 0?? L??
00260000 00008000????? 64???? 12???? 12???? 10???? 1???? 1??? 0????? 0??????
00380000 00001002????? 64???? 16???? 16????? 1???? 1???? 1??? 0????? 0?? L??
003a0000 00001002? 261184 179204 179204???? 35???? 8???? 1??? 0????? 0?? L??
-----------------------------------------------------------------------------
注意看003a0000地址,它申請的內(nèi)存和使用的內(nèi)存都一直再長。 說明這個堆地址有泄漏。
對這個堆做個統(tǒng)計:
!heap -stat -h 003a0000?
?heap @ 003a0000
group-by: TOTSIZE max-display: 20
??? size???? #blocks???? total???? ( %) (percent of total busy bytes)
??? 1f40 597c - aec6300? (99.99)
??? 800 2 - 1000? (0.00)
??? 48a 1 - 48a? (0.00)
??? 214 2 - 428? (0.00)
??? 245 1 - 245? (0.00)
??? 220 1 - 220? (0.00)
??? 94 2 - 128? (0.00)
??? 72 2 - e4? (0.00)
??? c8 1 - c8? (0.00)
??? 54 2 - a8? (0.00)
??? 90 1 - 90? (0.00)
??? 48 2 - 90? (0.00)
??? 8e 1 - 8e? (0.00)
??? 88 1 - 88? (0.00)
??? 44 2 - 88? (0.00)
??? 80 1 - 80? (0.00)
??? 2a 3 - 7e? (0.00)
??? 76 1 - 76? (0.00)
??? 39 2 - 72? (0.00)
??? 26 3 - 72? (0.00)
發(fā)現(xiàn)這個堆中,大小為1f40的內(nèi)存塊最多。
根據(jù)大小過濾下這個
!heap -flt s 1f40
??? _HEAP @ 150000
??? _HEAP @ 250000
??? _HEAP @ 260000
??? _HEAP @ 380000
??? _HEAP @ 3a0000
????? HEAP_ENTRY Size Prev Flags??? UserPtr UserSize - state
??????? 003a5c70 03e9 0000? [01]?? 003a5c78??? 01f40 - (busy)
??????? 003a7bb8 03e9 03e9? [01]?? 003a7bc0??? 01f40 - (busy)
??????? 003a9b00 03e9 03e9? [01]?? 003a9b08??? 01f40 - (busy)
??????? 003aba48 03e9 03e9? [01]?? 003aba50??? 01f40 - (busy)
??????? 003ad990 03e9 03e9? [01]?? 003ad998??? 01f40 - (busy)
??????? 00410040 03e9 03e9? [01]?? 00410048??? 01f40 - (busy)
??????? 00411f88 03e9 03e9? [01]?? 00411f90??? 01f40 - (busy)
??????? 00413ed0 03e9 03e9? [01]?? 00413ed8??? 01f40 - (busy)
??????? 00415e18 03e9 03e9? [01]?? 00415e20??? 01f40 - (busy)
??????? 00417d60 03e9 03e9? [01]?? 00417d68??? 01f40 - (busy)
??????? 00419ca8 03e9 03e9? [01]?? 00419cb0??? 01f40 - (busy)
??????? 0041bbf0 03e9 03e9? [01]?? 0041bbf8??? 01f40 - (busy)
??????? 0041db38 03e9 03e9? [01]?? 0041db40??? 01f40 - (busy)
??????? 0041fa80 03e9 03e9? [01]?? 0041fa88??? 01f40 - (busy)
??????? 004219c8 03e9 03e9? [01]?? 004219d0??? 01f40 - (busy)
??????? 00423910 03e9 03e9? [01]?? 00423918??? 01f40 - (busy)
??????? 00425858 03e9 03e9? [01]?? 00425860??? 01f40 - (busy)
??????? 004277a0 03e9 03e9? [01]?? 004277a8??? 01f40 - (busy)
??????? 004296e8 03e9 03e9? [01]?? 004296f0??? 01f40 - (busy)
??????? 0042b630 03e9 03e9? [01]?? 0042b638??? 01f40 - (busy)
??????? ... ...
明顯可以看到3a0000中有不少這種內(nèi)存塊。取一個UserPtr,調(diào)用!heap -p -a UsrPtr
這樣可以顯示出這個塊的調(diào)用棧。
0:001> !heap -p -a 0b2fe198
??? address 0b2fe198 found in
??? _HEAP @ 3a0000
????? HEAP_ENTRY Size Prev Flags??? UserPtr UserSize - state
??????? 0b2fe190 03e9 0000? [01]?? 0b2fe198??? 01f40 - (busy)
這里什么都沒有,當(dāng)然你需要配置操作系統(tǒng)標(biāo)志來啟動跟蹤內(nèi)存泄露進(jìn)程的user stack。
啟動方法就是運(yùn)行下面指令gflags.exe /i Testleak.exe +ust。
這樣運(yùn)行上面命令就有
!heap -p -a 0143d8c8?
??? address 0143d8c8 found in
??? _HEAP @ 330000
????? HEAP_ENTRY Size Prev Flags??? UserPtr UserSize - state
??????? 0143d8c0 03f0 0000? [07]?? 0143d8c8??? 01f64 - (busy)
??????? Trace: 0025
??????? 7c96d6dc ntdll!RtlDebugAllocateHeap+0x000000e1
??????? 7c949d18 ntdll!RtlAllocateHeapSlowly+0x00000044
??????? 7c91b298 ntdll!RtlAllocateHeap+0x00000e64
??????? 102c103e MSVCR90D!_heap_alloc_base+0x0000005e
??????? 102cfd76 MSVCR90D!_heap_alloc_dbg_impl+0x000001f6
??????? 102cfb2f MSVCR90D!_nh_malloc_dbg_impl+0x0000001f
??????? 102cfadc MSVCR90D!_nh_malloc_dbg+0x0000002c
??????? 102db25b MSVCR90D!malloc+0x0000001b
??????? 102bd691 MSVCR90D!operator new+0x00000011
??????? 102bd71f MSVCR90D!operator new[]+0x0000000f
??????? 4113d8 Test2!AllocateMemory+0x00000028
??????? 41145c Test2!wmain+0x0000002c
??????? 411a08 Test2!__tmainCRTStartup+0x000001a8
??????? 41184f Test2!wmainCRTStartup+0x0000000f
??????? 7c816fd7 kernel32!BaseProcessStart+0x00000023
這樣的效果?
??? 這樣泄露的位置就很清楚的找到了
轉(zhuǎn)載于:https://www.cnblogs.com/kissfu/p/3465787.html
總結(jié)
 
                            
                        - 上一篇: Samba nsswitch/pam_w
- 下一篇: 4入lut 6入
