WinDbg常用命令系列---!heap


!heap

簡介

!heap擴展顯示堆使用信息、控制堆管理器中的斷點、檢測泄漏的堆塊、搜索堆塊或顯示頁堆信息。此擴展支持段堆和NT堆。使用!heap沒有參數列出所有堆及其類型的堆。

使用形式

!heap [HeapOptions] [ValidationOptions] [Heap] !heap -b [{alloc|realloc|free} [Tag]] [Heap | BreakAddress] !heap -B {alloc|realloc|free} [Heap | BreakAddress] !heap -l !heap -s [SummaryOptions] [StatHeapAddress] !heap -i HeapAddress !heap -x [-v] Address !heap -p [PageHeapOptions] !heap -srch [Size] Pattern !heap -flt FilterOptions !heap -stat [-h Handle [-grp GroupBy [MaxDisplay]]] !heap [-p] -? !heap -triage [Handle | Address] 

參數

這些參數適用於Segment和NT堆。

  • -s
    指定正在請求摘要信息。如果省略SummaryOptions和StatHeapAddress,則顯示與當前進程關聯的所有堆的摘要信息。
  • SummaryOptions
    可以是以下選項的任意組合。SummaryOptions不區分大小寫。輸入!heap -s -?了解更多信息。
    選項 效果

    -v

    驗證所有數據塊。

    -b BucketSize

    指定存儲桶大小。 默認值為1024位。

    -d DumpBlockSize

    指定存儲桶大小。

    -a

    轉儲所有堆塊。

    -c

    指定應顯示每個塊的內容。

  • -triage [Handle | Address]
    使調試器自動搜索進程堆中的失敗。如果將堆句柄指定為參數,則檢查該堆;否則,將搜索所有堆中包含給定地址的堆,如果找到,則檢查該堆。使用-triage是驗證低碎片堆(LFH)損壞的唯一方法。
  • -x[-v]
    使調試器搜索包含指定地址的堆塊。如果添加了-v,該命令將搜索當前進程的整個虛擬內存空間以查找指向此堆塊的指針。
  • -l
    使調試器檢測泄漏的堆塊。
  • -iAddress -h HeapAddress
    顯示有關指定 的信息。
  • Address
    指定要搜索的地址。
  • -?
    在調試器命令窗口中顯示此擴展的簡短幫助文本。使用!heap -?一般的幫助,而且!heap -p -?頁面堆幫助。

