为什么 WinDbg 在测试内存泄漏程序时总是返回相同的"!heap -s"信息?

Why the WinDbg always return the same information of "!heap -s" when I test a memory leak program?

本文关键字:heap 信息 返回 测试 WinDbg 内存 泄漏 程序 为什么      更新时间:2023-10-16

我编写了一个程序来学习使用WinDbg进行内存泄漏检测。但是当我使用"!heap -s"命令时,在我长时间运行内存泄漏程序后,它总是返回相同的信息(见下文)。

Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
*** wait with pending attach
Symbol search path is: srv*c:symbols*http://msdl.microsoft.com/download/symbols;C:image
Executable search path is: srv*c:symbols*http://msdl.microsoft.com/download/symbols;C:image
ModLoad: 00000000`00400000 00000000`0041a000   C:imagememory.exe
ModLoad: 00000000`76d40000 00000000`76ee9000   C:WindowsSYSTEM32ntdll.dll
ModLoad: 00000000`76f20000 00000000`770a0000   ntdll.dll
ModLoad: 00000000`001c0000 00000000`0022e000   C:Windowssystem32verifier.dll
ModLoad: 00000000`731c0000 00000000`731ff000   C:WindowsSYSTEM32wow64.dll
ModLoad: 00000000`73160000 00000000`731bc000   C:WindowsSYSTEM32wow64win.dll
ModLoad: 00000000`74850000 00000000`74858000   C:WindowsSYSTEM32wow64cpu.dll
ModLoad: 00000000`6f7f0000 00000000`6f850000   VERIFIER.dll
ModLoad: 00000000`72a20000 00000000`72a49000   vrfcore.dll
ModLoad: 00000000`6f870000 00000000`6f8ac000   VFBASICS.dll
ModLoad: 00000000`76380000 00000000`76490000   KERNEL32.dll
ModLoad: 00000000`76490000 00000000`764d7000   KERNELBASE.dll
ModLoad: 00000000`10200000 00000000`10320000   MSVCR80D.dll
ModLoad: 00000000`74e20000 00000000`74ecc000   msvcrt.dll
(44e0.4748): Break instruction exception - code 80000003 (first chance)
ntdll!DbgBreakPoint:
00000000`76d90590 cc              int     3
0:001> !heap -s
LFH Key                   : 0x0000008a68294636
Termination on corruption : ENABLED
          Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                            (k)     (k)    (k)     (k) length      blocks cont. heap 
-------------------------------------------------------------------------------------
0000000000320000 00000002     512      8    512      3     1     1    0      0      
0000000003d80000 00001002     512      8    512      3     1     1    0      0      
0000000000310000 00008000      64      4     64      1     1     1    0      0      
00000000003a0000 00008000      64     64     64     61     1     1    0      0      
-------------------------------------------------------------------------------------
0:001> g
(44e0.1550): Break instruction exception - code 80000003 (first chance)
ntdll!DbgBreakPoint:
00000000`76d90590 cc              int     3
0:001> g
(44e0.3b04): Break instruction exception - code 80000003 (first chance)
ntdll!DbgBreakPoint:
00000000`76d90590 cc              int     3
0:001> !heap -s
LFH Key                   : 0x0000008a68294636
Termination on corruption : ENABLED
          Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                            (k)     (k)    (k)     (k) length      blocks cont. heap 
-------------------------------------------------------------------------------------
0000000000320000 00000002     512      8    512      3     1     1    0      0      
0000000003d80000 00001002     512      8    512      3     1     1    0      0      
0000000000310000 00008000      64      4     64      1     1     1    0      0      
00000000003a0000 00008000      64     64     64     61     1     1    0      0      
-------------------------------------------------------------------------------------

程序代码如下所示:

#include <windows.h>
void AllocateMemory() 
{ 
    int* a = new int[2000]; 
    ZeroMemory(a, 8000); 
    Sleep(1); 
}
int main(int argc, char* argv[])
{   
while(1) 
{ 
    AllocateMemory(); 
} 
return 0; 
} 

gflag 命令如下所示:

C:Program FilesDebugging Tools for Windows (x64)>gflags.exe -i memory.exe +ust

我只是稍微修改了代码以帮助我计算迭代次数并在 6.12 中运行它并使用 !heap -l 来检测泄漏 windbg 似乎正确报告 查看 BusyBlock 的计数

#include <windows.h>
int count =0;
void AllocateMemory() {
    int* a = new int[2000]; 
    ZeroMemory(a, 8000); 
    Sleep(1);
    count++;
}
int main(void) {   
while(1) { 
    AllocateMemory(); 
} 
return 0; 
} 

来自windbg的输出

0:000> .printf "%yn" ,@eip
leakmem!main (00401050)
0:000> ?? count ; !heap -l
int 0n0
Scanning references from 97 busy blocks (0 MBytes) ...No potential unreachable blocks were detected.
0:000> bp @eip+3 0n5
0:000> g
Breakpoint 0 hit
0:000> ?? count ; !heap -l
int 0n4
Scanning references from 101 busy blocks (0 MBytes) ...No potential unreachable blocks were detected.
0:000> bp 401053 0n15
breakpoint 0 redefined
0:000> bl
 0 e 00401053     000f (000f)  0:**** leakmem!main+0x3
0:000> g
Breakpoint 0 hit
0:000> ?? count ; !heap -l
int 0n19
Scanning references from 117 busy blocks (0 MBytes) ...
Entry     User      Heap      Segment       Size  PrevSize  Unused    Flags
-----------------------------------------------------------------------------
00421f98  00421fa0  00030000  00410000      1f58      1f58        18  busy extra
 fill
00425e48  00425e50  00030000  00410000      1f58      1f58        18  busy extra
 fill
00435908  00435910  00030000  00420000      1f58      1f58        18  busy extra
 fill
00437860  00437868  00030000  00420000      1f58      1f58        18  busy extra
 fill
004397b8  004397c0  00030000  00420000      1f58      1f58        18  busy extra
 fill
5 potential unreachable blocks were detected.
0:000>
相关文章: