!handle
!handle 擴展顯示目標(biāo)系統(tǒng)中一個或所有進程擁有的句柄的信息。
語法
用戶模式
!handle?[Handle?[UMFlags?[TypeName]]]?
!handle?-??
內(nèi)核模式
!handle?[Handle?[KMFlags?[Process?[TypeName]]]]?
參數(shù)
Handle
指定要顯示的句柄序號。如果Handle是-1或者省略,調(diào)試器顯示當(dāng)前進程關(guān)聯(lián)的所有句柄的數(shù)據(jù)。如果Handle 是0,調(diào)試器顯示所有句柄的數(shù)據(jù)。
UMFlags
(僅用戶模式) 指定顯示中應(yīng)該包括的內(nèi)容。該參數(shù)可以是任意的下面這些位值的和(默認值為1。)
Bit 0 (0x1)
顯示句柄類型信息。
Bit 1 (0x2)
顯示基本的句柄信息。
Bit 2 (0x4)
顯示句柄名信息。
Bit 3 (0x8)
如果可能的話,顯示對象相關(guān)的句柄信息。
KMFlags
(僅內(nèi)核模式) 指定顯示中應(yīng)該包含的內(nèi)容。該參數(shù)可以是任意的下面這些位值的和。(默認值是0x3。)
Bit 0 (0x1)
顯示基本句柄信息。
Bit 1 (0x2)
顯示對象的信息。
Bit 2 (0x4)
顯示free handle條目。如果不設(shè)置這一位或者Handle省略或為0,則顯示出來的句柄列表不包括free handle。如果Handle指定了單個free handle,則即使沒有設(shè)置這一位也會顯示出來。
Bit 4 (0x10)
(Windows?XP 和之后) 顯示內(nèi)核句柄表中的句柄而不是當(dāng)前進程的。
Bit 5 (0x20)
(Windows?XP 和之后) 將句柄當(dāng)作線程ID或進程ID,并且顯示相應(yīng)的內(nèi)核對象的信息。
Process
(僅內(nèi)核模式) 指定一個進程。可以使用進程ID或者進程對象的16進制地址。該參數(shù)必須指定目標(biāo)系統(tǒng)中正在運行的進程。如果設(shè)置為-1或者省略,則使用當(dāng)前進程。
TypeName
指定要確認的句柄類型。只有匹配該類型的句柄才會顯示出來。TypeName 是區(qū)分大小寫的。合法的類型有Event、Section、File、Port、Directory、SymbolLink、Mutant、WindowStation、Semaphore、Key、Token、Process 、Thread、Desktop、IoCompletion、Timer、Job和WaitablePort。
-?
(僅用戶模式) 在調(diào)試器命令窗口中顯示該擴展的幫助文本。
DLL
Windows?NT?4.0
|
Kdextx86.dll
Uext.dll
Ntsdexts.dll
|
Windows?2000
|
Kdextx86.dll
Uext.dll
Ntsdexts.dll
|
Windows?XP 和之后
|
Kdexts.dll
Uext.dll Ntsdexts.dll
|
注釋
可以在用戶模式和內(nèi)核模式活動調(diào)試時使用!handle 擴展。也可以在內(nèi)核模式dump文件上使用它。但如果創(chuàng)建時沒包含句柄信息,則不能在調(diào)試用戶模式dump文件時使用。(可以通過.dump?/mh (Create Dump File)命令來創(chuàng)建這種dump文件。)
用戶模式活動調(diào)試時,可以使用.closehandle?(Close Handle) 命令關(guān)閉一個或多個句柄。
下面是用戶模式下使用!handle 的示例。這條命令顯示句柄列表。
0:000>?!handle
Handle?4
??Type??????????Section
Handle?8
??Type??????????Event
Handle?c
??Type??????????Event
Handle?10
??Type??????????Event
Handle?14
??Type??????????Directory
Handle?5c
??Type??????????File
6?Handles
Type????????????Count
Event???????????3
Section?????????1
File????????????1
Directory???????1
下面的命令顯示句柄0x8的詳細信息。
0:000>?!handle?8?f
Handle?8
??Type??????????Event
??Attributes????0
??GrantedAccess?0x100003:
?????????Synch
?????????QueryState,ModifyState
??HandleCount???2
??PointerCount??3
??Name??????????<none>
??Object?Specific?Information
????Event?Type?Auto?Reset
????Event?is?Waiting
下面是內(nèi)核模式下使用!handle的示例。這條命令列舉所有句柄,包括free handle。
kd>?!handle?0?4
processor?number?0
PROCESS?80559800??SessionId:?0??Cid:?0000????Peb:?00000000??ParentCid:?0000
????DirBase:?00039000??ObjectTable:?e1000d60??TableSize:?380.
????Image:?Idle
New?version?of?handle?table?at?e1002000?with?380?Entries?in?use
0000:?free?handle,?Entry?address?e1002000,?Next?Entry?fffffffe
0004:?Object:?80ed5238??GrantedAccess:?001f0fff
0008:?Object:?80ed46b8??GrantedAccess:?00000000
000c:?Object:?e1281d00??GrantedAccess:?000f003f
0010:?Object:?e1013658??GrantedAccess:?00000000
......
0168:?Object:?ffb6c748??GrantedAccess:?00000003?(Protected)
016c:?Object:?ff811f90??GrantedAccess:?0012008b
0170:?free?handle,?Entry?address?e10022e0,?Next?Entry?00000458
0174:?Object:?80dfd5c8??GrantedAccess:?001f01ff
......
下面的命令顯示內(nèi)核句柄表中的0x14句柄的詳細信息。
kd>?!handle?14?13
processor?number?0
PROCESS?80559800??SessionId:?0??Cid:?0000????Peb:?00000000??ParentCid:?0000
????DirBase:?00039000??ObjectTable:?e1000d60??TableSize:?380.
????Image:?Idle
Kernel?New?version?of?handle?table?at?e1002000?with?380?Entries?in?use
0014:?Object:?e12751d0??GrantedAccess:?0002001f
Object:?e12751d0??Type:?(80ec8db8)?Key
????ObjectHeader:?e12751b8
????????HandleCount:?1??PointerCount:?1
????????Directory?Object:?00000000??Name:?\REGISTRY\MACHINE\SYSTEM\CONTROLSET001\CONTROL\SESSION?MANAGER\EXECUTIVE
附加信息
關(guān)于句柄的更多信息,查看!htrace 擴展、Microsoft Windows SDK 文檔,以及Mark Russinovich和David Solomon編寫的Microsoft Windows Internals。
!heap
!heap 擴展顯示堆使用信息,控制堆管理器中的斷點,檢測泄露的堆塊,搜索堆塊或者顯示頁堆(page heap)信息。
語法
Windows NT 4.0的語法
!heap?[HeapOptions]?[ValidationOptions]?[Heap]?
!heap?-b?[{alloc|realloc|free}?[Tag]]?[Heap?|?BreakAddress]?
!heap?-B?{alloc|realloc|free}?[Heap?|?BreakAddress]?
!heap?-??
Windows?2000的語法
!heap?[HeapOptions]?[ValidationOptions]?[Heap]?
!heap?-b?[{alloc|realloc|free}?[Tag]]?[Heap?|?BreakAddress]?
!heap?-B?{alloc|realloc|free}?[Heap?|?BreakAddress]?
!heap?-p?PageHeapOptions?
!heap?[-p]?-??
Windows?XP和之后的語法
!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]?-??
參數(shù)
Heap
指定堆序號或者堆的地址。默認值為1,用于指定進程堆。如果指定0,則顯示進程中所有堆的信息。省略Heap 則顯示進程中堆的簡明列表。
HeapOptions
可以使下面這些選項的任意組合。HeapOptions 值區(qū)分大小寫。
選項
|
作用
|
-v
|
使得調(diào)試器驗證指定的堆。
|
-a
|
顯示中包含指定堆的所有信息。這種情況下,大小會被四舍五入到堆的分配粒度。(運行!heap和 –a 選項相當(dāng)于使用-h -f –m這三個選項,會需要較長時間。)
|
-h
|
輸出中包含指定堆的所有條目。
|
-f
|
輸出中包含指定堆的所有空閑列表項(free list entries)。
|
-m
|
輸出重包含指定堆的所有段條目(segment entries)。
|
-t
|
使得輸出重包含指定堆的標(biāo)簽信息(tag information)。
|
-T
|
輸出中包含指定堆的偽標(biāo)簽條目(pseudo-tag entries)。
|
-g
|
輸出中包括全局標(biāo)簽信息(global tag information)。全局標(biāo)簽和每個無標(biāo)簽的分配(untagged allocation)關(guān)聯(lián)。
|
-s
|
輸出中包含指定堆的摘要信息。
|
-k
|
(僅x86目標(biāo)) 輸出重包含每個條目關(guān)聯(lián)的堆?;厮荨?/p>
|
-c
|
(僅Windows NT 4.0) 輸出中包含針對該堆的最近一次API調(diào)用。
|
ValidationOptions
可以是下面這些選項中的一個。ValidationOptions 區(qū)分大小寫。
選項
|
作用
|
-C
|
(僅Windows NT 4.0) 對指定的堆進行API調(diào)用跟蹤。使用該選項會交替的啟用和禁用這種跟蹤。初始的跟蹤狀態(tài)由傳遞給RtlCreateHeap 的標(biāo)志是否包含HEAP_CREATE_ENABLE_TRACING 決定。該狀態(tài)也可以通過全局標(biāo)志來改變。
|
-D
|
禁止指定堆的調(diào)用時驗證(validate-on-call)。
|
-E
|
啟用指定堆的調(diào)用時驗證(validate-on-call)。
|
-d
|
禁用指定堆的堆檢查(heap checking)。
|
-e
|
啟用指定堆的堆檢查(heap checking)。
|
BreakAddress
指定要設(shè)置或刪除斷點的塊的地址。
-b
使得調(diào)試器在堆管理器中設(shè)置條件斷點。-b 后可跟alloc、realloc或者 free,用于指定斷點是否在分配、重新分配或者釋放內(nèi)存時激活。如果BreakAddress 用來指定塊的地址,可以省略斷點類型。如果Heap用來指定堆地址或者堆序號,則必須包含類型和Tag參數(shù)。
Tag
指定堆中的標(biāo)簽名。
-B
使得調(diào)試器在堆管理器中移除一個條件斷點。必須指定斷點類型(alloc、 realloc或 free),并且必須和-b 選項使用的一樣。
-l
(Windows?XP和之后) 使得調(diào)試器檢查泄露的堆塊。
-s
(Windows?XP和之后) 指定需要摘要信息。如果省略SummaryOptions 和StatHeapAddress,則當(dāng)前進程關(guān)聯(lián)的所有堆的摘要信息都會顯示出來。
SummaryOptions
(Windows?XP 和之后) 可以是任意下面這些選項。SummaryOptions 不區(qū)分大小寫。
選項
|
作用
|
-v
|
驗證所有數(shù)據(jù)塊。
|
-b
BucketSize
|
指定存儲單元(bucket)的大小。默認值為1024 bit。
|
-d
DumpBlockSize
|
指定存儲單元大小。
|
-a
|
?
|
-c
|
指示每個塊得內(nèi)容都應(yīng)該顯示出來。
|
StatHeapAddress
(Windows?XP和之后) 指定堆的地址。如果為0或者省略,則顯示當(dāng)前進程關(guān)聯(lián)的所有堆。
-i
Heap
(Windows?XP 和之后) 顯示指定的Heap 的信息。
-x [-v]
(Windows?XP 和之后) 使得調(diào)試器搜索包含指定地址的堆塊。如果添加了-v ,命令會在當(dāng)前進程的整個虛擬內(nèi)存空間中搜索指向該堆塊的指針。
Address
(Windows?XP 和之后) 指定要搜索的地址。
-p
(Windows?2000 和之后) 指示需要頁堆(page heap)信息。如果沒有和任何PageHeapOptions 一起使用,則所有頁堆都會顯示出來。
PageHeapOptions
可以是下面這些選項中的單個。PageHeapOptions 區(qū)分大小寫。如果不指定選項,所有可能的頁堆句柄都會顯示出來。
選項
|
作用
|
-h
Handle
|
使得調(diào)試器顯示句柄為Handle的頁堆的詳細信息。
|
-a
Address
|
使得調(diào)試器查找塊中包含Address的頁堆。會包含該地址和完整的頁堆塊的關(guān)系的詳細信息,如是否該地址是頁堆的一部分、它在塊中的偏移,以及這個塊已經(jīng)被分配還是空閑的。在可能時還會包含堆棧回溯。使用該選項時,顯示的大小是堆分配粒度的倍數(shù)。
|
-t[c|s] [Traces]
|
使得調(diào)試器顯示大量使用堆的用戶(heavy heap users)的紀(jì)錄(collected traces)。Traces指定要顯示的紀(jì)錄數(shù)量,默認值為4。如果有比指定的數(shù)量更多的紀(jì)錄,則顯示前面的部分紀(jì)錄。如果使用-t 或者-tc ,則紀(jì)錄以使用記數(shù)(count usage)排序。如果使用-ts ,則紀(jì)錄以大小排序。 (-tc 和-ts 選項僅在Windows XP中支持,-t選項在Windows XP和之前的版本中都支持。)
|
-fi [Traces]
|
(Windows?XP 和之后) 使得調(diào)試器顯示最近的故障注入紀(jì)錄(fault injection traces)。 Traces 指定要顯示的熟練,默認值為4。
|
-all
|
(Windows?XP和之后) 使得調(diào)試器顯示所有頁堆的詳細信息。
|
-?
|
使得調(diào)試器顯示頁堆幫助(page heap help),包括堆塊的圖表。(這些圖表在下面的注釋節(jié)中可以看到。)
|
使用任何!heap -p 擴展命令之前,目標(biāo)進程中必須已經(jīng)啟用了頁堆。查看后面注釋節(jié)中的詳細說明。
-srch
(Windows?XP 和之后) 在所有堆中進行查找。
Pattern
(Windows?XP 和之后) 要查找的內(nèi)容。
Size
(Windows?XP 和之后) 可以是下面選項中的任意一個。用于指定pattern 的大小。必須使用'-'。
選項
|
作用
|
-b
|
pattern的大小是一個BYTE。
|
-w
|
pattern的大小是一個WORD。
|
-d
|
pattern的大小是一個DWORD。
|
-q
|
pattern的大小是一個QWORD。
|
如果不指定上面任何一個,則會假定pattern 的大小和機器的指針大小一致。
-flt
(Windows?XP和之后) 將顯示出來的堆限制為指定大小或大小范圍的。
FilterOptions
(Windows?XP 和之后) 可以是下面選項之一。FilterOptions 區(qū)分大小寫。
選項
|
作用
|
s
Size
|
限制顯示出來的堆必須是指定的大小。
|
r
SizeMin SizeMax
|
限制顯示出來的堆大小在指定范圍內(nèi)。
|
-stat
(Windows?XP和之后) 顯示指定的堆的使用統(tǒng)計。
-h
Handle
(Windows?XP 和之后) 只有句柄為Handle的堆的使用統(tǒng)計會顯示出來。如果Handle為0或者省略,則所有堆的使用統(tǒng)計都會顯示。
-grp
GroupBy
(Windows?XP 和之后) 按照GroupBy 的指定重新排序顯示。GroupBy 選項可以是下表中的值。
選項
|
作用
|
A
|
根據(jù)分配大小顯示使用統(tǒng)計。
|
B
|
根據(jù)塊數(shù)量顯示使用統(tǒng)計。
|
S
|
根據(jù)每次分配的總大小顯示使用統(tǒng)計。
|
MaxDisplay
(Windows?XP和之后) 限制輸出最多為MaxDisplay 行。
-?
在調(diào)試器命令窗口中顯示該命令的簡要幫助文本。使用!heap -? 查看常規(guī)幫助,!heap -p -? 查看頁堆幫助。 (頁堆幫助只在Windows 2000和之后的系統(tǒng)中可用。)
DLL
Windows?NT?4.0
|
Ext.dll
Kdextx86.dll
Ntsdexts.dll
|
Windows?2000
|
Ext.dll
Kdextx86.dll
Ntsdexts.dll
|
Windows?XP 和之后
|
Ext.dll
Exts.dll
|
注釋
該擴展命令可以用來實現(xiàn)幾種任務(wù)。
標(biāo)準(zhǔn)的!heap 命令用來顯示當(dāng)前進程的堆信息。(僅針對用戶模式進程。!pool 擴展命令用于系統(tǒng)進程。)
!heap -b 和!heap -B 命令用于在堆管理器中創(chuàng)建或者刪除條件斷點。
!heap -l 命令檢查泄露的堆塊。它使用一種垃圾回收算法(garbage collector algorithm)來檢測沒有被進程地址空間中任何地方引用到的已占用塊(busy blocks)。對很大的程序,可能需要花費數(shù)分鐘才能完成。該命令只在Windows XP和之后版本中可以使用。
!heap -x 命令搜索包含給定地址的堆塊。如果使用了-v 選項,該命令還會搜索當(dāng)前進程的整個虛擬地址空間,以獲得指向該堆塊的指針。這個命令僅在Windows XP和之后版本中可以使用。
!heap -p 命令顯示各種形式的頁堆(page heap)信息。僅在Windows 2000(Service Pack 1或之后)、Windows XP、以及之后版本的Windows中可用。如果在調(diào)試Windows NT 4.0,則需要使用!dphdump、 !dphfind、!dphflags和!dphhogs來替代。
使用!heap –p之前,必須啟用目標(biāo)進程的頁堆(page heap)。這可以通過全局標(biāo)志 (gflags.exe) 實用工具實現(xiàn)。打開該工具,在Image File Name 文本框中填入目標(biāo)進程的名字,選擇Image File Options 以及Enable page heap ,然后點擊Apply 。也可以從命令提示符窗口輸入gflags /i xxx.exe +hpa 來運行全局標(biāo)志工具,xxx.exe 是目標(biāo)程序的名字。
注意在NT 4.0中,只有在調(diào)試器已經(jīng)附加或者進程啟動時全局標(biāo)志已經(jīng)進行過了適當(dāng)?shù)脑O(shè)置時,頁堆命令才能正確工作。
!heap -p -t[c|s] 命令在Windows XP之后就不支持了。可以使用調(diào)試器工具包中的UMDH工具來獲得類似的結(jié)果。
!heap -srch 命令顯示包含指定模板的堆條目(heap entries)。該命令僅在Windows XP和之后版本中可以使用。
!heap -flt 命令限制只顯示分配大小為指定值的堆。該命令僅在Windows XP和之后版本中可用。
!heap -stat 命令顯示堆使用統(tǒng)計。該命令僅在Windows XP和之后版本可用。
這里是一個標(biāo)準(zhǔn)的!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'
下面的圖表是堆塊的格式。這是Windows 2000(Service Pack 1和之后)、Windows XP、以及之后的系統(tǒng)中的形式。
Light page heap 塊 — 已分配:
?+-----+---------------+---+??????????????????????????????????
?|?????|???????????????|???|??????????????????????????????????
?+-----+---------------+---+??????????????????????????????????
????^?????????^??????????^????????????????????????????????????
????|?????????|??????????8?
字節(jié)后綴
?(
以
0xA0
填充
)????
????|?????????
用戶分配
(User?allocation)?(
如果沒有要求清
0
,則填充為
?E0 )?
????
塊首
?(
以
?0xABCDAAAA?
開頭,
0xDCBAAAAA
結(jié)尾
)?
Light page heap 塊 — 已釋放:
?+-----+---------------+---+??????????????????????????????????
?|?????|???????????????|???|??????????????????????????????????
?+-----+---------------+---+??????????????????????????????????
????^?????????^??????????^????????????????????????????????????
????|?????????|??????????8?
字節(jié)后綴
?(
以
0xA0
填充
)????
????|?????????
用戶分配
?(
如果沒有要求清
0
,則填充為
?E0)??????????
????
塊首
?(
以
?0xABCDAAA9?
開頭,
0xDCBAAA9
結(jié)尾
)?
Full page heap 塊 — 已分配:
?+-----+---------+---+-------?????????????????????????????????
?|?????|?????????|???|??...?N/A?page??????????????????????????
?+-----+---------+---+-------?????????????????????????????????
????^???????^??????^??????????????????????????????????????????
????|???????|??????0-7?
字節(jié)后綴
?(
以
?0xD0
填充
)????????
????|???????
用戶分配
?(
如果未要求清
0
,
Windows 2000
中填充為
E0 ,???
????????????Windows?XP
中填充為
C0 )???????
????
塊首
?(
以
?0xABCDBBBB?
開頭,
0xDCBABBBB
結(jié)尾
)?
Full page heap 塊 —已釋放:
?+-----+---------+---+-------?????????????????????????????????
?|?????|?????????|???|??...?N/A?page??????????????????????????
?+-----+---------+---+-------?????????????????????????????????
????^???????^??????^??????????????????????????????????????????
????|???????|??????0-7?
字節(jié)后綴
?(
以
?0xD0
填充
)????????
????|???????
用戶分配
?(
以
?F0?
填充
)????????????
????
塊首
?(
以
?0xABCDBBA?
開頭,
0xDCBABBBA
結(jié)尾
)?
要查看Windows 2000下對堆塊或者full page heap 塊的分配和釋放的堆棧回溯,可以對頭地址使用dds?(Display Words and Symbols) 命令。
要查看Windows XP和之后的Windows下對堆塊或者full page heap 塊的分配和釋放的堆?;厮?,對頭地址實用 dt?DPH_BLOCK_INFORMATION ,然后對StackTrace字段使用 dds 。
Windows 2000的Full page heap 塊位于包含用戶分配內(nèi)存的頁面的開頭或者前一個頁面的開頭。
附加信息
關(guān)于堆的更多信息,查看Microsoft Windows SDK 文檔、Windows Driver Kit (WDK)文檔、以及Mark Russinovich和David Solomon編寫的Microsoft Windows Internal。