S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

windbg 的翻译文档

Posted on 2009-03-27 21:37 S.l.e!ep.¢% 阅读(573) 评论(0)  编辑 收藏 引用 所属分类: WinDbg

!handle

!handle 扩展显示目标系统中一个或所有进程拥有的句柄的信息。

语法

用户模式

!handle [Handle [UMFlags [TypeName]]] 
!handle -? 

内核模式

!handle [Handle [KMFlags [Process [TypeName]]]] 

参数

Handle

指定要显示的句柄序号。如果Handle是-1或者省略,调试器显示当前进程关联的所有句柄的数据。如果Handle 是0,调试器显示所有句柄的数据。

UMFlags

(仅用户模式) 指定显示中应该包括的内容。该参数可以是任意的下面这些位值的和(默认值为1。)

Bit 0 (0x1)

显示句柄类型信息。

Bit 1 (0x2)

显示基本的句柄信息。

Bit 2 (0x4)

显示句柄名信息。

Bit 3 (0x8)

如果可能的话,显示对象相关的句柄信息。

KMFlags

(仅内核模式) 指定显示中应该包含的内容。该参数可以是任意的下面这些位值的和。(默认值是0x3。)

Bit 0 (0x1)

显示基本句柄信息。

Bit 1 (0x2)

显示对象的信息。

Bit 2 (0x4)

显示free handle条目。如果不设置这一位或者Handle省略或为0,则显示出来的句柄列表不包括free handle。如果Handle指定了单个free handle,则即使没有设置这一位也会显示出来。

Bit 4 (0x10)

(Windows XP 和之后) 显示内核句柄表中的句柄而不是当前进程的。

Bit 5 (0x20)

(Windows XP 和之后) 将句柄当作线程ID或进程ID,并且显示相应的内核对象的信息。

Process

(仅内核模式) 指定一个进程。可以使用进程ID或者进程对象的16进制地址。该参数必须指定目标系统中正在运行的进程。如果设置为-1或者省略,则使用当前进程。

TypeName

指定要确认的句柄类型。只有匹配该类型的句柄才会显示出来。TypeName 是区分大小写的。合法的类型有Event、Section、File、Port、Directory、SymbolLink、Mutant、WindowStation、Semaphore、Key、Token、Process 、Thread、Desktop、IoCompletion、Timer、Job和WaitablePort。

-?

(仅用户模式)调试器命令窗口中显示该扩展的帮助文本。

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

注释

可以在用户模式和内核模式活动调试时使用!handle 扩展。也可以在内核模式dump文件上使用它。但如果创建时没包含句柄信息,则不能在调试用户模式dump文件时使用。(可以通过.dump /mh (Create Dump File)命令来创建这种dump文件。)

用户模式活动调试时,可以使用.closehandle (Close Handle) 命令关闭一个或多个句柄。

下面是用户模式下使用!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

下面是内核模式下使用!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
......

下面的命令显示内核句柄表中的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

附加信息