這些參數僅適用於NT堆。

  • HeapOptions
    可以是以下選項的任意組合。HeapOptions值區分大小寫。
    選項 效果

    -v

    使調試器驗證指定的堆。此選項不會檢測到低碎片堆(LFH)損壞。使用-triage代替。

     

    -a

    使顯示包含指定堆的所有信息。 大小,在本例中,將向上舍入到堆粒度。 (運行!heap 具有-a選項的堆等效於使用三個選項-h-f-m運行它,這可能需要很長時間。)

    -h

    使顯示包含指定堆的所有非 LFH 條目。

    -hl

    使顯示包含指定堆的所有條目,包括 LFH 條目。

    -f

    使顯示包含指定堆的所有可用列表項。

    -m

    使顯示內容包括指定堆的所有段條目。

    -t

    使顯示包含指定堆的標記信息。

    -T

    使顯示包含指定堆的偽標記條目。

    -g

    使顯示內容包含全局標記信息。 全局標記與每個未標記的分配相關聯。

    -s

    使顯示內容包括指定堆的摘要信息。

    -k

    (僅限基於 x86 的目標)使顯示內容包括與每個條目關聯的 stack backtrace。

  • ValidationOptions
    可以是以下任一選項。ValidationOptions區分大小寫。
    選項 效果

    -D

    對指定的堆禁用調用驗證。

    -E

    為指定的堆啟用調用時驗證。

    -d

    為指定的堆禁用堆檢查。

    -e

    為指定的堆啟用堆檢查。

  • -iHeapAddress or HeapAddress
    顯示有關指定 的信息。
  • BreakAddress
    指定要在其中設置或刪除斷點的塊的地址。
  • -b
    使調試器在堆管理器中創建條件斷點。-b選項可以后跟alloc、realloc或free;這指定是否通過分配、重新分配或釋放內存來激活斷點。如果使用BreakAddress指定塊的地址,則可以省略斷點類型。如果使用Heap指定堆地址或堆索引,則必須包括類型以及標記參數。
  • Tag
    指定堆中的標記名稱。
  • -B
    使調試器從堆管理器中刪除條件斷點。必須指定斷點類型(alloc、realloc或free),並且必須與-b選項使用的斷點類型相同。
  • StatHeapAddress
    指定堆的地址。 如果此為0或省略,則顯示與當前進程關聯的所有堆。
  • -p
    指定正在請求頁堆信息。 如果在沒有任何PageHeapOptions的情況下使用,則將顯示所有頁堆。
  • PageHeapOptions
    可以是以下選項中的任何一個。 PageHeapOptions區分大小寫。 如果未指定任何選項,則將顯示所有可能的頁堆句柄。
    選項 效果

    -h Handle

    使調試器顯示有關帶有句柄句柄的頁堆的詳細信息。

    -a Address

    使調試器查找其塊包含地址的頁堆。 將包括此地址如何包含到整頁堆塊的完整詳細信息,如此地址是否是頁面堆的一部分、其在塊內的偏移量,以及是分配塊還是釋放塊。 每次提供堆棧跟蹤。 使用此選項時,大小以堆分配粒度的倍數顯示。

    -t[c|s][Traces]

    使調試器顯示大量堆用戶的已收集跟蹤。 跟蹤指定要顯示的跟蹤數;默認值為四。 如果跟蹤超過指定的數量,則顯示最早的跟蹤。 如果使用-t-tc ,則跟蹤按計數使用情況進行排序。 如果使用-ts ,則跟蹤按大小排序。 (僅 Windows XP 支持-tc-ts選項; 僅在 windows xp 和更早版本的 windows 中支持-t選項。)

    -fi[Traces]

    使調試器顯示最新的錯誤注入跟蹤。 跟蹤指定要顯示的數量;默認值為4。

    -all

    使調試器顯示有關所有頁堆的詳細信息。

    -?

    使調試器顯示頁堆幫助,包括堆塊的關系圖。 (也可以在下面的 "備注" 部分中查看這些關系圖。)

  • -srch
    掃描給定模式的所有堆。
  • Pattern 
    指定要查找的模式。
  • Size
    可以是以下選項中的任何一個。 這將指定模式的大小。 "-" 是必需的。
    選項 效果

    -b

    模式大小為1個字節。

    -w

    模式為一個大小的單詞。

    -d

    模式為一個 DWORD 大小。

    -q

    模式為大小為1個 QWORD。


    如果未指定上述任何一個,則假設模式的大小與計算機指針的大小相同。
  • -flt
    將顯示范圍限制為僅包含具有指定大小或大小范圍的堆。
  • FilterOptions
    可以是以下選項中的任何一個。 FilterOptions區分大小寫。
    選項 效果

    s 大小

    將顯示范圍限制為僅包含指定大小的堆。

    r SizeMin SizeMax

    將顯示范圍限制為僅包含指定大小范圍內的堆。


  • -stat
    顯示指定堆的使用情況統計信息。
  • -h Handle
    導致顯示僅顯示在句柄上的堆的使用情況統計信息。 如果Handle為0或省略,則顯示所有堆的使用情況統計信息。
  • -grp GroupBy
    GroupBy指定的重新排序顯示。 可以在下表中找到GroupBy的選項。
    選項 效果

    A

    根據分配大小顯示使用情況統計信息。

    B

    根據塊計數顯示使用情況統計信息。

    S

    根據每個分配的總大小顯示使用量統計信息。


  • MaxDisplay
    將輸出限制為僅MaxDisplay的行數。

支持環境

Windows XP 和更高版本 Ext .dll Exts

備注

此擴展命令可用於執行各種任務。

標准 !heap命令用於顯示當前進程的堆信息。 (這應該只用於用戶模式進程。 !heap Pool extension 命令應用於系統進程。)

!heap-b!heap -B命令用於在堆管理器中創建和刪除條件斷點。

!heap -l命令檢測泄漏的堆塊。 它使用垃圾回收器算法來檢測未在進程地址空間中的任何位置引用的堆中的所有繁忙塊。 對於大型應用程序,可能需要幾分鍾才能完成。 此命令僅在 Windows XP 和更高版本的 Windows 中可用。

!heap -x命令搜索包含給定地址的堆塊。 如果使用了 -v選項,則此命令將另外在當前進程的整個虛擬內存空間中搜索指向此堆塊的指針。 此命令僅在 Windows XP 和更高版本的 Windows 中可用。

!heap -p命令顯示了各種形式的頁堆信息。 使用 !heap -p之前,必須為目標進程啟用頁堆。 這是通過全局標志(gflags)實用程序來完成的。 為此,請啟動實用工具,在 "映像文件" 文本框中填寫目標應用程序的名稱,選擇 "映像文件選項" 並啟用頁堆,並單擊 "應用"。 或者,你可以通過鍵入gflags/i xxx + hpa(其中, xxx是目標應用程序的名稱)從命令提示符窗口啟動全局標志實用程序。

不支持在 Windows XP 以外的情況!heap -p -t[c|s]命令。 使用隨調試器包一起提供的UMDH工具來獲取類似的結果。

!heap -srch命令顯示包含某個指定模式的堆條目。

!heap -flt命令會將顯示范圍限制為僅指定大小的堆分配。

!heap -stat命令顯示堆使用情況統計信息。

下面是標准!heap 命令的示例:

0:000> !ntsdexts.heap -a
Index   Address  Name      Debugging options enabled
  1:   00250000 
    Segment at 00250000 to 00350000 (00056000 bytes committed)
    Flags:               50000062
    ForceFlags:          40000060
    Granularity:         8 bytes
    Segment Reserve:     00100000
    Segment Commit:      00004000
    DeCommit Block Thres:00000400
    DeCommit Total Thres:00002000
    Total Free Size:     000003be
    Max. Allocation Size:7ffddfff
    Lock Variable at:    00250b54
    Next TagIndex:       0012
    Maximum TagIndex:    07ff
    Tag Entries:         00350000
    PsuedoTag Entries:   00250548
    Virtual Alloc List:  00250050
    UCR FreeList:        002504d8
    128-bit bitmap of free lists
    FreeList Usage:      00000014 00000000 00000000 00000000
              Free    Free
              List    List
#       Head      Blink      Flink
    FreeList[ 00 ] at 002500b8: 002a4378 . 002a4378
                                0x02 - HEAP_ENTRY_EXTRA_PRESENT
                                0x04 - HEAP_ENTRY_FILL_PATTERN
        Entry     Prev    Cur   0x10 - HEAP_ENTRY_LAST_ENTRY

Address   Size    Size  flags
002a4370: 00098 . 01c90 [14] - free
    FreeList[ 02 ] at 002500c8: 0025cb30 . 002527b8
002527b0: 00058 . 00010 [04] - free
0025cb28: 00088 . 00010 [04] - free
    FreeList[ 04 ] at 002500d8: 00269a08 . 0026e530
0026e528: 00038 . 00020 [04] - free
0026a4d0: 00038 . 00020 [06] - free
0026f9b8: 00038 . 00020 [04] - free
0025cda0: 00030 . 00020 [06] - free
00272660: 00038 . 00020 [04] - free
0026ab60: 00038 . 00020 [06] - free
00269f20: 00038 . 00020 [06] - free
00299818: 00038 . 00020 [04] - free
0026c028: 00038 . 00020 [06] - free
00269a00: 00038 . 00020 [46] - free
 
    Segment00 at 00250b90:
Flags:           00000000
Base:            00250000
First Entry:     00250bc8
Last Entry:      00350000
Total Pages:     00000080
Total UnCommit:  00000055
Largest UnCommit:000aa000
UnCommitted Ranges: (1)
    002a6000: 000aa000

    Heap entries for Segment00 in Heap 250000
                        0x01 - HEAP_ENTRY_BUSY            
                        0x02 - HEAP_ENTRY_EXTRA_PRESENT   
                        0x04 - HEAP_ENTRY_FILL_PATTERN    
                        0x08 - HEAP_ENTRY_VIRTUAL_ALLOC   
                        0x10 - HEAP_ENTRY_LAST_ENTRY      
                        0x20 - HEAP_ENTRY_SETTABLE_FLAG1  
                        0x40 - HEAP_ENTRY_SETTABLE_FLAG2  
Entry     Prev    Cur   0x80 - HEAP_ENTRY_SETTABLE_FLAG3  

Address   Size    Size  flags       (Bytes used)    (Tag name)
00250000: 00000 . 00b90 [01] - busy (b90)
00250b90: 00b90 . 00038 [01] - busy (38) 
00250bc8: 00038 . 00040 [07] - busy (24), tail fill (NTDLL!LDR Database)
00250c08: 00040 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
00250c68: 00060 . 00028 [07] - busy (10), tail fill (NTDLL!LDR Database)
00250c90: 00028 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
00250cf0: 00060 . 00050 [07] - busy (38), tail fill (Objects=  80)
00250d40: 00050 . 00048 [07] - busy (2e), tail fill (NTDLL!LDR Database)
00250d88: 00048 . 00c10 [07] - busy (bf4), tail fill (Objects>1024)
00251998: 00c10 . 00030 [07] - busy (12), tail fill (NTDLL!LDR Database)
...
002525c0: 00030 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
00252620: 00060 . 00050 [07] - busy (38), tail fill (NTDLL!LDR Database)
00252670: 00050 . 00040 [07] - busy (22), tail fill (NTDLL!CSRSS Client)
002526b0: 00040 . 00040 [07] - busy (24), tail fill (Objects=  64)
002526f0: 00040 . 00040 [07] - busy (24), tail fill (Objects=  64)
00252730: 00040 . 00028 [07] - busy (10), tail fill (Objects=  40)
00252758: 00028 . 00058 [07] - busy (3c), tail fill (Objects=  88)
002527b0: 00058 . 00010 [04] free fill
002527c0: 00010 . 00058 [07] - busy (3c), tail fill (NTDLL!LDR Database)
00252818: 00058 . 002d0 [07] - busy (2b8), tail fill (Objects= 720)
00252ae8: 002d0 . 00330 [07] - busy (314), tail fill (Objects= 816)
00252e18: 00330 . 00330 [07] - busy (314), tail fill (Objects= 816)
00253148: 00330 . 002a8 [07] - busy (28c), tail fill (NTDLL!LocalAtom)
002533f0: 002a8 . 00030 [07] - busy (18), tail fill (NTDLL!LocalAtom)
00253420: 00030 . 00030 [07] - busy (18), tail fill (NTDLL!LocalAtom)
00253450: 00030 . 00098 [07] - busy (7c), tail fill (BASEDLL!LMEM)
002534e8: 00098 . 00060 [07] - busy (44), tail fill (BASEDLL!TMP)
00253548: 00060 . 00020 [07] - busy (1), tail fill (Objects=  32)
00253568: 00020 . 00028 [07] - busy (10), tail fill (Objects=  40)
00253590: 00028 . 00030 [07] - busy (16), tail fill (Objects=  48)
...
0025ccb8: 00038 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
0025cd18: 00060 . 00058 [07] - busy (3c), tail fill (NTDLL!LDR Database)
0025cd70: 00058 . 00030 [07] - busy (18), tail fill (NTDLL!LDR Database)
0025cda0: 00030 . 00020 [06] free fill (NTDLL!Temporary)
0025cdc0: 00020 . 00258 [07] - busy (23c), tail fill (Objects= 600)
0025d018: 00258 . 01018 [07] - busy (1000), tail fill (Objects>1024)
0025e030: 01018 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
...
002a4190: 00028 . 00118 [07] - busy (100), tail fill (BASEDLL!GMEM)
002a42a8: 00118 . 00030 [07] - busy (18), tail fill (Objects=  48)
002a42d8: 00030 . 00098 [07] - busy (7c), tail fill (Objects= 152)
002a4370: 00098 . 01c90 [14] free fill
002a6000:      000aa000      - uncommitted bytes.

下面是!heap -l命令的示例:

1:0:011> !heap -l
1:Heap 00170000
Heap 00280000
Heap 00520000
Heap 00b50000
Heap 00c60000
Heap 01420000
Heap 01550000
Heap 016d0000
Heap 019b0000
Heap 01b40000
Scanning VM ...
## Entry     User      Heap      Segment       Size  PrevSize  Flags

