在windbg程序目录下有个gflags.exe,运行后设置:
运行CMD.EXE,输入 "D:\Debugging Tools for Windows (x86)\gflags.exe" /i test.exe +ust ,如果设置成功则显示:
如果设置失败,说明注册表被禁用了,可以尝试解除所有对注册表的禁用。这个注册表位置为:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options,命令“gflags.exe /i mydoneProject.exe +ust”实际上就是在该路径下创建一个子键“mydoneProject.exe ”并创建一个名为GlobalFlag内容为0x00001000的REG_DWORD值。
第二步:使用WinDbg调试程序:
void Crash()
{
++i;
p = new char[10240];
std::cout << "New Alloc Memory + 10240 * " << i << std::endl;
Sleep(2000);
}
int _tmain(int argc, _TCHAR* argv[])
{
while (1)
{
Crash();
}
return 0;
}
要先设置pdb路径:WinDbg -> file-> symbol file path
1.先查看初始的堆状态:
0:001> !heap -s
NtGlobalFlag enables following debugging aids for new heaps:
stack back traces
LFH Key : 0x55f96c69
Termination on corruption : DISABLED
Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast
(k) (k) (k) (k) length blocks cont. heap
-----------------------------------------------------------------------------
00220000 08000002 1024 164 1024 8 2 1 0 0 LFH
00010000 08008000 64 4 64 2 1 1 0 0
00020000 08008000 64 64 64 62 1 1 0 0
004d0000 08001002 1088 308 1088 20 8 2 0 0 LFH
-----------------------------------------------------------------------------
2. 让程序继续跑一段时间:
0:001> g
eax=00000001 ebx=c000013a ecx=bf5756bf edx=000001ff esi=776f7380 edi=776f7340
eip=776670f4 esp=006ffd6c ebp=006ffd88 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!KiFastSystemCallRet:
776670f4 c3 ret
3. 查看第二次堆状态:
0:001> !heap -s
NtGlobalFlag enables following debugging aids for new heaps:
stack back traces
LFH Key : 0x55f96c69
Termination on corruption : DISABLED
Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast
(k) (k) (k) (k) length blocks cont. heap
-----------------------------------------------------------------------------
00220000 08000002 1024 164 1024 8 4 1 0 0 LFH
00010000 08008000 64 4 64 2 1 1 0 0
00020000 08008000 64 64 64 62 1 1 0 0
004d0000 08001002 1088 616 1088 29 10 2 0 0 LFH
-----------------------------------------------------------------------------
两次分析,发现:004d0000地址上有异常:
0:001> !heap -stat -h 004d0000
heap @ 004d0000
group-by: TOTSIZE max-display: 20
size #blocks total ( %) (percent of total busy bytes)
2824 19 - 3eb84 (94.91)
824 1 - 824 (0.77)
630 1 - 630 (0.59)
32a 1 - 32a (0.30)
244 1 - 244 (0.21)
238 1 - 238 (0.21)
c4 2 - 188 (0.14)
ac 2 - 158 (0.13)
144 1 - 144 (0.12)
134 1 - 134 (0.11)
60 3 - 120 (0.11)
48 4 - 120 (0.11)
88 2 - 110 (0.10)
5a 3 - 10e (0.10)
42 4 - 108 (0.10)
fc 1 - fc (0.09)
52 3 - f6 (0.09)
6a 2 - d4 (0.08)
62 2 - c4 (0.07)
3f 3 - bd (0.07)
2824 19 - 3eb84 (94.91) 占了 94.91%, 看一下都是哪些堆申请
0:001> !heap -flt s 2824
_HEAP @ 220000
_HEAP @ 10000
_HEAP @ 20000
_HEAP @ 4d0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
004dbc00 0508 0000 [00] 004dbc18 02824 - (busy)
003aefc0 0508 0508 [00] 003aefd8 02824 - (busy)
003b1800 0508 0508 [00] 003b1818 02824 - (busy)
003b4040 0508 0508 [00] 003b4058 02824 - (busy)
003b6880 0508 0508 [00] 003b6898 02824 - (busy)
003b90c0 0508 0508 [00] 003b90d8 02824 - (busy)
003bb900 0508 0508 [00] 003bb918 02824 - (busy)
003be140 0508 0508 [00] 003be158 02824 - (busy)
003c0980 0508 0508 [00] 003c0998 02824 - (busy)
003c31c0 0508 0508 [00] 003c31d8 02824 - (busy)
003c5a00 0508 0508 [00] 003c5a18 02824 - (busy)
003c8240 0508 0508 [00] 003c8258 02824 - (busy)
003caa80 0508 0508 [00] 003caa98 02824 - (busy)
003cd2c0 0508 0508 [00] 003cd2d8 02824 - (busy)
003cfb00 0508 0508 [00] 003cfb18 02824 - (busy)
003d2340 0508 0508 [00] 003d2358 02824 - (busy)
003d4b80 0508 0508 [00] 003d4b98 02824 - (busy)
003d73e8 0541 0508 [00] 003d7400 02824 - (busy)
003d9df0 0541 0541 [00] 003d9e08 02824 - (busy)
003dc7f8 0541 0541 [00] 003dc810 02824 - (busy)
003df200 0541 0541 [00] 003df218 02824 - (busy)
003e1c08 0541 0541 [00] 003e1c20 02824 - (busy)
003e4610 0541 0541 [00] 003e4628 02824 - (busy)
003e7018 0541 0541 [00] 003e7030 02824 - (busy)
003e9a20 0541 0541 [00] 003e9a38 02824 - (busy)
随便挑几个地址看一下调用栈
0:001> !heap -p -a 003cfb00
address 003cfb00 found in
_HEAP @ 4d0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
003cfb00 0508 0000 [00] 003cfb18 02824 - (busy)
Trace: 77b9c
7769ddac ntdll!RtlAllocateHeap+0x00000274
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\windows\WinSxS\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\MSVCR90D.dll -
5d9d151e MSVCR90D!malloc_base+0x000000ee
5d9e0206 MSVCR90D!malloc_dbg+0x00000306
5d9dffbf MSVCR90D!malloc_dbg+0x000000bf
5d9dff6c MSVCR90D!malloc_dbg+0x0000006c
5d9eb5eb MSVCR90D!malloc+0x0000001b
5d9cdb81 MSVCR90D!operator new+0x00000011
*** WARNING: Unable to verify checksum for G:\test\mydoneProject\Debug\mydoneProject.exe
11c1fae mydoneProject!operator new[]+0x0000000e
11c1ab5 mydoneProject!Crash+0x00000035
11c152c mydoneProject!wmain+0x0000002c
11c25b8 mydoneProject!__tmainCRTStartup+0x000001a8
11c23ff mydoneProject!wmainCRTStartup+0x0000000f
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\windows\system32\kernel32.dll -
7609ed5c kernel32!BaseThreadInitThunk+0x00000012
776837eb ntdll!__RtlUserThreadStart+0x00000070
776837be ntdll!_RtlUserThreadStart+0x0000001b
///根据提供的符号得出,发现内存分配都是在这个堆栈里面分配出来的。
11c1fae mydoneProject!operator new[]+0x0000000e
11c1ab5 mydoneProject!Crash+0x00000035
11c152c mydoneProject!wmain+0x0000002c