关于句柄的更多信息,查看!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 [-vAddress 
!heap -p [PageHeapOptions
!heap -srch [SizePattern
!heap -flt FilterOptions
!heap -stat [-h Handle [-grp GroupBy [MaxDisplay]]]
!heap [-p-? 

参数

Heap

指定堆序号或者堆的地址。默认值为1,用于指定进程堆。如果指定0,则显示进程中所有堆的信息。省略Heap 则显示进程中堆的简明列表。

HeapOptions

可以使下面这些选项的任意组合。HeapOptions 值区分大小写。

选项

作用

-v

使得调试器验证指定的堆。

-a

显示中包含指定堆的所有信息。这种情况下,大小会被四舍五入到堆的分配粒度。(运行!heap–a 选项相当于使用-h -f –m这三个选项,会需要较长时间。)

-h

输出中包含指定堆的所有条目。

-f

输出中包含指定堆的所有空闲列表项(free list entries)。

-m

输出重包含指定堆的所有段条目(segment entries)。

-t

使得输出重包含指定堆的标签信息(tag information)。

-T

输出中包含指定堆的伪标签条目(pseudo-tag entries)。

-g

输出中包括全局标签信息(global tag information)。全局标签和每个无标签的分配(untagged allocation)关联。

-s

输出中包含指定堆的摘要信息。

-k

(仅x86目标) 输出重包含每个条目关联的堆栈回溯。

-c

(仅Windows NT 4.0) 输出中包含针对该堆的最近一次API调用。

ValidationOptions

可以是下面这些选项中的一个。ValidationOptions 区分大小写。

选项

作用

-C

(仅Windows NT 4.0) 对指定的堆进行API调用跟踪。使用该选项会交替的启用和禁用这种跟踪。初始的跟踪状态由传递给RtlCreateHeap 的标志是否包含HEAP_CREATE_ENABLE_TRACING 决定。该状态也可以通过全局标志来改变。

-D

禁止指定堆的调用时验证(validate-on-call)。

-E

启用指定堆的调用时验证(validate-on-call)。

-d

禁用指定堆的堆检查(heap checking)。

-e

启用指定堆的堆检查(heap checking)。

BreakAddress

指定要设置或删除断点的块的地址。

-b

使得调试器在堆管理器中设置条件断点。-b 后可跟allocrealloc或者 free,用于指定断点是否在分配、重新分配或者释放内存时激活。如果BreakAddress 用来指定块的地址,可以省略断点类型。如果Heap用来指定堆地址或者堆序号,则必须包含类型和Tag参数。

Tag

指定堆中的标签名。

-B

使得调试器在堆管理器中移除一个条件断点。必须指定断点类型(allocreallocfree),并且必须和-b 选项使用的一样。

-l

(Windows XP和之后) 使得调试器检查泄露的堆块。

-s

(Windows XP和之后) 指定需要摘要信息。如果省略SummaryOptions StatHeapAddress,则当前进程关联的所有堆的摘要信息都会显示出来。

SummaryOptions

(Windows XP 和之后) 可以是任意下面这些选项。SummaryOptions 不区分大小写。

选项

作用

-v

验证所有数据块。

-b BucketSize

指定存储单元(bucket)的大小。默认值为1024 bit。

-d DumpBlockSize

指定存储单元大小。

-a

 

-c

指示每个块得内容都应该显示出来。

StatHeapAddress

(Windows XP和之后) 指定堆的地址。如果为0或者省略,则显示当前进程关联的所有堆。

-i Heap

(Windows XP 和之后) 显示指定的Heap 的信息。

-x [-v]

(Windows XP 和之后) 使得调试器搜索包含指定地址的堆块。如果添加了-v ,命令会在当前进程的整个虚拟内存空间中搜索指向该堆块的指针。

Address

(Windows XP 和之后) 指定要搜索的地址。

-p

(Windows 2000 和之后) 指示需要页堆(page heap)信息。如果没有和任何PageHeapOptions 一起使用,则所有页堆都会显示出来。

PageHeapOptions

可以是下面这些选项中的单个。PageHeapOptions 区分大小写。如果不指定选项,所有可能的页堆句柄都会显示出来。

选项

作用

-h Handle

使得调试器显示句柄为Handle的页堆的详细信息。

-a Address

使得调试器查找块中包含Address的页堆。会包含该地址和完整的页堆块的关系的详细信息,如是否该地址是页堆的一部分、它在块中的偏移,以及这个块已经被分配还是空闲的。在可能时还会包含堆栈回溯。使用该选项时,显示的大小是堆分配粒度的倍数。

-t[c|s] [Traces]

使得调试器显示大量使用堆的用户(heavy heap users)的纪录(collected traces)。Traces指定要显示的纪录数量,默认值为4。如果有比指定的数量更多的纪录,则显示前面的部分纪录。如果使用-t 或者-tc ,则纪录以使用记数(count usage)排序。如果使用-ts ,则纪录以大小排序。 (-tc-ts 选项仅在Windows XP中支持,-t选项在Windows XP和之前的版本中都支持。)

-fi [Traces]

(Windows XP 和之后) 使得调试器显示最近的故障注入纪录(fault injection traces)。 Traces 指定要显示的熟练,默认值为4。

-all

(Windows XP和之后) 使得调试器显示所有页堆的详细信息。

-?

使得调试器显示页堆帮助(page heap help),包括堆块的图表。(这些图表在下面的注释节中可以看到。)

使用任何!heap -p 扩展命令之前,目标进程中必须已经启用了页堆。查看后面注释节中的详细说明。

-srch

(Windows XP 和之后) 在所有堆中进行查找。

Pattern

(Windows XP 和之后) 要查找的内容。

Size

(Windows XP 和之后) 可以是下面选项中的任意一个。用于指定pattern 的大小。必须使用'-'。

选项

作用

-b

pattern的大小是一个BYTE。

-w

pattern的大小是一个WORD。

-d

pattern的大小是一个DWORD。

-q

pattern的大小是一个QWORD。

如果不指定上面任何一个,则会假定pattern 的大小和机器的指针大小一致。

-flt

(Windows XP和之后) 将显示出来的堆限制为指定大小或大小范围的。

FilterOptions

(Windows XP 和之后) 可以是下面选项之一。FilterOptions 区分大小写。

选项

作用

s Size

限制显示出来的堆必须是指定的大小。

r SizeMin SizeMax

限制显示出来的堆大小在指定范围内。

-stat

(Windows XP和之后) 显示指定的堆的使用统计。

-h Handle

(Windows XP 和之后) 只有句柄为Handle的堆的使用统计会显示出来。如果Handle为0或者省略,则所有堆的使用统计都会显示。

-grp GroupBy

(Windows XP 和之后) 按照GroupBy 的指定重新排序显示。GroupBy 选项可以是下表中的值。

选项

作用

A

根据分配大小显示使用统计。

B

根据块数量显示使用统计。

S

根据每次分配的总大小显示使用统计。

MaxDisplay

(Windows XP和之后) 限制输出最多为MaxDisplay 行。

-?

在调试器命令窗口中显示该命令的简要帮助文本。使用!heap -? 查看常规帮助,!heap -p -? 查看页堆帮助。 (页堆帮助只在Windows 2000和之后的系统中可用。)

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

注释

该扩展命令可以用来实现几种任务。

标准的!heap 命令用来显示当前进程的堆信息。(仅针对用户模式进程。!pool 扩展命令用于系统进程。)

!heap -b!heap -B 命令用于在堆管理器中创建或者删除条件断点。

!heap -l 命令检查泄露的堆块。它使用一种垃圾回收算法(garbage collector algorithm)来检测没有被进程地址空间中任何地方引用到的已占用块(busy blocks)。对很大的程序,可能需要花费数分钟才能完成。该命令只在Windows XP和之后版本中可以使用。

!heap -x 命令搜索包含给定地址的堆块。如果使用了-v 选项,该命令还会搜索当前进程的整个虚拟地址空间,以获得指向该堆块的指针。这个命令仅在Windows XP和之后版本中可以使用。

!heap -p 命令显示各种形式的页堆(page heap)信息。仅在Windows 2000(Service Pack 1或之后)、Windows XP、以及之后版本的Windows中可用。如果在调试Windows NT 4.0,则需要使用!dphdump!dphfind!dphflags!dphhogs来替代。

使用!heap –p之前,必须启用目标进程的页堆(page heap)。这可以通过全局标志 (gflags.exe) 实用工具实现。打开该工具,在Image File Name 文本框中填入目标进程的名字,选择Image File Options 以及Enable page heap ,然后点击Apply 。也可以从命令提示符窗口输入gflags /i xxx.exe +hpa 来运行全局标志工具,xxx.exe 是目标程序的名字。

注意在NT 4.0中,只有在调试器已经附加或者进程启动时全局标志已经进行过了适当的设置时,页堆命令才能正确工作。

!heap -p -t[c|s] 命令在Windows XP之后就不支持了。可以使用调试器工具包中的UMDH工具来获得类似的结果。

!heap -srch 命令显示包含指定模板的堆条目(heap entries)。该命令仅在Windows XP和之后版本中可以使用。

!heap -flt 命令限制只显示分配大小为指定值的堆。该命令仅在Windows XP和之后版本中可用。

!heap -stat 命令显示堆使用统计。该命令仅在Windows XP和之后版本可用。

这里是一个标准的!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、以及之后的系统中的形式。

Light page heap 块 — 已分配:

 +-----+---------------+---+                                  
 |     |               |   |                                  
 +-----+---------------+---+                                  
    ^         ^          ^                                    
    |         |          8 
字节后缀  ( 0xA0 填充 )    
    |         
用户分配 (User allocation) ( 如果没有要求清 0 ,则填充为  E0 ) 
    
块首  (  0xABCDAAAA  开头, 0xDCBAAAAA 结尾

Light page heap 块 已释放:

 +-----+---------------+---+                                  
 |     |               |   |                                  
 +-----+---------------+---+                                  
    ^         ^          ^                                    
    |         |          8 
字节后缀  ( 0xA0 填充 )    
    |         
用户分配  ( 如果没有要求清 0 ,则填充为  E0)          
    
块首  (  0xABCDAAA9  开头, 0xDCBAAA9 结尾

Full page heap 块 — 已分配:

 +-----+---------+---+-------                                 
 |     |         |   |  ... N/A page                          
 +-----+---------+---+-------                                 
    ^       ^      ^                                          
    |       |      0-7 
字节后缀  (  0xD0 填充 )        
    |       
用户分配  ( 如果未要求清 0 Windows 2000 中填充为 E0 ,   
            Windows XP
中填充为 C0 )       
    
块首  (  0xABCDBBBB  开头, 0xDCBABBBB 结尾

Full page heap 块 —已释放:

 +-----+---------+---+-------                                 
 |     |         |   |  ... N/A page                          
 +-----+---------+---+-------                                 
    ^       ^      ^                                          
    |       |      0-7 
字节后缀  (  0xD0 填充 )        
    |       
用户分配  (  F0  填充 )            
    
块首  (  0xABCDBBA  开头, 0xDCBABBBA 结尾

要查看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 块位于包含用户分配内存的页面的开头或者前一个页面的开头。

附加信息

关于堆的更多信息,查看Microsoft Windows SDK 文档、Windows Driver Kit (WDK)文档、以及Mark Russinovich和David Solomon编写的Microsoft Windows Internal


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理