001b2958  001b2960  00170000  00000000        40        18  busy extra
001b9cb0  001b9cb8  00170000  00000000        80       300  busy extra
001ba208  001ba210  00170000  00000000        80        78  busy extra
001cbc90  001cbc98  00170000  00000000        e0        48  busy extra
001cbd70  001cbd78  00170000  00000000        d8        e0  busy extra
001cbe90  001cbe98  00170000  00000000        68        48  busy extra
001cbef8  001cbf00  00170000  00000000        58        68  busy extra
001cc078  001cc080  00170000  00000000        f8       128  busy extra
001cc360  001cc368  00170000  00000000        80        50  busy extra
001cc3e0  001cc3e8  00170000  00000000        58        80  busy extra
001fe550  001fe558  00170000  00000000       150       278  busy extra
001fe6e8  001fe6f0  00170000  00000000        48        48  busy extra
002057a8  002057b0  00170000  00000000        58        58  busy extra
00205800  00205808  00170000  00000000        48        58  busy extra
002058b8  002058c0  00170000  00000000        58        70  busy extra
00205910  00205918  00170000  00000000        48        58  busy extra
00205958  00205960  00170000  00000000        90        48  busy extra
00246970  00246978  00170000  00000000        60        88  busy extra
00251168  00251170  00170000  00000000        78        d0  busy extra user_flag
00527730  00527738  00520000  00000000        40        40  busy extra
00527920  00527928  00520000  00000000        40        80  busy extra
21 leaks detected.

此示例中的表包含發現的所有21個泄漏。

下面是!heap x命令的示例:

0:011> !heap 002057b8 -x
## Entry     User      Heap      Segment       Size  PrevSize  Flags

002057a8  002057b0  00170000  00170640        58        58  busy extra

下面是!heap -x v命令的示例:

1:0:011> !heap 002057b8 -x -v
## 1:Entry     User      Heap      Segment       Size  PrevSize  Flags

002057a8  002057b0  00170000  00170640        58        58  busy extra

Search VM for address range 002057a8 - 002057ff : 00205990 (002057d0),

在此示例中,有一個指向地址0x00205990 的堆塊的指針。

下面是 !heap flt s命令的示例:

0:001>!heap -flt s 0x50

這會顯示大小0x50 的所有分配。

下面是 !heap flt r命令的示例:

0:001>!heap -flt r 0x50 0x80

這會顯示大小介於0x50 和0x7F 之間的每個分配。

下面是 !heap srch命令的示例。

0:001> !heap -srch 77176934
    _HEAP @ 00090000
   in HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state
        00099A48: 0018 : 0005 [01] - 00099A50 (000000B8) - (busy)
          ole32!CALLFRAME_CACHE<INTERFACE_HELPER_CLSID>::`vftable'
    _HEAP @ 00090000
   in HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state
        00099B58: 0018 : 0005 [01] - 00099B60 (000000B8) - (busy)
          ole32!CALLFRAME_CACHE<INTERFACE_HELPER_CLSID>::`vftable'

輕型頁堆塊--已分配:

 +-----+---------------+---+                                  
 |     |               |   |                                  
 +-----+---------------+---+                                  
    ^         ^          ^                                    
    |         |          8 suffix bytes (filled with 0xA0)    
    |         User allocation (filled with E0 if zeroing not requested) 
    Block header (starts with 0xABCDAAAA and ends with 0xDCBAAAAA) 

輕型頁堆塊--已釋放:

 +-----+---------------+---+                                  
 |     |               |   |                                  
 +-----+---------------+---+                                  
    ^         ^          ^                                    
    |         |          8 suffix bytes (filled with 0xA0)    
    |         User allocation (filled with F0 bytes)          
    Block header (starts with 0xABCDAAA9 and ends with 0xDCBAAA9) 

整頁堆塊--已分配:

 +-----+---------+---+-------                                 
 |     |         |   |  ... N/A page                          
 +-----+---------+---+-------                                 
    ^       ^      ^                                          
    |       |      0-7 suffix bytes (filled with 0xD0)        
    |       User allocation (if zeroing not requested, filled   
            with C0)       
    Block header (starts with 0xABCDBBBB and ends with 0xDCBABBBB) 

整頁堆塊--已釋放:

 +-----+---------+---+-------                                 
 |     |         |   |  ... N/A page                          
 +-----+---------+---+-------                                 
    ^       ^      ^                                          
    |       |      0-7 suffix bytes (filled with 0xD0)        
    |       User allocation (filled with F0 bytes)            
    Block header (starts with 0xABCDBBA and ends with 0xDCBABBBA) 
要查看堆塊或整頁堆塊的分配或釋放的堆棧跟蹤,請使用dt DPH_block_INFORMATION和頭地址,然后使用dds和塊的stack trace字段。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM