cc682/NetRoc
http://netroc682.spaces.live.com/
!processfields 扩展命令显示执行进程块(EPROCESS)中字段的名字和偏移。
!processfields
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
不可用(查看注释) |
该扩展命令在Windows XP和之后的系统中都不可用。可以直接使用 dt (Display Type) 命令显示EPROCESS结构:
kd> dt nt!_EPROCESS
下面是!processfields 在Windows 2000系统中的示例:
kd> !processfields
EPROCESS structure offsets:
Pcb: 0x0
ExitStatus: 0x6c
LockEvent: 0x70
LockCount: 0x80
CreateTime: 0x88
ExitTime: 0x90
LockOwner: 0x98
UniqueProcessId: 0x9c
ActiveProcessLinks: 0xa0
QuotaPeakPoolUsage[0]: 0xa8
QuotaPoolUsage[0]: 0xb0
PagefileUsage: 0xb8
CommitCharge: 0xbc
PeakPagefileUsage: 0xc0
PeakVirtualSize: 0xc4
VirtualSize: 0xc8
Vm: 0xd0
DebugPort: 0x120
ExceptionPort: 0x124
ObjectTable: 0x128
Token: 0x12c
WorkingSetLock: 0x130
WorkingSetPage: 0x150
ProcessOutswapEnabled: 0x154
ProcessOutswapped: 0x155
AddressSpaceInitialized: 0x156
AddressSpaceDeleted: 0x157
AddressCreationLock: 0x158
ForkInProgress: 0x17c
VmOperation: 0x180
VmOperationEvent: 0x184
PageDirectoryPte: 0x1f0
LastFaultCount: 0x18c
VadRoot: 0x194
VadHint: 0x198
CloneRoot: 0x19c
NumberOfPrivatePages: 0x1a0
NumberOfLockedPages: 0x1a4
ForkWasSuccessful: 0x182
ExitProcessCalled: 0x1aa
CreateProcessReported: 0x1ab
SectionHandle: 0x1ac
Peb: 0x1b0
SectionBaseAddress: 0x1b4
QuotaBlock: 0x1b8
LastThreadExitStatus: 0x1bc
WorkingSetWatch: 0x1c0
InheritedFromUniqueProcessId: 0x1c8
GrantedAccess: 0x1cc
DefaultHardErrorProcessing 0x1d0
LdtInformation: 0x1d4
VadFreeHint: 0x1d8
VdmObjects: 0x1dc
DeviceMap: 0x1e0
ImageFileName[0]: 0x1fc
VmTrimFaultValue: 0x20c
Win32Process: 0x214
Win32WindowStation: 0x1c4
关于EPROCESS块的信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!psp 扩展用于显示指定地址处的处理器状态参数寄存器(processor state parameter (PSP) register)。
该命令仅在Itanium目标机上支持。
!psp Address [DisplayLevel]
Address
指定要显示的PSP寄存器的16进制地址。
DisplayLevel
可以是下面这些选项中任意一个:
0
仅显示PSP字段的值。这是默认情况。
1
显示非保留和非忽略的PSP字段的详细信息。
2
显示所有PSP字段的详细信息,包括被忽略或保留的那些。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
!pte 扩展显示指定地址的页表项(page table entry (PTE))和页目录项(page directory entry (PDE))。
Windows NT 4.0 和Windows 2000的语法
!pte VirtualAddress
!pte PTE
!pte LiteralAddress 1
!pte StartAddress EndAddress
Windows XP和之后的语法
!pte VirtualAddress
!pte PTE
!pte LiteralAddress 1
VirtualAddress
指定需要查看页表的虚拟地址。
PTE
指定实际的PTE的地址。
LiteralAddress 1
指定实际的PTE或PDE的地址。
StartAddress
(仅x86 或x64 目标机;仅 Windows NT 4.0 和Windows 2000) 指定某个范围的开始的虚拟地址。该范围内的所有页表都会被显示出来。
EndAddress
(仅x86 或x64 目标机; 仅Windows NT 4.0 和Windows 2000) 指定某个范围的结束的虚拟地址。该范围内的所有页表都会被显示出来。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
如果指定了一个参数,并且该参数是一个用于保存页表的内存区域中的地址,那么调试器将它当作一个PTE参数。该参数被当作要查看的PTE的实际地址,调试器会显示该PTE以及相应的PDE。
如果指定的参数不在这个范围内,调试器把它当作VirtualAddress。会显示用于映射这个地址的PTE和PDE。
如果指定了两个参数,并且第二个参数是1 (或者更小的数字),调试器将第一个参数当作LiteralAddress。这个地址会被当作PTE或者PDE的实际地址,并且显示相应的数据(可能是错误的)。
(仅x86 或x64目标机) 如果提供了两个参数,并且第二个参数比第一个大,调试器将它们当作StartAddress 和EndAddress。命令会显示指定的内存范围中每个页面的PTE。
使用!sysptes扩展命令查看所有系统PTE的列表。
下面是x86目标机上的示例:
kd> !pte 801544f4
801544F4 - PDE at C0300800 PTE at C0200550
contains 0003B163 contains 00154121
pfn 3b G-DA--KWV pfn 154 G--A--KRV
输出的第一行会再次显示被查看的虚拟地址。然后是包含该地址内存映射(virtual-physical mapping)信息的PDE和PTE的虚拟地址。
第二行是PDE和PTE的实际内容。
第三行是对这些内容的分析,将它们分解成页面帧序号(PFN)和状态位(status bits)。
查看 !pfn扩展命令或者 将虚拟地址转换成物理地址小节来获得如何理解和使用PFN的信息。
在x86和x64目标机上,PDE和PTE的状态位在下表中列出。!pte 的显示会用大写字母或者虚线来表示这些位,并且还添加其他信息。
位 |
设置时的显示 |
清除时的显示 |
意义 |
0x200 |
C |
- |
写时复制(Copy on write) |
0x100 |
G |
- |
全局页面(Global) |
0x80 |
L |
- |
大页面(Large page)。只有PDE有,PTE中没有。 |
0x40 |
D |
- |
脏页面(Dirty) |
0x20 |
A |
- |
已访问(Accessed) |
0x10 |
N |
- |
禁止缓存(Cache disabled) |
0x8 |
T |
- |
通写(Write-through) |
0x4 |
U |
K |
所有者(用户模式或内核模式)。 |
0x2 |
W |
R |
可写或者只读。只有在多处理器计算机和任何运行Windows Vista和之后系统的机器上有。 |
0x1 |
V |
有效位(Valid) |
|
E |
- |
可执行页面。对于包括很多x86系统在内的不支持硬件执行/非执行标志位的平台,总是显示E。 |
在Itanium目标机上,PDE和PTE的状态位和PPE中有少许不同。Itanium PPE位有下面这些:
设置时的显示 |
清除时的显示 |
意义 |
V |
有效位(Valid) |
|
U |
K |
所有者(用户模式或内核模式)。 |
D |
- |
脏页面(Dirty) |
A |
- |
已访问(Accessed) |
W |
R |
可写或者只读。只有在多处理器计算机和任何运行Windows Vista和之后系统的机器上有。 |
E |
- |
执行(Execute) |
C |
- |
写时复制(Copy on write) |
关于页表、页目录和这些状态位的说明,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!pte2va 扩展命令显示指定的页表项(PTE)对应的虚拟地址。
!pte2va Address
Address
指定PTE。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
要查看指定的PTE的内容,使用!pte命令。
下面是!pte2va 扩展的输出示例:
kd> !pte2va 9230
000800000248c000
关于页表和PTE的信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!ptov扩展显示给定进程的整个物理地址到虚拟地址的映射(physical-to-virtual map)。
!ptov PFN
PFN
指定进程的页目录基址(directory base)的页面帧序号(PFN)。这和去掉最后三个16进制数字的页目录基地址相同 (即右移12位)。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
下面是一个示例。首先使用!process扩展来获得需要的进程的页目录基址:
kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
....
PROCESS ff779190 SessionId: 0 Cid: 04fc Peb: 7ffdf000 ParentCid: 0394
DirBase: 098fd000 ObjectTable: e1646b30 TableSize: 8.
Image: MyApp.exe
这里的页目录基址是0x098FD000。去掉末尾的三个0,结果为0x098FD。这就是页目录基址的页面帧序号(PFN)。
将这个数字传递给!ptov:
kd> !ptov 98fd
7119000 10000
a21a000 20000
6133000 12e000
9de9000 12f000
2b0c000 130000
87cd000 131000
aaf6000 140000
... ...
左边一列的数字是映射到该进程的每个内存页面的物理地址。右边一列是它们映射到的虚拟地址。
全部的输出会非常长。
相关主题,查看!vtop、 !vpdd、以及 将虚拟地址转换成物理地址。关于页表和页目录的信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
cc682/NetRoc
http://netroc682.spaces.live.com/
!poolfind 扩展命令在非分页和分页内存中查找指定的pool tag。
Windows NT 4.0中的语法
!poolfind TagString [PoolType]
Windows 2000和之后
!poolfind TagString [PoolType]
!poolfind TagValue [PoolType]
TagString
指定pool tag。TagString 是区分大小写的ASCII字符串。星号(*)可以用来表示任意数量的字符,问号 (?)可以用来代表一个字符。如果没有使用星号, TagString 必须刚好是4个字符长度。
TagValue
(Windows 2000和之后) 指定pool tag。TagValue 必须以"0x"开头,即使默认的基数为16。如果该参数以任何其他值开头(包括"0X"),则会被解释为ASCII的标签字符串。
PoolType
指定要搜索的池类型。允许下面这些值:
0
指定非分页内存池。这是默认值。
1
指定分页内存池。
2
指定特殊池(special pool)。
4
(Windows XP和之后) 指定会话池(session pool)。
4, 5, 6
(仅Windows NT 4.0) 和0、1、2一样,但是显示详细信息。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
该命令根据需要搜索的池内存大小的不同,需要很长时间来执行。要加快速度,可以通过CTRL+A (Toggle Baud Rate) 键增加COM端口,或者使用.cache (Set Cache Size) 命令增加缓存大小 (设置到大约10 MB)。
Pool tag和传递给ExAllocateXxx 类例程的标签一样。
下面是一个示例。搜索整个非分页内存池之后搜索分页池,但是命令在完成之前被终止(长时间操作之后):
kd> !poolfind SeSd 0
Scanning large pool allocation table for Tag: SeSd (827d1000 : 827e9000)
Searching NonPaged pool (823b1000 : 82800000) for Tag: SeSd
826fa130 size: c0 previous size: 40 (Allocated) SeSd
82712000 size: c0 previous size: 0 (Allocated) SeSd
82715940 size: a0 previous size: 60 (Allocated) SeSd
8271da30 size: c0 previous size: 10 (Allocated) SeSd
82721c00 size: 10 previous size: 30 (Free) SeSd
8272b3f0 size: 60 previous size: 30 (Allocated) SeSd
8272d770 size: 60 previous size: 40 (Allocated) SeSd
8272d7d0 size: a0 previous size: 60 (Allocated) SeSd
8272d960 size: a0 previous size: 70 (Allocated) SeSd
82736f30 size: a0 previous size: 10 (Allocated) SeSd
82763840 size: a0 previous size: 10 (Allocated) SeSd
8278b730 size: 100 previous size: 290 (Allocated) SeSd
8278b830 size: 10 previous size: 100 (Free) SeSd
82790130 size: a0 previous size: 20 (Allocated) SeSd
82799180 size: a0 previous size: 10 (Allocated) SeSd
827c00e0 size: a0 previous size: 30 (Allocated) SeSd
827c8320 size: a0 previous size: 60 (Allocated) SeSd
827ca180 size: a0 previous size: 50 (Allocated) SeSd
827ec140 size: a0 previous size: 10 (Allocated) SeSd
Searching NonPaged pool (fe7c3000 : ffbe0000) for Tag: SeSd
kd> !poolfind SeSd 1
Scanning large pool allocation table for Tag: SeSd (827d1000 : 827e9000)
Searching Paged pool (e1000000 : e4400000) for Tag: SeSd
e10000b0 size: d0 previous size: 20 (Allocated) SeSd
e1000260 size: d0 previous size: 60 (Allocated) SeSd
......
e1221dc0 size: a0 previous size: 60 (Allocated) SeSd
e1224250 size: a0 previous size: 30 (Allocated) SeSd
...terminating - searched pool to e1224000
kd>
关于内存池和pool tag的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!poolused 扩展用于根据每个内存池分配的标签(tag)的使用来显示内存使用摘要。
Windows NT 4.0的语法:
!poolused [Flags]
Windows 2000和之后的语法:
!poolused [Flags [TagString]]
Flags
指定要显示的内容和输出排序的方式。可以是下面这些位值的任意组合,但是bit 1 (0x2) 和 2 (0x4)不能一起使用。默认值为0,仅输出摘要信息,以pool tag排序。
Bit 0 (0x1)
显示详细信息。
Bit 1 (0x2)
以非分页内存使用的总数来排序。
Bit 2 (0x4)
以使用分页内存的总数来排序。
Bit 3 (0x8)
(Windows Server 2003和之后) 显示session pool而不是standard pool。
TagString
(Windows 2000和之后) 指定pool tag。TagString是区分大小写的ASCII字符串。星号 (*) 可用来代表任意数量的字符,问号 (?) 可以用来代表一个字符。如果没有使用星号,TagString 必须刚好是4个字符的长度。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
!poolused 扩展利用Windows的内存池标签(Pool tagging)功能来搜集数据。Pool tagging在Windows Server 2003和之后版本的Windows中一直是起用的。在Windows XP和之前版本中必须使用Gflags来启用。
如果在该扩展命令执行完成前停止它,调试器中会显示出部分结果。
该命令会显示每种标签的paged pool和nonpaged pool内存使用。两种情况下,显示中都包含当前使用给定tag分配的次数,以及分配的这些存储单元使用的字节数量。
下面是命令输出的一部分的示例:
0: kd> !poolused
Sorting by Tag
Pool Used:
NonPaged Paged
Tag Allocs Used Allocs Used
1394 1 520 0 0UNKNOWN pooltag '1394', please update pooltag.txt
1MEM 1 3368 0 0UNKNOWN pooltag '1MEM', please update pooltag.txt
2MEM 1 3944 0 0UNKNOWN pooltag '2MEM', please update pooltag.txt
3MEM 3 248 0 0UNKNOWN pooltag '3MEM', please update pooltag.txt
8042 4 3944 0 0PS/2 kb and mouse , Binary: i8042prt.sys
AGP 1 344 2 384UNKNOWN pooltag 'AGP ', please update pooltag.txt
AcdN 2 1072 0 0TDI AcdObjectInfoG
AcpA 3 192 1 504ACPI Pooltags , Binary: acpi.sys
AcpB 0 0 4 576ACPI Pooltags , Binary: acpi.sys
AcpD 40 13280 0 0ACPI Pooltags , Binary: acpi.sys
AcpF 6 240 0 0ACPI Pooltags , Binary: acpi.sys
AcpM 0 0 1 128ACPI Pooltags , Binary: acpi.sys
AcpO 4 208 0 0ACPI Pooltags , Binary: acpi.sys
...
WmiG 30 6960 0 0Allocation of WMIGUID
WmiR 63 4032 0 0Wmi Registration info blocks
Wmip 146 3504 182 18600Wmi General purpose allocation
Wmit 1 4096 7 49480Wmi Trace
Wrpa 2 720 0 0WAN_ADAPTER_TAG
Wrpc 1 72 0 0WAN_CONN_TAG
Wrpi 1 120 0 0WAN_INTERFACE_TAG
Wrps 2 128 0 0WAN_STRING_TAG
aEoP 1 672 0 0UNKNOWN pooltag 'aEoP', please update pooltag.txt
fEoP 1 16 0 0UNKNOWN pooltag 'fEoP', please update pooltag.txt
hSVD 0 0 1 40Shared Heap Tag , Binary: mrxdav.sys
hibr 0 0 1 24576UNKNOWN pooltag 'hibr', please update pooltag.txt
iEoP 1 24 0 0UNKNOWN pooltag 'iEoP', please update pooltag.txt
idle 2 208 0 0Power Manager idle handler
jEoP 1 24 0 0UNKNOWN pooltag 'jEoP', please update pooltag.txt
mEoP 1 88 0 0UNKNOWN pooltag 'mEoP', please update pooltag.txt
ohci 1 136 0 01394 OHCI host controller driver
rx.. 3 1248 0 0UNKNOWN pooltag ' rx', please update pooltag.txt
sidg 2 48 0 0GDI spooler events
thdd 0 0 1 20480DirectDraw/3D handle manager table
usbp 18 77056 2 96UNKNOWN pooltag 'usbp', please update pooltag.txt
vPrt 0 0 18 68160UNKNOWN pooltag 'vPrt', please update pooltag.txt
TOTAL 3570214 209120008 38769 13066104
关于内存池和内存池标签的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!poolval 扩展命令分析pool page 的头部并诊断任何可能的错误。该命令仅在Windows XP和之后版本中可用。
!poolval Address [DisplayLevel]
Address
指定要分析头部的pool的地址。
DisplayLevel
指定输出中要包含的信息。可以是任意的下面这些值(默认为0):
0
显示基本信息。
1
显示基本信息和头部链表(linked header lists)。
2
显示基本信息、头部链表和基本的头信息。
3
显示基本信息、头部链表,以及完整的头信息。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
关于内存池的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!popolicy 扩展显示目标机的电源策略。
!popolicy [Address]
Address
指定要显示的电源策略结构的地址。如果省略,则显示nt!PopPolicy。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
下面是命令输出的示例:
kd> !popolicy
SYSTEM_POWER_POLICY (R.1) @ 0x80164d58
PowerButton: Shutdown Flags: 00000003 Event: 00000000 Query UI
SleepButton: None Flags: 00000003 Event: 00000000 Query UI
LidClose: None Flags: 00000001 Event: 00000000 Query
Idle: None Flags: 00000001 Event: 00000000 Query
OverThrottled: None Flags: c0000004 Event: 00000000 Override NoWakes Critical
IdleTimeout: 0 IdleSensitivity: 50%
MinSleep: S0 MaxSleep: S0
LidOpenWake: S0 FastSleep: S0
WinLogonFlags: 1 S4Timeout: 0
VideoTimeout: 0 VideoDim: 209
SpinTimeout: 0 OptForPower: 1
FanTolerance: 0% ForcedThrottle: 0%
MinThrottle: 0%
使用!pocaps 扩展命令查看系统的电源能力(power cababilities)。关于电源能力和电源策略(power policy)的信息,查看Windows Driver Kit (WDK)文档,以及Mark Russinovich and David Solomon 编写的Microsoft Windows Internals。
!prcb 扩展命令显示处理器控制块(processor control block (PRCB))。
!prcb [Processor]
Processor
指定要获得PRCB信息的处理器。如果省略Processor,则使用处理器0。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
PRCB是处理器控制域(PCR)的一个扩展。使用!pcr 命令来显示PCR。
下面是示例:
kd> !prcb
PRCB for Processor 0 at e0000000818ba000:
Threads-- Current e0000000818bbe10 Next 0000000000000000 Idle e0000000818bbe10
Number 0 SetMember 00000001
Interrupt Count -- 0000b81f
Times -- Dpc 00000028 Interrupt 000003ff
Kernel 00005ef4 User 00000385
关于PCR和PRCB的信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!process 扩展显示指定的进程或所有进程的信息,包括EPROCESS块在内。
该命令只能在内核模式调试时使用。
Windows NT 4.0的语法:
!process [Process [Flags]]
Windows 2000的语法:
!process [/s Session] [Process [Flags]]
!process [/s Session] 0 Flags ImageName
Windows XP和之后的语法:
!process [/s Session] [/m Module] [Process [Flags]]
!process [/s Session] [/m Module] 0 Flags ImageName
/s Session
(Windows 2000和之后) 指定拥有给定进程的会话(session)。
/m Module
(Windows XP和之后) 指定拥有需要的进程的模块。
Process
指定目标机上某个进程的16进制地址或者进程ID。
Process 的值决定了!process 命令显示的是进程地址还是进程ID。如果在Windows NT 4.0中Process 为-1 ,或在其他任何系统中省略掉,调试器只显示当前系统进程的数据。如果Process 为0 并且省略ImageName,调试器显示所有活动进程的信息。
Flags
指定显示内容的级别。Flags 可以是下面这些位的任意组合。如果Flags为0,只会显示很少的信息。默认值根据Windows版本和Process的值会有所不同。在Windows NT 4.0中,当Process被省略或者设置为0时默认为0x3,否则默认值为0xF。在Windows 2000中,当Process省略,或者Process为0并且省略ImageFile时,默认值是0x3;否则默认值为0xF。在Windows XP和之后,当Process省略或者为0或-1时,默认值为0x3,否则为0xF。
Bit 0 (0x1)
显示时间和优先级统计。
Bit 1 (0x2)
显示该进程关联的线程和事件列表,以及它们的等待状态。
Bit 2 (0x4)
显示进程关联的线程列表。如果没有同时指定Bit 1(0x2),则每个线程显示在单独一行上。如果同时指定了Bit 1,则每个线程还会显示堆栈回溯。
Bit 3 (0x8)
(Windows XP和之后) 显示每个函数的返回地址、堆栈指针,以及(在Itanium系统上)bsp寄存器的值。不显示函数的参数。
Bit 4 (0x10)
(Windows XP和之后) 在命令执行期间将进程上下文设定为指定的进程。这样会使得线程调用堆栈显示更加精确。因为该标志相当于对这个进程使用了.process /p /r,会丢弃(discard)任何存在的用户模式模块列表。当Process 为0时,调试器显示所有进程,并且显示每一个时都会切换进程上下文。如果只显示单个进程,并且它的用户模式状态已经被刷新(例如,使用了.process /p /r),那么就不需要使用这个标志。该标志仅在使用了 Bit 0(0x1)的时候起效。
ImageName
(Windows 2000和之后) 指定要显示的进程的名字。调试器会显示所有可执行映像名和ImageName 匹配的进程。映像名必须匹配EPROCESS 块中的那个。一般来说,这是启动了该进程的可执行文件的名字,包含扩展名(一般是.exe),并且第15个字符之后的字符被裁减掉。不能指定包含空格的映像名。指定了ImageName 时,Process 必须为0。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
下面是!process 0 0的显示的示例:
kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 80a02a60 Cid: 0002 Peb: 00000000 ParentCid: 0000
DirBase: 00006e05 ObjectTable: 80a03788 TableSize: 150.
Image: System
PROCESS 80986f40 Cid: 0012 Peb: 7ffde000 ParentCid: 0002
DirBase: 000bd605 ObjectTable: 8098fce8 TableSize: 38.
Image: smss.exe
PROCESS 80958020 Cid: 001a Peb: 7ffde000 ParentCid: 0012
DirBase: 0008b205 ObjectTable: 809782a8 TableSize: 150.
Image: csrss.exe
PROCESS 80955040 Cid: 0020 Peb: 7ffde000 ParentCid: 0012
DirBase: 00112005 ObjectTable: 80955ce8 TableSize: 54.
Image: winlogon.exe
PROCESS 8094fce0 Cid: 0026 Peb: 7ffde000 ParentCid: 0020
DirBase: 00055005 ObjectTable: 80950cc8 TableSize: 222.
Image: services.exe
PROCESS 8094c020 Cid: 0029 Peb: 7ffde000 ParentCid: 0020
DirBase: 000c4605 ObjectTable: 80990fe8 TableSize: 110.
Image: lsass.exe
PROCESS 809258e0 Cid: 0044 Peb: 7ffde000 ParentCid: 0026
DirBase: 001e5405 ObjectTable: 80925c68 TableSize: 70.
Image: SPOOLSS.EXE
这个表格是!process 0 0输出中出现的各个部分的说明。
成员 |
含义 |
Process address |
单词PROCESS 之后的8字符长度的16进制数字是EPROCESS块的地址。上面例子中最后一条的进程地址为0x809258E0。 |
Process ID (PID) |
Cid 后的16进制数字。上面例子中最后一条的PID是0x44,或者10进制的68。 |
Process Environment Block (PEB) |
Peb 后面的16进制数字是进程环境块的地址 。上面例中最后一条的PEB位于0x7FFDE000。 |
Parent process PID |
ParentCid 后面的16进制数字是父进程的PID。上面例中最后一条的父进程PID为0x26,或者10进制的38。 |
Image |
拥有该进程的模块名。上例中最后一条的所有者为spoolss.exe。第一条的所有者为操作系统本身。 |
Process object address |
ObjectTable 后的16进制数字。上例最后一条中,进程对象(process object)地址为0x80925c68。 |
要显示某个进程的完整信息,可以将Flags设置为7。可以将Process 设置为进程地址、进程ID,或者将ImageName设置为可执行映像的名字来指定进程。例如:
kd> !process fb667a00 7
PROCESS fb667a00 Cid: 0002 Peb: 00000000 ParentCid: 0000
DirBase: 00030000 ObjectTable: e1000f88 TableSize: 112.
Image: System
VadRoot fb666388 Clone 0 Private 4. Modified 9850. Locked 0.
FB667BBC MutantState Signalled OwningThread 0
Token e10008f0
ElapsedTime 15:06:36.0338
UserTime 0:00:00.0000
KernelTime 0:00:54.0818
QuotaPoolUsage[PagedPool] 1480
Working Set Sizes (now,min,max) (3, 50, 345)
PeakWorkingSetSize 118
VirtualSize 1 Mb
PeakVirtualSize 1 Mb
PageFaultCount 992
MemoryPriority BACKGROUND
BasePriority 8
CommitCharge 8
THREAD fb667780 Cid 2.1 Teb: 00000000 Win32Thread: 80144900 WAIT: (WrFreePage) KernelMode Non-Alertable
80144fc0 SynchronizationEvent
Not impersonating
Owning Process fb667a00
WaitTime (seconds) 32278
Context Switch Count 787
UserTime 0:00:00.0000
KernelTime 0:00:21.0821
Start Address Phase1Initialization (0x801aab44)
Initial Sp fb26f000 Current Sp fb26ed00
Priority 0 BasePriority 0 PriorityDecrement 0 DecrementCount 0
ChildEBP RetAddr Args to Child
fb26ed18 80118efc c0502000 804044b0 00000000 KiSwapThread+0xb5
fb26ed3c 801289d9 80144fc0 00000008 00000000 KeWaitForSingleObject+0x1c2
注意输出中的进程对象的地址可以用于类似!handle这样的其他扩展命令,用于获得更多信息。
下面表格用于说明前面例子中的各个部分。
成员 |
含义 |
WAIT |
这个头后面附加的注释说明了等待原因。使用命令dt nt!_KWAIT_REASON 可以显示所有等待原因的列表。 |
ElapsedTime |
列出从进程创建以来经过了多长时间。显示是以Hours : Minutes : Seconds . Milliseconds格式的。 |
UserTime |
显示进程在用户模式下执行的时间。如果UserTime 特别高,可能说明了这个进程正在消耗系统资源。显示格式和ElapsedTime 一样。 |
KernelTime |
显示进程在内核模式下运行的时间。如果KernelTime 的值非常高,可能意味着该进程在消耗系统资源。显示格式和ElapsedTime一样。 |
Working Set sizes |
显示进程当前的最小和最大工作集(working set)大小,以页面数为单位。如果工作集异常的大,说明进程可能存在内存泄露,或者消耗了很多系统资源。 |
QuotaPoolUsage entries |
列出进程使用的分页和非分页内存池。对存在内存泄露的系统,查看所有进程额外的非分页内存使用可以知道哪个进程存在内存泄露。 |
Clone |
指示进程是否是由POSIX 或Interix字系统创建的。 |
Private |
指示进程当前使用到的私有(非共享)页面数量。包括物理内存中的和已经换出的内存。 |
除了进程信息之外,线程信息中还包含被线程锁定的资源列表。这个信息位于线程信息的第三行。上面例子中,线程锁定了一个位于80144fc0处的SynchronizationEvent 资源。通过将该地址和!kdext*.locks扩展命令显示的锁的列表对比,可以知道哪个进程拥有资源的排它锁(exclusive lock)。
!stacks 扩展给出每个线程的状态的简单摘要。它可以代替!process 用于对系统进行快速的查看,特别是调试像资源争用或者死锁这样的多线程问题时。
关于内核模式下进程的信息,查看改变上下文。关于对进程和线程进行分析的信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
cc682/NetRoc
http://netroc682.spaces.live.com/
!pars 扩展显示指定的processor application registers file。
!pars Address
Address
指定processor application registers file的地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该命令只能对Itanium目标机使用。
!pat 显示目标处理器的页面属性表寄存器(Page Attribute Table (PAT) registers)。
!pat Flag
!pat
Flag
如果设置Flag,调试器在显示PAT之前会先验证PAT功能是否存在。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
该扩展只能对x86目标机使用。
!pci 扩展命令用来显示PCI(peripheral component interconnect)总线的当前状态,以及附加到该总线上的任何设备。
!pci [Flags [Bus [Device [Function [MinAddress MaxAddress]]]]]
Flags
指定输出级别。可以是下面这些位的任意组合:
Bit 0 (0x1)
显示详细输出。
Bit 1 (0x2)
显示从bus 0到指定的Bus范围内的所有总线。
Bit 2 (0x4)
显示中包含原始字节格式的信息。如果设置了MinAddress、MaxAddress,或者标志的位0x8,则该标志也自动被设置。
Bit 3 (0x8)
显示中包含原始DWORD格式的信息。
Bit 4 (0x10)
显示中包含无效设备的号码(invalid device number)。如果指定了Device,则跳过该标志。
Bit 5 (0x20)
显示中包含无效功能号(invalid function numbers)。
Bit 6 (0x40)
显示中包含capabilities。
Bit 7 (0x80)
显示Intel 8086设备相关信息(Intel 8086 device-specific information)。
Bit 8 (0x100)
显示PCI配置空间(PCI configuration space)。
Bus
指定要显示的总线。Bus 可以在0到0xFF范围之内。如果省略,则显示primary bus (bus 0)的信息。如果Flags包含bit 1 (0x2), Bus 用于指定要显示的最大一个总线号。
Device
指定设备的slot device number。如果省略,则显示所有设备的信息。
Function
指定设备的slot function number。如果省略,则显示所有的设备功能(device function)。
MinAddress
指定要显示的原始字节或者原始DWORD的首地址。必须在0到0xFF之间。
MaxAddress
指定要显示的原始字节或者原始DWORD的尾地址。必须在0到0xFF之间,并且不能比MinAddress 小。
Windows NT 4.0 |
Kext.dll |
Windows 2000 |
Kext.dll |
Windows XP和之后 |
Kdexts.dll |
该扩展命令只能对x86目标机使用。
使用!ecb、!ecd、或者 !ecw来编辑PCI配置空间(PCI configuration space)。
下面的例子显示了所有总线和它们的设备的列表。该命令需要较长时间来执行。调试器扫描目标系统的PCI总线时,在显示的信息底部可以看到移动的计数器:
kd> !pci 2 ff
PCI Bus 0
00:0 8086:1237.02 Cmd[0106:.mb..s] Sts[2280:.....] Device Host bridge
0d:0 8086:7000.01 Cmd[0007:imb...] Sts[0280:.....] Device ISA bridge
0d:1 8086:7010.00 Cmd[0005:i.b...] Sts[0280:.....] Device IDE controller
0e:0 1011:0021.02 Cmd[0107:imb..s] Sts[0280:.....] PciBridge 0->1-1 PCI-PCI bridge
10:0 102b:0519.01 Cmd[0083:im....] Sts[0280:.....] Device VGA compatible controller
PCI Bus 1
08:0 10b7:9050.00 Cmd[0107:imb..s] Sts[0200:.....] Device Ethernet
09:0 9004:8178.00 Cmd[0117:imb..s] Sts[0280:.....] Device SCSI controller
下面的例子显示primary bus 上设备的详细信息。每行开头的两位数字是设备号(device number),后面跟的一位数字是功能号(function number):
kd> !pci 1 0
PCI Bus 0
00:0 8086:1237.02 Cmd[0106:.mb..s] Sts[2280:.....] Device Host bridge
cf8:80000000 IntPin:0 IntLine:0 Rom:0 cis:0 cap:0
0d:0 8086:7000.01 Cmd[0007:imb...] Sts[0280:.....] Device ISA bridge
cf8:80006800 IntPin:0 IntLine:0 Rom:0 cis:0 cap:0
0d:1 8086:7010.00 Cmd[0005:i.b...] Sts[0280:.....] Device IDE controller
cf8:80006900 IntPin:0 IntLine:0 Rom:0 cis:0 cap:0
IO[4]:fff1
0e:0 1011:0021.02 Cmd[0107:imb..s] Sts[0280:.....] PciBridge 0->1-1 PCI-PCI bridge
cf8:80007000 IntPin:0 IntLine:0 Rom:0 cap:0 2sts:2280 BCtrl:6 ISA
IO:f000-ffff Mem:fc000000-fdffffff PMem:fff00000-fffff
10:0 102b:0519.01 Cmd[0083:im....] Sts[0280:.....] Device VGA compatible controller
cf8:80008000 IntPin:1 IntLine:9 Rom:80000000 cis:0 cap:0
MEM[0]:fe800000 MPF[1]:fe000008
下面的例子显示bus 0,设备0x0D,功能0x01的更详细一些的信息,包括从地址0x00到0x3F之间的原始DWORD值:
kd> !pci f 0 d 1 0 3f
PCI Bus 0
0d:1 8086:7010.00 Cmd[0005:i.b...] Sts[0280:.....] Device IDE controller
cf8:80006900 IntPin:0 IntLine:0 Rom:0 cis:0 cap:0
IO[4]:fff1
00000000: 70108086 02800005 01018000 00002000
00000010: 00000000 00000000 00000000 00000000
00000020: 0000fff1 00000000 00000000 00000000
00000030: 00000000 00000000 00000000 00000000
查看Plug and Play 调试获得该扩展命令的应用和更多示例。关于PCI总线的信息,查看Windows Driver Kit (WDK)文档。
!pciir 扩展显示从PCI设备到中断控制器输入(interrupt controller input)的硬件路由(hardware routing)的内容。
!pciir
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP |
Kdexts.dll |
Windows Vista和之后 |
不可用 |
该扩展命令只能在未启用ACPI(Advanced Configuration and Power Interface)的x86目标机上使用。
使用!acpiirqarb 扩展在启用ACPI的机器上查看类似信息。
关于PCI总线的信息,查看Windows Driver Kit (WDK)文档。
!pcitree 扩展显示PCI设备对象的信息,包括子PCI总线和CardBus总线,以及附加到他们上的设备。
!pcitree
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
下面是一个示例:
kd> !pcitree
Bus 0x0 (FDO Ext fe517338)
0600 12378086 (d=0, f=0) devext fe4f4ee8 Bridge/HOST to PCI
0601 70008086 (d=d, f=0) devext fe4f4ce8 Bridge/PCI to ISA
0101 70108086 (d=d, f=1) devext fe4f4ae8 Mass Storage Controller/IDE
0604 00211011 (d=e, f=0) devext fe4f4788 Bridge/PCI to PCI
Bus 0x1 (FDO Ext fe516998)
0200 905010b7 (d=8, f=0) devext fe515ee8 Network Controller/Ethernet
0100 81789004 (d=9, f=0) devext fe515ce8 Mass Storage Controller/SCSI
0300 0519102b (d=10, f=0) devext fe4f4428 Display Controller/VGA
Total PCI Root busses processed = 1
要根据最后的设备显示来理解输出的内容。它的base class 为03、subclass 为00、Device ID 为0x0519,、Vendor ID 为0x102B。这些值是设备本身固有的。
"d="后面的数字是设备号;"f="后的数字是功能号(function number)。"devext"后是设备扩展的地址: 0xFE4F4428。最后显示base class 名字和subclass名字。
要获得某个设备的更多信息,可以使用!devext 扩展命令,并且将设备扩展地址作为参数。对这类设备,命令应该像下面一样:
kd> !devext fe4f4428 pci
如果!pcitree 扩展产生一个错误,通常意味着PCI符号没有正确的加载。使用.reload pci.sys来修正这个问题。
查看Plug and Play调试来获得该扩展命令的应用。关于PCI总线和PCI设备对象的信息,查看 Windows Driver Kit (WDK)文档。
!pcm 扩展显示指定的private cache map。该扩展仅在Windows 2000中可用。
!pcm Address
Address
指定private cache map的地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
不可用(查看注释节) |
该扩展仅在Windwos 2000中支持。在Windows XP和之后的Windows中,可以使用dt nt!_PRIVATE_CACHE_MAP Address命令。
关于缓存管理的信息,查看Microsoft Windows SDK 文档,以及Mark Russinovich 和David Solomon编写的Microsoft Windows Internals。
其他缓存管理命令的信息,可以查看!cchelp扩展的参考。
!pcr 扩展显示指定处理器上的处理器控制域(Processor Control Region (PCR))的当前状态。
!pcr [Processor]
Processor
指定要获取哪个处理器的PCR信息。如果省略Processor,则使用当前处理器。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
处理器控制块(PRCB)是PCR的一个扩展。可以通过!prcb 命令来显示。
下面是x86目标机上的!pcr扩展命令的示例:
kd> !pcr 0
KPCR for Processor 0 at ffdff000:
Major 1 Minor 1
NtTib.ExceptionList: 801626e0
NtTib.StackBase: 801628f0
NtTib.StackLimit: 8015fb00
NtTib.SubSystemTib: 00000000
NtTib.Version: 00000000
NtTib.UserPointer: 00000000
NtTib.SelfTib: 00000000
SelfPcr: ffdff000
Prcb: ffdff120
Irql: 00000000
IRR: 00000000
IDR: ffffffff
InterruptMode: 00000000
IDT: 80043400
GDT: 80043000
TSS: 803cc000
CurrentThread: 8015e8a0
NextThread: 00000000
IdleThread: 8015e8a0
DpcQueue: 0x80168ee0 0x80100d04 ntoskrnl!KiTimerExpiration
显示中的一个条目是中断请求级别(IRQL)。!pcr 扩展显示的是当前IRQL,但是通常对当前IRQL都不是很感兴趣。Bug check或者调试器连接之前的IRQL要更加有用一些。可以通过!irql来显示这种IRQL,但是只有针对运行Windows Server2003和之后版本Windows的机器才有用。
关于PCR和PRCB的更多信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!pcrs 扩展命令显示Intel Itanium处理器的控制寄存器(control register)。
!pcrs Address
Address
指定processor control registers file的地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该扩展命令只能对Itanium目标机使用。
不要将!pcrs扩展和 !pcr 混淆,后者用来显示处理器控制域(processor control region)的当前状态。
!pfn 扩展用于显示指定的页面帧(page frame)或者整个页面帧数据库(page frame database)。
!pfn PageFrame
PageFrame
指定要显示的页面帧的16进制序号。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
可以通过!pte扩展获得某个虚拟地址的页面帧序号。
下面是该扩展的输出示例:
kd> !pte 801544f4
801544F4 - PDE at C0300800 PTE at C0200550
contains 0003B163 contains 00154121
pfn 3b G-DA--KWV pfn 154 G--A--KRV
kd> !pfn 3b
PFN 0000003B at address 82350588
flink 00000000 blink / share count 00000221 pteaddress C0300800
reference count 0001 color 0
restore pte 00000000 containing page 000039 Active
kd> !pfn 154
PFN 00000154 at address 82351FE0
flink 00000000 blink / share count 00000001 pteaddress C0200550
reference count 0001 color 0
restore pte 00000060 containing page 00003B Active M
Modified
关于页表、页目录、页面帧的信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!pmc 扩展显示指定地址处的性能监控计数器(Performance Monitor Counter (PMC))寄存器。
该命令仅在Itanium目标机上支持。
!pmc [- Option] Expression [DisplayLevel]
Option
可以是下面这些值中任意一个:
gen
将该寄存器当作常规PMC寄存器显示。
btb
将该寄存器当作branch trace buffer (BTB) PMC寄存器进行显示。
Expression
指定PMC的16进制地址。可以使用表达式@kpfcgen 和@kpfcbtb 用作参数的值。
如果Expression 是@kpfcgen,调试器将当前处理器的PMC寄存器当作常规PMC寄存器显示。还可以通过将Option 设置为gen,并且Expression 值使用@kpfc4、@kpfc5、@kpfc6或者@kpfc7来将当前处理器的PMC寄存器作为常规PMC寄存器显示。
如果Expression 为@kpfcbtb,调试器将当前处理器的PMC寄存器当作BTB PMC寄存器显示。也可以通过Optio设置为btb,并且Expression 的值使用@kpfc12来当作BTB PMC寄存器显示。
DisplayLevel
可以是下面这些值中任意一个:
0
仅显示每个PMC寄存器字段的值。这是默认情况。
1
显示非保留和非忽略的PCM寄存器字段的详细信息。
2
显示所有PMC寄存器字段的详细信息,包括被忽略的和保留的。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
!pmssa 扩展显示指定的processor Minimal State Save Area (也称为Min-StateSave Area)。
该扩展命令仅在Itanium目标机上可用。
!pmssa Address
Address
指定某个processor Min-StateSave Area的地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
!pnpevent 扩展显示即插即用(Plug and Play)设备事件队列。
!pnpevent [DeviceEvent]
DeviceEvent
指定要显示的设备事件(device event)的地址。如果为0或者省略,则显示该队列中所有设备事件的树(tree)。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
查看Plug and Play调试获得该扩展命令的应用。关于Plug and Play驱动程序的信息,查看Windows Driver Kit (WDK) 文档。
!pocaps 扩展显示目标机的电源能力(power capability)。
!pocaps
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
下面是该命令输出的示例:
kd> !pocaps
PopCapabilities @ 0x8016b100
Misc Supported Features: S4 FullWake
Processor Features:
Disk Features: SpinDown
Battery Features:
Wake Caps
Ac OnLine Wake: Sx
Soft Lid Wake: Sx
RTC Wake: Sx
Min Device Wake: Sx
Default Wake: Sx
要查看系统的电源策略(power policy),可以使用!popolicy 扩展命令。关于电源能力和电源策略的更多信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!pool扩展显示指定的内存池分配的信息,或者整个系统范围内内存池的分配信息。
!pool [Address [Flags]]
Address
指定要显示的内存池入口。如果Address是 -1,该命令显示进程中所有堆(all heaps in the process)的信息。如果Address 为0或省略,命令显示进程堆(process heap)的信息。
Flags
指定显示的级别。可以是下面这些位值的任意组合,默认值为0:
Bit 0 (0x1)
显示内存池内容,而不仅仅是头部(pool header)。
Bit 1 (0x2)
(Windows 2000和之后) 不显示所有内存池的头信息,除了实际包含指定的Address的那个。
Bit 31 (0x80000000)
(Windows XP和之后) 不显示池类型(type)和标签(tag)。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
在Windows XP和之后版本的Windows中,!pool 扩展显示每个分配关联的内存池标签(pool tag)。还会显示该标签的所有者。显示是基于pooltag.txt 文件的内容的。该文件位于Windwos调试工具包安装目录的triage 子目录下。如果需要的话,可以通过编辑该文件来添加自己的项目相关的其他pool tag。
警告 如果在当前版本安装的目录上安装Windwos调试工具包的升级版本,则它会覆盖该目录中所有文件,包括pooltag.txt。如果改变或者替换了示例的pooltag.txt,则要将它先保存到其他目录中。重新安装调试器之后,可以再用保存的那个pooltag.txt来进行覆盖。
如果!pool 扩展报告内存池破坏,应该使用!poolval来进行调查。
下面是一个例子。如果Address 指定0xE1001050,则显示这个块中的所有内存池的头部,并且0xE1001050本身用星号(*)标记。
kd> !pool e1001050
e1001000 size: 40 previous size: 0 (Allocated) MmDT
e1001040 size: 10 previous size: 40 (Free) Mm
*e1001050 size: 10 previous size: 10 (Allocated) *ObDi
e1001060 size: 10 previous size: 10 (Allocated) ObDi
e1001070 size: 10 previous size: 10 (Allocated) Symt
e1001080 size: 40 previous size: 10 (Allocated) ObDm
e10010c0 size: 10 previous size: 40 (Allocated) ObDi
.....
这个例子中,最右边的一列是pool tag。这一列左边显示这个pool是空闲的还是已分配的。
下面的命令显示内存池头部和内容(pool headers and pool contents):
kd> !pool e1001050 1
e1001000 size: 40 previous size: 0 (Allocated) MmDT
e1001008 ffffffff 0057005c 004e0049 004f0044
e1001018 ffffffff 0053005c 00730079 00650074
e1001040 size: 10 previous size: 40 (Free) Mm
e1001048 ffffffff e1007ba8 e1501a58 01028101
e1001058 ffffffff 00000000 e1000240 01028101
*e1001050 size: 10 previous size: 10 (Allocated) *ObDi
e1001058 ffffffff 00000000 e1000240 01028101
e1001068 ffffffff 00000000 e10009c0 01028101
e1001060 size: 10 previous size: 10 (Allocated) ObDi
e1001068 ffffffff 00000000 e10009c0 01028101
e1001078 ffffffff 00000000 00000000 04028101
......
关于内存池的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
cc682/NetRoc
http://netroc682.spaces.live.com/
在x86目标机上,!mca 扩展用于显示机器检查架构(machine check architecture (MCA))寄存器。在Itanium目标机上,!mca用于显示MCA错误记录。
x86 目标机语法
!mca
Itanium目标机语法
!mca Address [Flags]
Address
(仅Itanium目标) 指定MCA错误记录的地址。
Flags
(仅Itanium目标) 指定显示级别。Flags 可以是下面这些位的任意组合。默认值为0xFF,会显示日志中的所有部分(section)。
Bit 0 (0x1)
显示处理器部分(section)。
Bit 1 (0x2)
显示平台相关部分(platform-specific section)。
Bit 2 (0x4)
显示内存部分(memory section)
Bit 3 (0x8)
显示PCI组件部分。
Bit 4 (0x10)
显示PCI总线部分。
Bit 5 (0x20)
显示SystemEvent Log部分。
Bit 6 (0x40)
显示平台控制器(platform host controller)部分。
Bit 7 (0x80)
显示平台总线(platform bus)部分。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
该扩展命令只能针对x86或Itanium目标机使用。
在Itanium目标上,!mca 显示系统抽象层(system abstraction layer (SAL))中的MCA错误记录。下面是该扩展输出的示例:
kd> !mca e0000165f3f58000
hal!HalpFeatureBits: 0xf [HAL_PERF_EVENTS|HAL_MCA_PRESENT|HAL_CMC_PRESENT|HAL_CPE_PRESENT]
MCA Error Record Header @ 0xe0000165f3f58000 0xe0000165f3f597a8
Id : 8
Revision :
Revision : 2
Minor : 0x2 ''
Major : 0 ''
ErrorSeverity : 0 ''
Valid :
Valid : 0 ''
OemPlatformID : 0y0
Reserved : 0y0000000 (0)
Length : 0x17a8
TimeStamp :
TimeStamp : 0x20031106`00134944
Seconds : 0x44 'D'
Minutes : 0x49 'I'
Hours : 0x13 ''
Reserved : 0 ''
Day : 0x6 ''
Month : 0x11 ''
Year : 0x3 ''
Century : 0x20 ' '
OemPlatformId : [16] ""
Severity : ErrorRecoverable
MCA Error Section Header @ 0xe0000165f3f58028 0xe0000165f3f59578 [Processor]
Header :
Guid :
Data1 : 0xe429faf1
Data2 : 0x3cb7
Data3 : 0x11d4
Data4 : [8] "???"
Revision :
Revision : 2
Minor : 0x2 ''
Major : 0 ''
RecoveryInfo :
RecoveryInfo : 0 ''
Corrected : 0y0
NotContained : 0y0
Reset : 0y0
Reserved : 0y0000
Valid : 0y0
Reserved : 0 ''
Length : 0x1550
Valid :
Valid : 0x100101f
ErrorMap : 0y1
StateParameter : 0y1
CRLid : 0y1
StaticStruct : 0y1
CacheCheckNum : 0y0001
TlbCheckNum : 0y0000
BusCheckNum : 0y0001
RegFileCheckNum : 0y0000
MsCheckNum : 0y0000
CpuIdInfo : 0y1
Reserved : 0y000000000000000000000000000000000000000 (0)
ErrorMap :
ErrorMap : 0x1002000
Cid : 0y0000
Tid : 0y0000
Eic : 0y0000
Edc : 0y0010
Eit : 0y0000
Edt : 0y0000
Ebh : 0y0001
Erf : 0y0000
Ems : 0y0000000000000000 (0)
Reserved : 0y0000000000000000 (0)
StateParameter :
StateParameter : 0x28000000`fff21130
reserved0 : 0y00
rz : 0y0
ra : 0y0
me : 0y1
mn : 0y1
sy : 0y0
co : 0y0
ci : 0y1
us : 0y0
hd : 0y0
tl : 0y0
mi : 0y1
pi : 0y0
pm : 0y0
dy : 0y0
in : 0y0
rs : 0y1
cm : 0y0
ex : 0y0
cr : 0y1
pc : 0y1
dr : 0y1
tr : 0y1
rr : 0y1
ar : 0y1
br : 0y1
pr : 0y1
fp : 0y1
b1 : 0y1
b0 : 0y1
gr : 0y1
dsize : 0y0000000000000000 (0)
reserved1 : 0y00000000000 (0)
cc : 0y1
tc : 0y0
bc : 0y1
rc : 0y0
uc : 0y0
CRLid :
LocalId : 0
reserved : 0y0000000000000000 (0)
eid : 0y00000000 (0)
id : 0y00000000 (0)
ignored : 0y00000000000000000000000000000000 (0)
CacheErrorInfo[0]:
Valid : 1
CheckInfo : 0y1
RequestorIdentifier : 0y0
ResponderIdentifier : 0y0
TargetIdentifier : 0y0
PreciseIP : 0y0
Reserved : 0y00000000000000000000000000000000000000000000000000000000000 (0)
CheckInfo : 0x0
RequestorId : 0x0
ResponderId : 0x0
TargetIp : 0x0
TargetId : 0x0
PreciseIp : 0x0
CheckInfo:
CacheCheck : 0
Operation : 0y0000
Level : 0y00
Reserved1 : 0y00
DataLine : 0y0
TagLine : 0y0
DataCache : 0y0
InstructionCache : 0y0
MESI : 0y000
MESIValid : 0y0
Way : 0y00000 (0)
WayIndexValid : 0y0
Reserved2 : 0y0000000000 (0)
Index : 0y00000000000000000000 (0)
Reserved3 : 0y00
InstructionSet : 0y0
InstructionSetValid : 0y0
PrivilegeLevel : 0y00
PrivilegeLevelValid : 0y0
MachineCheckCorrected : 0y0
TargetAddressValid : 0y0
RequestIdValid : 0y0
ResponderIdValid : 0y0
PreciseIPValid : 0y0
BusErrorInfo[0]:
Valid : 9
CheckInfo : 0y1
RequestorIdentifier : 0y0
ResponderIdentifier : 0y0
TargetIdentifier : 0y1
PreciseIP : 0y0
Reserved : 0y00000000000000000000000000000000000000000000000000000000000 (0)
CheckInfo : 0x1080000003000144
RequestorId : 0x0
ResponderId : 0x0
TargetIp : 0x0
TargetId : 0xd0022004
PreciseIp : 0x0
CheckInfo:
BusCheck : 0x10800000`03000144
Size : 0y00100 (0x4)
Internal : 0y0
External : 0y1
CacheTransfer : 0y0
Type : 0y00000001 (0x1)
Severity : 0y00000 (0)
Hierarchy : 0y00
Reserved1 : 0y0
Status : 0y00000011 (0x3)
Reserved2 : 0y0000000000000000000000 (0)
InstructionSet : 0y0
InstructionSetValid : 0y1
PrivilegeLevel : 0y00
PrivilegeLevelValid : 0y0
MachineCheckCorrected : 0y0
TargetAddressValid : 0y1
RequestIdValid : 0y0
ResponderIdValid : 0y0
PreciseIPValid : 0y0
StaticInfo @ 0xe0000165f3f580f0 0xe0000165f3f59578
Valid @ 0xe0000165f3f580f0
Valid : 0x3f
MinState : 0y1
BR : 0y1
CR : 0y1
AR : 0y1
RR : 0y1
FR : 0y1
Reserved : 0y0000000000000000000000000000000000000000000000000000000000 (0)
MinState @ 0xe0000165f3f580f8 0xe0000165f3f584f0
IntNats : 0
IntGp : 0xe0000165`f1a99b00
IntT0 : 0
IntT1 : 0xe0f0e0f0`e0f0e000
IntS0 : 0
IntS1 : 1
IntS2 : 0xe0000000`83068300
IntS3 : 0xe0000000`832f8780
IntV0 : 0x4600
IntT2 : 0x230
IntT3 : 0x3ff
IntT4 : 0xe0000165`f38c6000
IntSp : 0xe0000165`f0f97da0
IntTeb : 0
IntT5 : 0
IntT6 : 0xfffff630
B0R16 : 0x1010`082a6018
B0R17 : 0
B0R18 : 0xe0000000`830067c0
B0R19 : 0x101
B0R20 : 0x80000000`00000308
B0R21 : 0
B0R22 : 0xe0000000`84bedd20
B0R23 : 0xe0000000`84bedd20
B0R24 : 0xe0000165`f213df5a
B0R25 : 0xfff80000`597c84f0
B0R26 : 0x6081
B0R27 : 0xfffffe00`00165f20
B0R28 : 0x8000465
B0R29 : 0x8000465
B0R30 : 0x60
B0R31 : 0xa04`00000000
IntT7 : 0x44
IntT8 : 0x200
IntT9 : 0xe0000165`f38c6000
IntT10 : 0xe0000165`f3cb81bc
IntT11 : 0xe0000165`f3cb81b8
IntT12 : 0xe0000000`8363f7b0
IntT13 : 0xe0000165`f1899d08
IntT14 : 0x9804c`8a70433f
IntT15 : 0xe0000000`832821f8
IntT16 : 0xe0000000`836536e0
IntT17 : 0xe0000000`8363f7b8
IntT18 : 0xffffffff`fffffbc3
IntT19 : 0xe0000165`f1ff6000
IntT20 : 0x2400580
IntT21 : 0xe0000165`f1ff6004
IntT22 : 0xe0000165`f3cb8dc0
Preds : 0x2277
BrRp : 0xe0000165`ea212df0
RsRSC : 3
StIIP : 0xe0000165`f1895370
StIPSR : 0x1010`082a6018
StIFS : 0x80000000`00000285
XIP : 0xe0000165`ea212c50
XPSR : 0x1010`082a6018
XFS : 0x80000000`00000b1c
BR @ 0xe0000165f3f584f8 0xe0000165f3f58530
e0000165`f3f584f8 e0000165`ea212df0 USBPORT!USBPORT_StopDevice+0x850
e0000165`f3f58500 00000000`00000000
e0000165`f3f58508 00000000`00000000
e0000165`f3f58510 00000000`00000000
e0000165`f3f58518 00000000`00000000
e0000165`f3f58520 00000000`00000000
e0000165`f3f58528 e0000000`832cb061 nt!NtClose+0x1
e0000165`f3f58530 e0000165`f1895320 usbohci!OHCI_StopController
CR @ 0xe0000165f3f58538 0xe0000165f3f58930
e0000165`f3f58538 00000000`00007e05
e0000165`f3f58540 00000154`a7047201
e0000165`f3f58548 e0000000`83230000 nt!KiVhptTransVector
e0000165`f3f58550 00000000`00000000
...
e0000165`f3f585c8 00000000`00000000
e0000165`f3f585d0 e0000165`f1895370 usbohci!OHCI_StopController+0x50
e0000165`f3f585d8 e0000165`f213df5a
e0000165`f3f585e0 00000000`00000060
e0000165`f3f585e8 e0000165`f1895360 usbohci!OHCI_StopController+0x40
e0000165`f3f585f0 80000000`00000285
...
e0000165`f3f58930 00000000`00000000
AR @ 0xe0000165f3f58938 0xe0000165f3f58d30
e0000165`f3f58938 00000000`00000000
e0000165`f3f58940 00000000`00000000
e0000165`f3f58948 00000000`00000000
e0000165`f3f58950 00000000`00000000
e0000165`f3f58958 00000000`00000000
e0000165`f3f58960 00000000`00000006
e0000165`f3f58968 e0000000`8301add0 nt!KiMemoryFault
e0000165`f3f58970 00000000`00000000
e0000165`f3f58978 00000000`00000000
e0000165`f3f58980 00000000`00000000
e0000165`f3f58988 00000000`00000000
e0000165`f3f58990 00000000`00000000
e0000165`f3f58998 00000000`00000000
e0000165`f3f589a0 00000000`00000000
e0000165`f3f589a8 00000000`00000000
e0000165`f3f589b0 00000000`00000000
e0000165`f3f589b8 e0000165`f1895370 usbohci!OHCI_StopController+0x50
e0000165`f3f589c0 e0000165`f0f988e0
...
e0000165`f3f58d30 00000000`00000000
RR @ 0xe0000165f3f58d38 0xe0000165f3f58d70
e0000165`f3f58d38 00000000`00000535
e0000165`f3f58d40 00000000`00000535
e0000165`f3f58d48 00000000`00000535
e0000165`f3f58d50 00000000`00000535
e0000165`f3f58d58 00000000`00000535
e0000165`f3f58d60 00000000`00000535
e0000165`f3f58d68 00000000`00000535
e0000165`f3f58d70 00000000`00000535
FR @ 0xe0000165f3f58d78 0xe0000165f3f59570
e0000165`f3f58d78 00000000`00000000
e0000165`f3f58d80 00000000`00000000
e0000165`f3f58d88 80000000`00000000
e0000165`f3f58d90 00000000`0000ffff
e0000165`f3f58d98 00000000`00000000
e0000165`f3f58da0 00000000`00000000
e0000165`f3f58da8 00000000`00000000
e0000165`f3f58db0 00000000`00000000
...
e0000165`f3f59570 00000000`00000000
MCA Error Section Header @ 0xe0000165f3f59578 0xe0000165f3f596a0 [PciComponent]
Header :
Guid :
Data1 : 0xe429faf6
Data2 : 0x3cb7
Data3 : 0x11d4
Data4 : [8] "???"
Revision :
Revision : 2
Minor : 0x2 ''
Major : 0 ''
RecoveryInfo :
RecoveryInfo : 0x80 ''
Corrected : 0y0
NotContained : 0y0
Reset : 0y0
Reserved : 0y0000
Valid : 0y1
Reserved : 0 ''
Length : 0x128
Valid :
Valid : 0x23
ErrorStatus : 0y1
Info : 0y1
MemoryMappedRegistersPairs : 0y0
ProgrammedIORegistersPairs : 0y0
RegistersDataPairs : 0y0
OemData : 0y1
Reserved : 0y0000000000000000000000000000000000000000000000000000000000 (0)
ErrorStatus :
Status : 0x121900
Reserved0 : 0y00000000 (0)
Type : 0y00011001 (0x19)
Address : 0y0
Control : 0y1
Data : 0y0
Responder : 0y0
Requestor : 0y1
FirstError : 0y0
Overflow : 0y0
Reserved1 : 0y00000000000000000000000000000000000000000 (0)
Info :
VendorId : 0x8086
DeviceId : 0x100e
ClassCodeInterface : 0 ''
ClassCodeSubClass : 0 ''
ClassCodeBaseClass : 0x2 ''
FunctionNumber : 0 ''
DeviceNumber : 0x3 ''
BusNumber : 0xa0 ''
SegmentNumber : 0 ''
Reserved0 : 0 ''
Reserved1 : 0
MemoryMappedRegistersPairs : 0
ProgrammedIORegistersPairs : 0
OemData @ 0xe0000165f3f595b8 0xe0000165f3f596a0
Data Length = 0xe6
Data:
e0000165`f3f595ba 00 00 00 00 00 00 91 d3-86 d3 7a 5e 7e 48 a4 0a ..........z^~H..
e0000165`f3f595ca 2b f6 f7 a6 cc ca 00 ff-ff ff ff ff ff ff 09 00 +...............
e0000165`f3f595da 00 00 00 00 00 00 00 00-00 00 08 00 00 00 86 80 ................
e0000165`f3f595ea 0e 10 47 01 30 22 08 00-00 00 08 00 00 00 02 00 ..G.0"..........
e0000165`f3f595fa 00 02 20 80 00 00 10 00-00 00 08 00 00 00 00 00 .. .............
e0000165`f3f5960a 00 d0 00 00 00 00 18 00-00 00 08 00 00 00 81 a0 ................
e0000165`f3f5961a 00 00 00 00 00 00 20 00-00 00 08 00 00 00 00 00 ...... .........
e0000165`f3f5962a 00 00 00 00 00 00 28 00-00 00 08 00 00 00 00 00 ......(.........
e0000165`f3f5963a 00 00 3c 10 74 12 30 00-00 00 08 00 00 00 00 00 ..<.t.0.........
e0000165`f3f5964a 00 00 dc 00 00 00 38 00-00 00 08 00 00 00 00 00 ......8.........
e0000165`f3f5965a 00 00 2a 01 ff 00 e4 00-00 00 08 00 00 00 07 f0 ..*.............
e0000165`f3f5966a 1e 00 00 00 40 04 00 00-00 00 00 00 00 00 00 00 ....@...........
e0000165`f3f5967a 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
e0000165`f3f5968a 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
e0000165`f3f5969a 00 00 00 00 00 00 ......
MCA Error Section Header @ 0xe0000165f3f596a0 0xe0000165f3f597a8 [PciBus]
Header :
Guid :
Data1 : 0xe429faf4
Data2 : 0x3cb7
Data3 : 0x11d4
Data4 : [8] "???"
Revision :
Revision : 2
Minor : 0x2 ''
Major : 0 ''
RecoveryInfo :
RecoveryInfo : 0x84 ''
Corrected : 0y0
NotContained : 0y0
Reset : 0y1
Reserved : 0y0000
Valid : 0y1
Reserved : 0 ''
Length : 0x108
Valid :
Valid : 0x74f
ErrorStatus : 0y1
ErrorType : 0y1
Id : 0y1
Address : 0y1
Data : 0y0
CmdType : 0y0
RequestorId : 0y1
ResponderId : 0y0
TargetId : 0y1
OemId : 0y1
OemData : 0y1
Reserved : 0y00000000000000000000000000000000000000000000000000000 (0)
ErrorStatus :
Status : 0x121900
Reserved0 : 0y00000000 (0)
Type : 0y00011001 (0x19)
Address : 0y0
Control : 0y1
Data : 0y0
Responder : 0y0
Requestor : 0y1
FirstError : 0y0
Overflow : 0y0
Reserved1 : 0y00000000000000000000000000000000000000000 (0)
Type :
Type : 0x4 ''
Reserved : 0 ''
Id :
BusNumber : 0xa0 ''
SegmentNumber : 0 ''
Reserved : [4] ""
Address : 0xd0022054
Data : 0
CmdType : 0
RequestorId : 0xfed2a000
ResponderId : 0
TargetId : 0xd0022054
OemId : [16] ".???"
OemData :
Length : 0x98
CP M/R/F/A Manufacturer SerialNumber Features Speed
0 1,5,31,0 GenuineIntel 0000000000000000 0000000000000001 1000 Mhz
在x86目标上,!mca 显示由活动处理器支持的machine check 寄存器。还会显示基本的CPU信息(和!cpuinfo显示的一样)。下面是该扩展的输出示例:
0: kd> !mca
MCE: Enabled, Cycle Address: 0x00000001699f7a00, Type: 0x0000000000000000
MCA: Enabled, Banks 5, Control Reg: Supported, Machine Check: None.
Bank Error Control Register Status Register
0. None 0x000000000000007f 0x0000000000000000
1. None 0x00000000ffffffff 0x0000000000000000
2. None 0x00000000000fffff 0x0000000000000000
3. None 0x0000000000000007 0x0000000000000000
4. None 0x0000000000003fff 0x0000000000000000
No register state available.
CP F/M/S Manufacturer MHz Update Signature Features
0 15,5,0 SomeBrandName 1394 0000000000000000 a0017fff
注意该扩展需要HAL的私有符号。如果没有这些符号,扩展命令会显示信息"HalpFeatureBits not found",以及基本CPU信息。例如 :
kd> !mca
HalpFeatureBits not found
CP F/M/S Manufacturer MHz Update Signature Features
0 6,5,1 GenuineIntel 334 0000004000000000 00001fff
!memlist 扩展用来扫描页面帧序号数据库(page frame number (PFN) database)中的物理内存列表,以检查它们的一致性。
!memlist Flags
Flags
指定要校验的内存。目前只实现了下面这一个值:
Bit 0 (0x1)
校验零页面列表(zeroed pages list)。
Windows NT 4.0 |
Kdexts.dll |
Windows 2000 |
Kdexts.dll |
Windows XP和之后 |
Kdexts.dll |
目前,该扩展命令只检查零页面列表(zeroed pages list )来确认是否该列表中所有页面都被用0填充了。使用的语法如下:
kd> !memlist 1
!memusage 扩展显示物理内存使用的摘要统计。
Windows 2000和之后的语法
!memusage
Windows XP和之后的语法
!memusage [Flags]
Flags
(Windows XP和之后) 可以是下面这些值的任意一个。默认为0x0。
0x0
显示一般摘要信息,以及对PFN数据库中的页面更详细一些的说明。查看注释节获得这种输出的示例。
0x1
仅显示PFN数据库中已修改的非写页面(no-write page)的摘要信息。
0x2
仅显示PFN数据库中已修改的非写页面(no-write page)的详细信息。
0x8
仅显示内存使用的一般摘要信息。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
物理内存统计是由内存管理器(Memory Manager)的页面帧序号(PFN)数据库搜集的。
由于需要获取大量数据,该命令需要运行较长时间,特别是当目标机运行在64位模式时。加载PFN数据库时,会由一个计数器来显示进度。要加快这种加载,可以通过CTRL+A (Toggle Baud Rate) 键增加COM口的速度,或者使用, .cache (Set Cache Size) 命令增加缓存大小(可能大约在10 MB左右)。
!memusage 命令也可以在本地内核调试时使用。
下面是该命令输出的一个例子:
kd> !memusage
loading PFN database
loading (98% complete)
Compiling memory usage data (100% Complete).
Zeroed: 49 ( 196 kb)
Free: 5 ( 20 kb)
Standby: 5489 ( 21956 kb)
Modified: 714 ( 2856 kb)
ModifiedNoWrite: 1 ( 4 kb)
Active/Valid: 10119 ( 40476 kb)
Transition: 6 ( 24 kb)
Unknown: 0 ( 0 kb)
TOTAL: 16383 ( 65532 kb)
Building kernel map
Finished building kernel map
Scanning PFN database - (99% complete)
Usage Summary (in Kb):
Control Valid Standby Dirty Shared Locked PageTables name
8251a258 12 108 0 0 0 0 mapped_file( cscui.dll )
827ab1b8 8 1708 0 0 0 0 mapped_file( $Mft )
8263c408 908 48 0 0 0 0 mapped_file( win32k.sys )
8252dda8 0 324 0 0 0 0 mapped_file( ShellIconCache )
8272f638 128 112 0 116 0 0 mapped_file( advapi32.dll )
......
82755958 0 4 0 0 0 0 mapped_file( $Directory )
8250b518 0 4 0 0 0 0 No Name for File
8254d8d8 0 4 0 0 0 0 mapped_file( $Directory )
82537be8 0 4 0 0 0 0 mapped_file( Windows Explorer.lnk )
-------- 1348 0 0 ----- ----- 904 process ( System )
-------- 492 0 0 ----- ----- 72 process ( winmine.exe )
-------- 3364 1384 1396 ----- ----- 188 process ( explorer.exe )
-------- 972 0 0 ----- ----- 88 process ( services.exe )
-------- 496 1456 384 ----- ----- 164 process ( winmgmt.exe )
-------- 1144 0 0 ----- ----- 120 process ( svchost.exe )
-------- 944 0 0 ----- ----- 156 process ( winlogon.exe )
-------- 412 0 0 ----- ----- 64 process ( csrss.exe )
......
-------- 12 0 0 ----- ----- 8 process ( wmiadap.exe )
-------- 316 0 0 ----- ----- 0 pagefile section (346e)
-------- 4096 0 0 ----- ----- 0 pagefile section (9ad)
-------- 884 280 36 ----- 0 ----- driver ( ntoskrnl.exe )
-------- 88 8 0 ----- 0 ----- driver ( hal.dll )
-------- 8 0 0 ----- 0 ----- driver ( kdcom.dll )
-------- 12 0 0 ----- 0 ----- driver ( BOOTVID.dll )
......
-------- 8 0 0 ----- 0 ----- driver ( ndisuio.sys )
-------- 16 0 0 ----- 0 ----- driver ( dump_scsiport.sys )
-------- 56 0 0 ----- 0 ----- driver ( dump_aic78xx.sys )
-------- 2756 1060 876 ----- 0 ----- driver ( Paged Pool )
-------- 1936 128 148 ----- 0 ----- driver ( Kernel Stacks )
-------- 0 0 0 ----- 0 ----- driver ( NonPaged Pool )
第一列显示用来描述每个已映射结构(mapped structure)的控制域结构(control area structure)地址。使用!ca 扩展命令可以显示这些控制域。
使用 !vm 扩展命令可以分析虚拟内存使用。该命令一般比!memusage要更有用些。关于内存管理的信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!pfn 扩展命令可以用来查看PFN数据库中某个特定页面帧。
!mps 扩展显示目标机中Intel 多处理器规范(Multiprocessor Specification (MPS))的BIOS信息。
!mps [Address]
Address
指定BIOS中MPS表的16进制地址。如果省略,则从HAL中获取该信息。这需要HAL的符号。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
该扩展命令仅对x86目标机使用。
关于BIOS调试的更多信息,查看调试BIOS代码。关于MPS的信息,查看Intel MultiProcessor Specification的适当版本。
!mtrr 扩展显示MTRR寄存器的内容。
!mtrr
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
该扩展命令只能用于x86目标机。
!npx 扩展显示浮点寄存器保存区域(floating-point register save area)的内容。
!npx Address
Address
指定FLOATING_SAVE_AREA 结构的16进制地址。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
该扩展命令只能用于x86目标机。
!ob、 !od、以及!ow 扩展命令已废除。使用ob, od, ow (Output to Port) 命令来替代。
!object 扩展显示某个系统对象。
Windows NT 4.0的语法
!object Address
!object 0 Name
!object /
Windows 2000和之后的语法
!object Address
!object 0 Name
!object Path
!object -r
Address
如果第一个参数是非0的16进制数字,则指定要显示信息的系统对象的16进制地址。
Name
如果第一个参数为0,则第二个参数是要显示所有实例的系统对象类型的名字。
Path
如果第一个参数以反斜线开头 (/), !object 将它当作一个对象路径的名字(object path name)。使用该选项时,会根据对象管理器(Object Manager)的目录结构来进行显示。
/
(仅Windows NT 4.0) 指定根目录对象(root directory object)。
-r
(Windows 2000 和之后) 使得被缓存的全局变量的值被刷新。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
!object 扩展会缓存一些值能够被改变的特定的全局变量。如果使用的内核符号已经过期,可以使用!object –r来刷新缓存的值。
下面的例子用!handle 扩展来获得对象指针:
kd> !handle
processor number 0
PROCESS 80a02920 Cid: 0002 Peb: 00000000 ParentCid: 0000
DirBase: 0006c805 ObjectTable: 80a03788 TableSize: 54.
Image: System
006c: Object: 80967768 GrantedAccess: 00100003
Object: 80967768 Type: (809d5c20) File
ObjectHeader: 80967750
HandleCount: 1 PointerCount: 1
Directory Object: 00000000 Name: /WINNT/system32/config/software {Partition1}
kd> !object 80967768
Object: 80967768 Type: (809d5c20) File
ObjectHeader: 80967750
HandleCount: 1 PointerCount: 1
Directory Object: 00000000 Name: /WINNT/system32/config/software {Partition1}
关于对象和对象管理器的信息,查看Microsoft Windows SDK文档、Windows Driver Kit (WDK)文档、以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!obtrace 扩展显示指定对象的对象引用数据。
!obtrace Object
Object
指向对象的指针或者路径。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
Windows的对象引用跟踪功能会在每次对象的引用计数增加或者减少时记录调用堆栈。
使用该扩展命令来显示对象引用跟踪数据前,必须用GFlags来对指定的对象启用对象引用跟踪(object reference tracing) 。可以通过内核标志(运行时)设置来启用对象引用跟踪,这种改变会立即生效,但是关闭或重起之后消失;也可以通过注册表设置,这种设置需要重起,但是如果没有改变的话会一直保持下去。
下面是!obtrace 扩展的输出示例:
kd> !obtrace 0xfa96f700
Object: fa96f700 Image: cmd.exe
Sequence (+/-) Stack
-------- ----- ---------------------------------------------------
2421d +1 nt!ObCreateObject+180
nt!NtCreateEvent+92
nt!KiFastCallEntry+104
nt!ZwCreateEvent+11
win32k!UserThreadCallout+6f
win32k!W32pThreadCallout+38
nt!PsConvertToGuiThread+174
nt!KiBBTUnexpectedRange+c
2421e -1 nt!ObfDereferenceObject+19
nt!NtCreateEvent+d4
nt!KiFastCallEntry+104
nt!ZwCreateEvent+11
win32k!UserThreadCallout+6f
win32k!W32pThreadCallout+38
nt!PsConvertToGuiThread+174
nt!KiBBTUnexpectedRange+c
2421f +1 nt!ObReferenceObjectByHandle+1c3
win32k!xxxCreateThreadInfo+37d
win32k!UserThreadCallout+6f
win32k!W32pThreadCallout+38
nt!PsConvertToGuiThread+174
nt!KiBBTUnexpectedRange+c
24220 +1 nt!ObReferenceObjectByHandle+1c3
win32k!ProtectHandle+22
win32k!xxxCreateThreadInfo+3a0
win32k!UserThreadCallout+6f
win32k!W32pThreadCallout+38
nt!PsConvertToGuiThread+174
nt!KiBBTUnexpectedRange+c
24221 -1 nt!ObfDereferenceObject+19
win32k!xxxCreateThreadInfo+3a0
win32k!UserThreadCallout+6f
win32k!W32pThreadCallout+38
nt!PsConvertToGuiThread+174
nt!KiBBTUnexpectedRange+c
---- ----------------------------------------------------------
References: 3, Dereferences 2
!obtrace 0xfa96f700显示出来的主要指示符在下表中列出。
参数 |
意义 |
Sequence |
表示操作的顺序。 |
+/- |
表示引用或者取消引用的操作。 |
在x64目标机上的对象引用跟踪可能不完全,因为在IRQL高于PASSIVE_LEVEL 的时候并不一定能够取到调用堆栈。
任何时候可以通过按下CTRL+BREAK (WinDbg) 或CTRL+C (KD)中止命令。
关于全局标志实用工具(GFlags)的更多信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!openmaps 扩展显示指定的共享缓存映射(shared cache map)的引用缓冲区控制块(referenced buffer control blocks (BCBs)),和虚拟地址控制块(virtual address control blocks (VACBs))。
!openmaps Address [Flag]
Address
指定共享缓存映射的地址。
Flag
指定要显示哪个控制块。如果Flag为1,调试器显示所有控制块。如果Flag为0,调试器仅显示引用控制块 (referenced control blocks)。默认值为0。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
关于缓存管理的信息,查看Microsoft Windows SDK文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
关于其他缓存管理扩展命令的信息,查看!cchelp 扩展。
cc682/NetRoc
http://netroc682.spaces.live.com/
!job 扩展用来显示一个作业(job)对象。
!job [Process [Flags]]
Process
指定要查看的job对象所关联的进程或者线程的16进制地址。如果省略或者设为-1(Windows 2000中)或者0 (Windows XP和之后),则显示当前进程关联的job对象。
Flags
指定显示中包含的内容。可以是任意下面这些位值的和。默认值为0x1:
Bit 0 (0x1)
显示job的设置和统计。
Bit 1 (0x2)
显示job中所有进程的列表。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
下面是该扩展输出的示例:
kd> !process 52c
Searching for Process with Cid == 52c
PROCESS 8276c550 SessionId: 0 Cid: 052c Peb: 7ffdf000 ParentCid: 0060
DirBase: 01289000 ObjectTable: 825f0368 TableSize: 24.
Image: cmd.exe
VadRoot 825609e8 Vads 30 Clone 0 Private 77. Modified 0. Locked 0.
DeviceMap e1733f38
Token e1681610
ElapsedTime 0:00:12.0949
UserTime 0:00:00.0359
.....
CommitCharge 109
Job 8256e1f0
kd> !job 8256e1f0
Job at ffffffff8256e1f0
TotalPageFaultCount 0
TotalProcesses 1
ActiveProcesses 1
TotalTerminatedProcesses 0
LimitFlags 0
MinimumWorkingSetSize 0
MaximumWorkingSetSize 0
ActiveProcessLimit 0
PriorityClass 0
UIRestrictionsClass 0
SecurityLimitFlags 0
Token 00000000
关于job对象的信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!kb 和!kv 扩展命令已经废除。使用kb (Display Stack Backtrace) 和kv (Display Stack Backtrace) 命令来替代。
!loadermemorylist 扩展显示Windows boot loader传递给Windows的内存分配列表。
!loadermemorylist ListHeadAddress
ListHeadAddress
指定列表头的地址。
Windows NT 4.0 |
Kdexts.dll |
Windows 2000 |
Kdexts.dll |
Windows XP |
Kdexts.dll |
Windows Vista和之后 |
Kdexts.dll |
该扩展是设计在Ntldr正在运行的系统引导早期使用的。它会在内存分配列表中显示开始位置、结束为止和每个页范围的类型。
任何时候按下CTRL+BREAK (WinDbg) 或CTRL+C (KD)都可以中断命令的执行。
!lockedpages 扩展在Windows 2000中显示当前进程的driver-locked page,在Windows XP和之后的系统中显示指定进程的driver-locked page。
Windows 2000的语法
!lockedpages
Windows XP和之后的语法
!lockedpages [Process]
Process
(仅Windows XP和之后) 指定某个进程。如果省略Process,则使用当前进程。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
任何时候按下CTRL+BREAK (WinDbg) 或CTRL+C (KD)都可以中断命令的执行。
Kdextx86.dll 和Kdexts.dll中的!locks 扩展命令显示内核ERESOURCE 锁的信息。
该命令不要和!ntsdexts.locks 扩展命令混淆。
!locks [Options] [Address]
Options
指定要显示的信息数量。可以是下面这些选项的任意组合:
-v
显示每个锁的详细信息。
-p
显示锁的所有可能的信息,包括性能统计。
-d
显示所有锁的信息。否则只显示出现争用的锁。
Address
指定要显示的ERESOURCE 锁的16进制地址。如果Address为0或者省略,则显示系统中所有ERESOURCE 锁。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
!locks 扩展显示线程为资源而持有的所有的锁。锁可以是共享的(shared)或者独占的(exclusive),独占意味着其它线程不能访问该资源。当系统发生死锁时这个信息很有用。死锁是由于某个非执行的线程持有了某个资源的独占锁,但是其它执行的线程又需要这个所的时候会发生。
在Microsoft Windows 2000中通常可以通过查找非执行线程持有了某个执行线程请求的某个资源的独占锁的情况,来定位死锁。大多数的锁都是共享的。
下面是基本的!locks 输出的示例:
kd> !locks
**** DUMP OF ALL RESOURCE OBJECTS ****
KD: Scanning for held locks......
Resource @ 0x80e97620 Shared 4 owning threads
Threads: ff688da0-01<*> ff687da0-01<*> ff686da0-01<*> ff685da0-01<*>
KD: Scanning for held locks.......................................................
Resource @ 0x80e23f38 Shared 1 owning threads
Threads: 80ed0023-01<*> *** Actual Thread 80ed0020
KD: Scanning for held locks.
Resource @ 0x80d8b0b0 Shared 1 owning threads
Threads: 80ed0023-01<*> *** Actual Thread 80ed0020
2263 total locks, 3 locks currently held
注意显示出来的每个线程的地址后面都跟有线程计数 (例如"-01")。如果某个线程后跟有 I "<*>",则该线程是锁的所有者。有些情况下,初始线程的地址会包含一个偏移。这种情况下,实际的线程地址也会显示出来。
如果想查看这些资源对象中某一个的更多信息,可以将"Resource @"后的地址作为其它命令的参数。要查看上面例子中的第二个资源,可以使用dt ERESOURCE 80d8b0b0 或者 !thread 80ed0020。或者也可以带-v选项再次使用!locks:
kd> !locks -v 80d8b0b0
Resource @ 0x80d8b0b0 Shared 1 owning threads
Threads: 80ed0023-01<*> *** Actual Thread 80ed0020
THREAD 80ed0020 Cid 4.2c Teb: 00000000 Win32Thread: 00000000 WAIT: (WrQueue) KernelMode Non-Alertable
8055e100 Unknown
Not impersonating
GetUlongFromAddress: unable to read from 00000000
Owning Process 80ed5238
WaitTime (ticks) 44294977
Context Switch Count 147830
UserTime 0:00:00.0000
KernelTime 0:00:02.0143
Start Address nt!ExpWorkerThread (0x80506aa2)
Stack Init fafa4000 Current fafa3d18 Base fafa4000 Limit fafa1000 Call 0
Priority 13 BasePriority 13 PriorityDecrement 0
ChildEBP RetAddr
fafa3d30 804fe997 nt!KiSwapContext+0x25 (FPO: [EBP 0xfafa3d48] [0,0,4]) [D:/NT/base/ntos/ke/i386/ctxswap.asm @ 139]
fafa3d48 80506a17 nt!KiSwapThread+0x85 (FPO: [Non-Fpo]) (CONV: fastcall) [d:/nt/base/ntos/ke/thredsup.c @ 1960]
fafa3d78 80506b36 nt!KeRemoveQueue+0x24c (FPO: [Non-Fpo]) (CONV: stdcall) [d:/nt/base/ntos/ke/queueobj.c @ 542]
fafa3dac 805ad8bb nt!ExpWorkerThread+0xc6 (FPO: [Non-Fpo]) (CONV: stdcall) [d:/nt/base/ntos/ex/worker.c @ 1130]
fafa3ddc 8050ec72 nt!PspSystemThreadStartup+0x2e (FPO: [Non-Fpo]) (CONV: stdcall) [d:/nt/base/ntos/ps/create.c @ 2164]
00000000 00000000 nt!KiThreadStartup+0x16 [D:/NT/base/ntos/ke/i386/threadbg.asm @ 81]
1 total locks, 1 locks currently held
!logonsession 扩展显示指定的登陆会话(logon session)的信息。
Free Build 语法
!logonsession LUID
Checked Build语法
!logonsession LUID [InfoLevel]
LUID
指定要显示的登陆会话的局部唯一标识符(LUID)。 如果LUID为0,则显示所有登陆会话的信息。
要在check版中显示系统会话和所有系统令牌(system token),输入!logonsession 3e7 1。
InfoLevel
(仅Checked Build) 指定要显示多少令牌信息(token information)。InfoLevel 参数可以是0到4之间的值,0表示最少的信息,4表示最多。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
下面是该扩展命令在free build上的输出示例:
kd> !logonsession 0
Dumping all logon sessions.
** Session 0 = 0x0
LogonId = {0x0 0x0}
References = 0
** Session 1 = 0x8ebb50
LogonId = {0xe9f1 0x0}
References = 21
** Session 2 = 0x6e31e0
LogonId = {0x94d1 0x0}
References = 1
** Session 3 = 0x8ecd60
LogonId = {0x6b31 0x0}
References = 0
** Session 4 = 0xe0000106
LogonId = {0x0 0x0}
References = 0
** Session 5 = 0x0
LogonId = {0x0 0x0}
References = 0
** Session 6 = 0x8e9720
LogonId = {0x3e4 0x0}
References = 6
** Session 7 = 0xe0000106
LogonId = {0x0 0x0}
References = 0
** Session 8 = 0xa2e160
LogonId = {0x3e5 0x0}
References = 3
** Session 9 = 0xe0000106
LogonId = {0x0 0x0}
References = 0
** Session 10 = 0x3ca0
LogonId = {0x3e6 0x0}
References = 2
** Session 11 = 0xe0000106
LogonId = {0x0 0x0}
References = 0
** Session 12 = 0x1cd0
LogonId = {0x3e7 0x0}
References = 33
** Session 13 = 0xe0000106
LogonId = {0x0 0x0}
References = 0
14 sessions in the system.
任何时候都可以通过按下CTRL+BREAK (WinDbg) 或CTRL+C (KD)来中止命令执行。
关于登陆会话的信息,查看Microsoft Windows SDK 文档和Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!lookaside 扩展可以显示look-aside lists的信息、重置look-aside list的计数器、或者改变look-aside list的深度。
!lookaside [Address [Options [Depth]]]
Address
指定要使用的look-aside lists的16进制地址。如果Address为0或者省略,则显示所有的系统look-aside list。
Options
控制要进行的操作。支持下面这些可能的Options 。默认值为0:
0
显示指定的look-aside list 的信息。 (如果Address为0,则显示所有系统look-aside list。)
1
重置指定look-aside list的计数器。(仅Windows NT 4.0:如果Address 为0,则重置所有small pool look-aside list。)
2
改变指定look-aside list 的深度。该选项只有在Address 非0时可以使用。
Depth
设置给定的look-aside list的最大深度。该参数仅在Addres非0,并且Options 等于 2时可用。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
Look-aside list是一种用于管理固定大小的分页或非分页内存池的多处理器安全的机制。
由于在大多数平台上都不使用自旋锁(spin lock),所以look-aside list是高效的。
注意如果look-aside list的当前深度大于它的最大深度,则释放关联到该list的结构时会释放到池内存中,而不是释放到list内存中。
下面是该扩展的输出示例:
kd> !lookaside e0000165f7621800
Lookaside "" @ e0000165f7621800 "Ntfs"
Type = 0011 PagedPool RaiseIfAllocationFailure
Current Depth = 0 Max Depth = 4
Size = 488 Max Alloc = 1952
AllocateMisses = 3 FreeMisses = 0
TotalAllocates = 4 TotalFrees = 4
Hit Rate = 25% Hit Rate = 100%
关于look-aside list的信息,查看Windows Driver Kit (WDK) 文档,以及 Mark Russinovich 和David Solomon编写的Microsoft Windows Internals。
!lpc 扩展显示目标系统中的本地过程调用(local procedure call (LPC))端口和信息。
Windows NT 4.0的语法
!lpc
Windows 2000的语法
!lpc message MessageID
!lpc port Port
!lpc scan Port
!lpc thread Thread
!lpc
Windows Server 2003 和Windows XP的语法
!lpc message MessageID
!lpc port Port
!lpc scan Port
!lpc thread Thread
!lpc PoolSearch
!lpc
message
(仅Windows Server 2003、Windows XP、和Windows 2000) 如果有的话,显示某条消息的信息,例如队列中包含该消息的服务器端口(server port)、等待该消息的线程。
MessageID
(仅Windows Server 2003、Windows XP、和Windows 2000) 指定要显示的消息的消息ID。如果该参数的值为0或者省略,!lpc message 命令显示消息的摘要列表。(在Windows 2000 Service Pack 1 (SP1)中,摘要包括LPC zone 的所有消息。在Windows 2000 Service Pack 2 (SP2)、 Windows XP和之后版本的Windows中,摘要包括系统池中的所有消息。已经被页换出得消息不会包含。)
port
(仅Windows Server 2003、Windows XP、和Windows 2000) 显示端口信息,如端口的名字、信号量状态、队列中的消息、裁剪队列(rundown queue)中的线程、句柄数量、引用、以及相关的端口。
scan
(仅Windows Server 2003、Windows XP、和Windows 2000) 显示指定端口以及连接到它的所有端口的摘要信息。
Port
(仅Windows Server 2003、Windows XP、和Windows 2000) 指定要显示的端口的16进制地址。如果使用!lpc port 命令,并且 Port 为0或省略,则显示所由LPC端口的摘要列表。如果使用!lpc scan 命令,Port 必须指定一个实际的端口地址。
thread
(仅Windows Server 2003、Windows XP、和Windows 2000) 显示在rundown port queue中包含指定线程的所有端口的信息。
Thread
(仅Windows Server 2003、Windows XP、和Windows 2000) 指定线程的16进制地址。如果为0或者省略,!lpc thread命令显示所有正在进行LPC操作的线程的摘要列表。
PoolSearch
(仅Windows Server 2003、Windows XP、和Windows 2000) 指定!lpc message命令是否在内核池(kernel pool)中搜索消息。每次使用!lpc PoolSearch时,该设置会在打开和关闭之间切换(初始设置是不搜索内核池)。它仅作用于MessageID指定为非0值的!lpc message命令。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP |
Kdexts.dll |
该扩展在Windows Vista和之后版本的Windows中不支持。
在Windows NT 4.0,不带参数使用 !lpc 会显示目标机上所有LPC端口和消息,类似在Windows 2000和之后系统中使用!lpc port 然后使用 !lpc message。
在Windows Server 2003、Windows XP和Windows 2000中,不带参数使用!lpc 会在调试器命令窗口中显示该扩展命令的帮助文本。
如果有某个线程被标记为在等待某条消息返回,可以使用!lpc message 命令和这条延迟的消息的ID。命令会显示该消息、包含它的端口、以及所有被延迟的线程。
如果找不到消息,并且没有读取错误(例如"Unable to access zone segment"),则服务器已经接收到了这条消息。
这种情况下,服务器端口一般可以通过!lpc thread命令找到。等待响应的线程连接到服务器通信队列(server communication queue)上。这条命令可以显示所有包含指定线程的端口。知道了端口地址之后,可以使用!lpc port 命令。通过使用!lpc thread 命令和线程地址,可以获得关于每条线程的更多信息。
下面是扩展命令在Windows XP系统上的输出示例:
这个例子中,显示了所有LPC端口。
kd> !lpc port
Scanning 225 objects
1 Port: 0xe1405650 Connection: 0xe1405650 Communication: 0x00000000 'SeRmCommandPort'
1 Port: 0xe141ef50 Connection: 0xe141ef50 Communication: 0x00000000 'SmApiPort'
1 Port: 0xe13c5740 Connection: 0xe13c5740 Communication: 0x00000000 'ApiPort'
1 Port: 0xe13d9550 Connection: 0xe13d9550 Communication: 0x00000000 'SbApiPort'
3 Port: 0xe13d8830 Connection: 0xe141ef50 Communication: 0xe13d8910 ''
80000004 Port: 0xe13d8910 Connection: 0xe141ef50 Communication: 0xe13d8830 ''
3 Port: 0xe13d8750 Connection: 0xe13d9550 Communication: 0xe13a4030 ''
.....
上面例子中,地址e14ae238 处的端口没有消息,即所有消息都已经被接收并且没有新消息到达。
kd> !lpc port e14ae238
Server connection port e14ae238 Name: ApiPort
Handles: 1 References: 107
Server process : 84aa0140 (csrss.exe)
Queue semaphore : 84a96da8
Semaphore state 0 (0x0)
The message queue is empty
The LpcDataInfoChainHead queue is empty
上面例子中,0xe14ae238 处的端口有已排队但是还没有被服务器接收的消息。
kd> !lpc port 0xe14ae238
Server connection port e14ae238 Name: ApiPort
Handles: 1 References: 108
Server process : 84aa0140 (csrss.exe)
Queue semaphore : 84a96da8
Semaphore state 0 (0x0)
Messages in queue:
0000 e20d9b80 - Busy Id=0002249c From: 0584.0680 Context=00000021 [e14ae248 . e14ae248]
Length=0098007c Type=00000001 (LPC_REQUEST)
Data: 00000000 0002021e 00000584 00000680 002f0001 00000007
The message queue contains 1 messages
The LpcDataInfoChainHead queue is empty
剩下的这些Windows XP上的示例是关于可以在这条扩展命令中使用的其它选项的。
kd> !lpc message 222be
Searching message 222be in threads ...
Client thread 842a4db0 waiting a reply from 222be
Searching thread 842a4db0 in port rundown queues ...
Server communication port 0xe114a3c0
Handles: 1 References: 1
The LpcDataInfoChainHead queue is empty
Connected port: 0xe1e7b948 Server connection port: 0xe14ae238
Client communication port 0xe1e7b948
Handles: 1 References: 3
The LpcDataInfoChainHead queue is empty
Server connection port e14ae238 Name: ApiPort
Handles: 1 References: 107
Server process : 84aa0140 (csrss.exe)
Queue semaphore : 84a96da8
Semaphore state 0 (0x0)
The message queue is empty
The LpcDataInfoChainHead queue is empty
Done.
kd> !lpc thread 842a4db0
Searching thread 842a4db0 in port rundown queues ...
Server communication port 0xe114a3c0
Handles: 1 References: 1
The LpcDataInfoChainHead queue is empty
Connected port: 0xe1e7b948 Server connection port: 0xe14ae238
Client communication port 0xe1e7b948
Handles: 1 References: 3
The LpcDataInfoChainHead queue is empty
Server connection port e14ae238 Name: ApiPort
Handles: 1 References: 107
Server process : 84aa0140 (csrss.exe)
Queue semaphore : 84a96da8
Semaphore state 0 (0x0)
The message queue is empty
The LpcDataInfoChainHead queue is empty
kd> !lpc scan e13d8830
Scanning 225 objects
3 Port: 0xe13d8830 Connection: 0xe141ef50 Communication: 0xe13d8910 ''
80000004 Port: 0xe13d8910 Connection: 0xe141ef50 Communication: 0xe13d8830 ''
Scanning 3 objects
下面是在Windows NT 4.0系统上的输出示例:
kd> !lpc
Scanning 2 objects of type 'Port'
Connection Port Object at e11b8bc0 - Name='/SmApiPort' created by smss.exe
Connection Port Object at e11ba040 - Name='/SeRmCommandPort' created by System
关于LPC的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
cc682/NetRoc
http://netroc682.spaces.live.com/
!iovirp 扩展显示指定的I/O Verifier IRP 的详细信息。
!iovirp [IRP]
IRP
指定被驱动程序验证器(Driver Verifier)跟踪的IRP的地址。如果IRP 为0或省略,则显示每个未完成IRP的摘要信息。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
下面是该扩展输出的示例:
kd> !iovirp 947cef68
IovPacket 84509af0
TrackedIrp 947cef68
HeaderLock 84509d61
LockIrql 0
ReferenceCount 1
PointerCount 1
HeaderFlags 00000000
ChainHead 84509af0
Flags 00200009
DepartureIrql 0
ArrivalIrql 0
StackCount 1
QuotaCharge 00000000
QuotaProcess 0
RealIrpCompletionRoutine 0
RealIrpControl 0
RealIrpContext 0
TopStackLocation 2
PriorityBoost 0
LastLocation 0
RefTrackingCount 0
SystemDestVA 0
VerifierSettings 84509d08
pIovSessionData 84509380
Allocation Stack:
nt!IovAllocateIrp+1a (817df356)
nt!IopXxxControlFile+40c (8162de20)
nt!NtDeviceIoControlFile+2a (81633090)
nt!KiFastCallEntry+164 (81513c64)
nt!EtwpFlushBuffer+10f (817606d7)
nt!EtwpFlushBuffersWithMarker+bd (817608cb)
nt!EtwpFlushActiveBuffers+2b4 (81760bc2)
nt!EtwpLogger+213 (8176036f)
任何时候通过按下CTRL+BREAK (WinDbg) 或者CTRL+C (KD)都可以中止命令。
!ipi 扩展显示指定处理器的跨处理器中断(interprocessor interrupt (IPI))状态。
!ipi [Processor]
Processor
指定一个处理器。如果省略Processor,则显示所有处理器的 IPI 状态。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该扩展只能对x86目标机使用。
下面是命令输出的示例:
0: kd> !ipi
IPI State for Processor 0
Worker Routine: nt!KiFlushTargetMultipleTb [Stale]
Parameter[0]: 0
Parameter[1]: 3
Parameter[2]: F7C98770
Ipi Trap Frame: F7CCCCDC [.trap F7CCCCDC]
Signal Done: 0
IPI Frozen: 24 [FreezeActive] [Owner]
Request Summary: 0
Target Set: 0
Packet Barrier: 0
IPI State for Processor 1
Worker Routine: nt!KiFlushTargetMultipleTb [Stale]
Parameter[0]: 1
Parameter[1]: 3
Parameter[2]: F7CDCD28
Ipi Trap Frame: F7C8CCC4 [.trap F7C8CCC4]
Signal Done: 0
IPI Frozen: 2 [Frozen]
Request Summary: 0
Target Set: 0
Packet Barrier: 0
关于IPI的信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!irp 扩展显示某个I/O请求包(IRP)的信息。
!irp Address [Detail]
Address
指定IRP的16进制地址。
Detail
如果该参数包含了任何值,例如1,则输出重包含IRP的状态、内存描述符表(memory descriptor list (MDL))的地址、拥有者线程、它的所有I/O栈的堆栈信息、以及每个IRP堆栈位置的信息,包括主功能代码(major function code)和次功能代码(minor function code)的16进制数值。如果省略该参数,则只显示摘要信息。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
下面这些信息有助于理解该扩展命令输出的内容。
IRP 主功能代码有下面这些:
Major Function Code |
16进制代码 |
IRP_MJ_CREATE |
0x00 |
IRP_MJ_CREATE_NAMED_PIPE |
0x01 |
IRP_MJ_CLOSE |
0x02 |
IRP_MJ_READ |
0x03 |
IRP_MJ_WRITE |
0x04 |
IRP_MJ_QUERY_INFORMATION |
0x05 |
IRP_MJ_SET_INFORMATION |
0x06 |
IRP_MJ_QUERY_EA |
0x07 |
IRP_MJ_SET_EA |
0x08 |
IRP_MJ_FLUSH_BUFFERS |
0x09 |
IRP_MJ_QUERY_VOLUME_INFORMATION |
0x0A |
IRP_MJ_SET_VOLUME_INFORMATION |
0x0B |
IRP_MJ_DIRECTORY_CONTROL |
0x0C |
IRP_MJ_FILE_SYSTEM_CONTROL |
0x0D |
IRP_MJ_DEVICE_CONTROL |
0x0E |
IRP_MJ_INTERNAL_DEVICE_CONTROL |
0x0F |
IRP_MJ_SHUTDOWN |
0x10 |
IRP_MJ_LOCK_CONTROL |
0x11 |
IRP_MJ_CLEANUP |
0x12 |
IRP_MJ_CREATE_MAILSLOT |
0x13 |
IRP_MJ_QUERY_SECURITY |
0x14 |
IRP_MJ_SET_SECURITY |
0x15 |
IRP_MJ_POWER |
0x16 |
IRP_MJ_SYSTEM_CONTROL |
0x17 |
IRP_MJ_DEVICE_CHANGE |
0x18 |
IRP_MJ_QUERY_QUOTA |
0x19 |
IRP_MJ_SET_QUOTA |
0x1A |
IRP_MJ_PNP |
0x1B |
即插即用(Plug and Play) 次功能代码有下面这些:
Minor Function Code |
16进制代码 |
IRP_MN_START_DEVICE |
0x00 |
IRP_MN_QUERY_REMOVE_DEVICE |
0x01 |
IRP_MN_REMOVE_DEVICE |
0x02 |
IRP_MN_CANCEL_REMOVE_DEVICE |
0x03 |
IRP_MN_STOP_DEVICE |
0x04 |
IRP_MN_QUERY_STOP_DEVICE |
0x05 |
IRP_MN_CANCEL_STOP_DEVICE |
0x06 |
IRP_MN_QUERY_DEVICE_RELATIONS |
0x07 |
IRP_MN_QUERY_INTERFACE |
0x08 |
IRP_MN_QUERY_CAPABILITIES |
0x09 |
IRP_MN_QUERY_RESOURCES |
0x0A |
IRP_MN_QUERY_RESOURCE_REQUIREMENTS |
0x0B |
IRP_MN_QUERY_DEVICE_TEXT |
0x0C |
IRP_MN_FILTER_RESOURCE_REQUIREMENTS |
0x0D |
IRP_MN_READ_CONFIG |
0x0F |
IRP_MN_WRITE_CONFIG |
0x10 |
IRP_MN_EJECT |
0x11 |
IRP_MN_SET_LOCK |
0x12 |
IRP_MN_QUERY_ID |
0x13 |
IRP_MN_QUERY_PNP_DEVICE_STATE |
0x14 |
IRP_MN_QUERY_BUS_INFORMATION |
0x15 |
IRP_MN_DEVICE_USAGE_NOTIFICATION |
0x16 |
IRP_MN_SURPRISE_REMOVAL |
0x17 |
IRP_MN_QUERY_LEGACY_BUS_INFORMATION |
0x18 |
WMI次功能代码有:
Minor Function Code |
16进制代码 |
IRP_MN_QUERY_ALL_DATA |
0x00 |
IRP_MN_QUERY_SINGLE_INSTANCE |
0x01 |
IRP_MN_CHANGE_SINGLE_INSTANCE |
0x02 |
IRP_MN_CHANGE_SINGLE_ITEM |
0x03 |
IRP_MN_ENABLE_EVENTS |
0x04 |
IRP_MN_DISABLE_EVENTS |
0x05 |
IRP_MN_ENABLE_COLLECTION |
0x06 |
IRP_MN_DISABLE_COLLECTION |
0x07 |
IRP_MN_REGINFO |
0x08 |
IRP_MN_EXECUTE_METHOD |
0x09 |
电源管理的次功能代码有:
Minor Function Code |
16进制代码 |
IRP_MN_WAIT_WAKE |
0x00 |
IRP_MN_POWER_SEQUENCE |
0x01 |
IRP_MN_SET_POWER |
0x02 |
IRP_MN_QUERY_POWER |
0x03 |
SCSI 次功能代码有:
Minor Function Code |
16进制代码 |
IRP_MN_SCSI_CLASS |
0x01 |
输出中还指出了当每个stack location当IRP完成或者stack location被处理时,在什么情况下完成例程会被调用。有三种可能的情况:
Success
表示当IRP以成功代码完成时完成例程会被调用。
Error
表示当IRP以错误代码完成时,完成例程会被调用 。
Cancel
表示当尝试cancel该IRP时完成里程会被调用。
可能会出现上面三个的任何组合形式,只要满足其中一种条件,那么完成例程都会被调用。适当的值会在每个stack location信息的第一行末尾列出,紧跟Completion-Context 之后。
下面是该扩展命令在Windows XP上的输出示例:
!irp 81183468
Irp is active with 2 stacks 2 is current (= 0x811834fc)
No Mdl Thread 00000000: Irp stack trace.
Cmd flg cl Device File Completion-Context
[ 0, 0] 0 0 8145f470 00000000 00000000-00000000
/Driver/E100B
Args: 00000000 00000000 00000000 00000000
[ 16, 2] 0 e1 8145f470 00000000 8047f744-814187a8 Success Error Cancel pending
/Driver/E100B ntoskrnl!PopCompleteSystemPowerIrp
Args: 00000000 00000000 00000002 00000002
在Windows XP示例的第二个stack location处, 主功能代码 是16,说明该IRP是发送给power stack的。次功能代码是2,所以power stack 知道它是一个set 请求。该IRP被pending,并且当它完成时,不管指定的返回值是Success还是Error,ntoskrnl!PopCompleteSystemPowerIrp 都会被调用。
下面是该扩展命令在Windows Vista上的输出示例:
0: kd> !irp 0x831f4a00
Irp is active with 8 stacks 5 is current (= 0x831f4b00)
Mdl = 82b020d8 Thread 8c622118: Irp stack trace.
cmd flg cl Device File Completion-Context
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
>[ 3,34] 40 e1 828517a8 00000000 842511e0-00000000 Success Error Cancel pending
/Driver/disk partmgr!PmReadWriteCompletion
Args: 00007000 00000000 fe084e00 00000004
[ 3, 0] 40 e0 82851450 00000000 842414d4-82956350 Success Error Cancel
/Driver/PartMgr volmgr!VmpReadWriteCompletionRoutine
Args: 129131bb 000000de fe084e00 00000004
[ 3, 0] 0 e0 82956298 00000000 847eeed0-829e2ba8 Success Error Cancel
/Driver/volmgr Ntfs!NtfsMasterIrpSyncCompletionRoutine
Args: 00007000 00000000 1bdae400 00000000
[ 3, 0] 0 0 82ac2020 8e879410 00000000-00000000
/FileSystem/Ntfs
Args: 00007000 00000000 00018400 00000000
注意驱动名边上的完成例程是设置在该stack location上的,并且它是被下一行的驱动设置的。上面的例子中, Ntfs!NtfsMasterIrpSyncCompletionRoutine 是由/FileSystem/Ntfs设置的。 Ntfs!NtfsMasterIrpSyncCompletionRoutine上面的Completion-Context为 847eeed0-829e2ba8,指示了该完成例程的地址以及将会传递给Ntfs!NtfsMasterIrpSyncCompletionRoutine的context。从这里我们可以知道Ntfs!NtfsMasterIrpSyncCompletionRoutine 的地址是847eeed0,将会被传递给它的context为 829e2ba8。
查看Plug and Play 调试以及调试Interrupt Storms获得该扩展命令的应用。关于IRP的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。关于主功能代码和次功能代码的更多信息,查看Windows Driver Kit (WDK)文档。
!irpfind 显示当前目标系统中已分配的,或者符合指定搜索条件的I/O请求包(IRP)的信息。
Windows NT 4.0的语法
!irpfind [PoolType]
Windows 2000的语法
!irpfind [PoolType [RestartAddress [Criteria Data]]]
Windows XP and later的语法
!irpfind [-v] [PoolType [RestartAddress [Criteria Data]]]
-v
(Windows XP和之后) 显示详细信息。
PoolType
指定要搜索的池的类型。可以指定下面这些值:
0
指定非分页内存池(nonpaged memory pool)。这是默认值。
1
指定分页内存池(paged memory pool)。
2
指定特殊池(special pool)。
4
(Windows XP和之后) 指定会话池(session pool)。
4, 5, 6
(仅Windows NT 4.0) 和0, 1, 2一样,但是显示详细信息。
RestartAddress
指定搜索开始位置的16进制地址。这在前面的搜索提前终止时游泳。默认值为0。
Criteria
指定搜索条件。只有满足给定条件的IRP才会显示出来。
条件 |
匹配 |
arg |
查找所有某个stack location具有等于Data的参数的IRP。 |
device |
查找某个stack location的DeviceObject等于Data 的所有IRP。 |
fileobject |
查找Irp.Tail.Overlay.OriginalFileObject 等于Data的IRP。 |
mdlprocess |
查找Irp.MdlAddress.Process 等于Data的IRP。 |
thread |
查找Irp.Tail.Overlay.Thread 等于Data的IRP。 |
userevent |
查找 Irp.UserEvent 等于Data的IRP。 |
Data
指定搜索的匹配项。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
下面的例子查找完成时会设置FF9E4F48 用户事件的,在非分页池中的IRP:
kd> !irpfind 0 0 userevent ff9e4f48
下面的命令列出所有非分页池中的IRP:
kd> !irpfind
Searching NonPaged pool (8090c000 : 8131e000) for Tag: Irp
8097c008 Thread 8094d900 current stack belongs to /Driver/symc810
8097dec8 Thread 8094dda0 current stack belongs to /FileSystem/Ntfs
809861a8 Thread 8094dda0 current stack belongs to /Driver/symc810
809864e8 Thread 80951ba0 current stack belongs to /Driver/Mouclass
80986608 Thread 80951ba0 current stack belongs to /Driver/Kbdclass
80986728 Thread 8094dda0 current stack belongs to /Driver/symc810
查看Plug and Play 调试获取该扩展命令的应用。关于IRP的更多信息,查看Windows Driver Kit (WDK)文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!irpzone 扩展命令已经废除,使用 !irpfind 来替代。
!irql 扩展显示目标机在调试器中断之前某个处理器的中断请求级别(interrupt request level (IRQL))。
!irql [Processor]
Processor
指定处理器。输入处理器号。如果省略该参数,调试器显示当前处理器的IRQL。
!irql 扩展仅在Windows Server 2003和之后的Windows版本中可用。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP |
不可用 |
Windows Server 2003和之后 |
Kdexts.dll |
当目标机中断到调试器时IRQL会改变,但是调试器中断之前的IRQL会被保存下来。!irql 扩展会显示这个被保存的 IRQL。
类似的,当发生bug check并且创建dump文件时,dump文件中会保存bug check之前的IRQL,而不是KeBugCheckEx 例程执行时的。
两种情况下,除了x86架构上之外,当前IRQL都会被提升到DISPATCH_LEVEL。因此,如果不止一个这样的事件发生,那么显示出来的IRQL会是DISPATCH_LEVEL,这样对调试问题就没有用处了。
!pcr 扩展命令可以在所有Windows版本上显示当前IRQL,但是当前IRQL一般都是无用的。Bug check或者调试器连接之前的IRQL要更加有用一点,而它只能用!irql显示出来。
如果指定了非法的处理器号,或者内核被破坏了,调试器会显示"Cannot get PRCB address"的信息。
下面是该扩展在一个双处理器的x86计算机上的输出示例:
kd> !irql 0
Debugger saved IRQL for processor 0x0 -- 28 (CLOCK2_LEVEL)
kd> !irql 1
Debugger saved IRQL for processor 0x1 -- 0 (LOW_LEVEL)
如果调试器在详细模式(verbose mode)下,则还会显示IRQL本身的说明。下面是一个在Itanium处理器上的示例 :
kd> !irql
Debugger saved IRQL for processor 0x0 -- 12 (PC_LEVEL) [Performance counter level]
IRQL数字的意义通常由处理器决定。这里是一个x64 处理器的例子。注意IRQL数字和上面的例子一样,但是该IRQL的含义是不同的:
kd> !irql
Debugger saved IRQL for processor 0x0 -- 12 (SYNCH_LEVEL) [Synchronization level]
关于IRQL的信息,查看Windows Driver Kit (WDK)文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!isainfo 显示PNPISA卡或者系统中存在的设备的信息。
!isainfo [Card]
Card
指定一个PNPISA卡。如果 Card为0或者省略,则显示PNPISA (即PC I/O)总线上所有设备和卡。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
下面是该扩展输出的示例:
0: kd> !isainfo
ISA PnP FDO @ 0x867b9938, DevExt @ 0x867b99f0, Bus # 0
Flags (0x80000000) DF_BUS
ISA PnP PDO @ 0x867B9818, DevExt @ 0x86595388
Flags (0x40000818) DF_ENUMERATED, DF_ACTIVATED,
DF_REQ_TRIMMED, DF_READ_DATA_PORT
!isr 扩展显示指定地址处的Itanium中断状态寄存器(Interruption Status Register (ISR))。
!isr Expression [DisplayLevel]
Expression
指定要显示的ISR寄存器的16进制地址。也可以使用@isr表达式作为该参数。这种情况下,显示当前处理器的ISR寄存器信息。
DisplayLevel
可以是下面这些选项之一:
0
仅显示每个ISR字段的值。这是默认值。
1
显示非保留和非忽略的ISR字段的详细信息。
2
显示ISR的所有字段,包括被忽略或被保留的那些。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该扩展命令只能对Itanium目标机使用。
下面是命令输出的示例:
kd> !isr @isr
isr:ed ei so ni ir rs sp na r w x vector code
0 0 0 0 0 0 0 0 0 0 0 0 0
kd> !isr @isr 2
cod : 0 : interruption Code
vec : 0 : IA32 exception vector number
rv : 0 : reserved0
x : 0 : eXecute exception
w : 0 : Write exception
r : 0 : Read exception
na : 0 : Non-Access exception
sp : 0 : Speculative load exception
rs : 0 : Register Stack
ir : 0 : Invalid Register frame
ni : 0 : Nested Interruption
so : 0 : IA32 Supervisor Override
ei : 0 : Exception IA64 Instruction
ed : 0 : Exception Deferral
rv : 0 : reserved1
!ivt 扩展显示Itanium中断向量表(interrupt vector table)。
!ivt [-v] [-a] [Vector]
!ivt -?
Vector
指定当前处理器的中断向量表条目。如果省略Vector,则显示目标机当前处理器的整个中断向量表。如果没有使用-a选项,那么未赋值的中断向量不会显示出来。
-a
显示所有中断向量,包括未赋值的那些。
-v
显示详细输出。
-?
在调试器命令窗口中显示帮助文本。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该扩展命令只能在Itanium目标机上使用。
下面是命令输出的示例:
kd> !ivt
Dumping IA64 IVT:
00:e000000083005f60 nt!KiPassiveRelease
0f:e000000083576830 hal!HalpPCIISALine2Pin
10:e0000000830067f0 nt!KiApcInterrupt
20:e000000083006790 nt!KiDispatchInterrupt
30:e000000083576b30 hal!HalpCMCIHandler
31:e000000083576b20 hal!HalpCPEIHandler
41:e000000085039680 i8042prt!I8042KeyboardInterruptService (KINTERRUPT e000000085039620)
51:e000000085039910 i8042prt!I8042MouseInterruptService (KINTERRUPT e0000000850398b0)
61:e0000000854484f0 VIDEOPRT!pVideoPortInterrupt (KINTERRUPT e000000085448490)
71:e0000000856c9450 NDIS!ndisMIsr (KINTERRUPT e0000000856c93f0)
81:e0000000857fd000 SCSIPORT!ScsiPortInterrupt (KINTERRUPT e0000000857fcfa0)
91:e0000000857ff510 atapi!IdePortInterrupt (KINTERRUPT e0000000857ff4b0)
a1:e0000000857d84b0 atapi!IdePortInterrupt (KINTERRUPT e0000000857d8450)
a2:e0000165fff2cab0 portcls!CInterruptSyncServiceRoutine (KINTERRUPT e0000165fff2ca50)
b1:e0000000858c7460 ACPI!ACPIInterruptServiceRoutine (KINTERRUPT e0000000858c7400)
b2:e0000000850382e0 USBPORT!USBPORT_InterruptService (KINTERRUPT e000000085038280)
d0:e0000000835768d0 hal!HalpClockInterrupt
e0:e000000083576850 hal!HalpIpiInterruptHandler
f0:e0000000835769c0 hal!HalpProfileInterrupt
f1:e000000083576830 hal!HalpPCIISALine2Pin
fd:e000000083576b10 hal!HalpMcRzHandler
fe:e000000083576830 hal!HalpPCIISALine2Pin
关于如何显示x64和x86目标机上的中断分配表(interrupt dispatch table) ,查看!idt。
cc682/NetRoc
http://netroc682.spaces.live.com/
!gbl 扩展显示目标机的ACPI BIOS 根系统描述表(ACPI BIOS Root System Description (RSDT) table)的头信息。
!gbl [-v]
-v
详细输出。显示表中的详细信息。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
关于ACPI和ACPI表的更多信息,查看其他ACPI调试扩展以及 ACPI Specification站点。也可以查看Microsoft Windows SDK文档、Windows Driver Kit (WDK)文档、以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!gentable 扩展显示某个RTL_GENERIC_TABLE 。
Windows 2000中的语法
!gentable Address
Windows XP和之后的语法
!gentable Address [Flag]
Address
指定RTL_GENERIC_TABLE的地址。
Flag
(Windows XP 和之后) 指定表的来源。如果Flag 是1,则使用AVL表,如果Flag 为0或者省略,则使用non-AVL 表。在Windows 2000中,总是使用non-AVL表。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
!hidppd 扩展显示HIDP_PREPARSED_DATA 结构的内容。
!hidppd Address
Address
指定HIDP_PREPARSED_DATA 结构的16进制地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
关于human input devices (HID)的信息,查看Windows Driver Kit (WDK) 文档。
!ib、 !id、和 !iw 命令已经废除。使用ib, id, iw (Input from Port)命令替代。
!icpleak 扩展在系统中查找队列中条目个数最大的I/O completion对象。
!icpleak [HandleFlag]
HandleFlag
如果设置了该标志,则还会显示拥有该最大的队列条目个数的对象句柄的所有进程。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该扩展在I/O completion池存在泄漏的情况下很有用。I/O completion pool 泄露在进程调用PostQueuedCompletionStatus 分配I/O completion packet,但是又没有调用GetQueuedCompletionStatus 来释放,或者进程将completion entries排队到某个端口,但是又没有任何线程会取出这些entries时就会发生。通过运行!poolused 扩展并且检查ICP pool tag的值来发现泄露。如果有使用ICP tag的池(pool),那么就可能发生了泄露。
该扩展只有在系统维护了类型列表(type lists)时才能工作。如果设置了HandleFlag并且系统中有很多进程,则可能需要运行很长时间。
可以按下CTRL+BREAK (WinDbg中) 或者CTRL+C (KD中)来中止命令。
关于I/O完成端口( I/O completion port)的信息,查看Mark Russinovich 和David Solomon编写的 Microsoft Windows Internals。
!idt 扩展显示指定的中断分配表(interrupt dispatch table (IDT))中的中断服务例程(interrupt service routine (ISR))。
!idt IDT
!idt [-a]
!idt -?
IDT
指定要显示的IDT。
-a
没有指定IDT 时,会以简短的格式显示目标机上所有处理器的IDT。如果指定了-a ,则显示所有IDT的ISR。
-?
在调试器命令窗口中显示该命令的帮助文本。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该扩展命令只能对x64或者x86目标机使用。
下面是该扩展命令的示例:
0: kd> !idt
Dumping IDT:
37:806ba78c hal!PicSpuriousService37
3d:806bbc90 hal!HalpApcInterrupt
41:806bbb04 hal!HalpDispatchInterrupt
50:806ba864 hal!HalpApicRebootService
63:8641376c VIDEOPRT!pVideoPortInterrupt (KINTERRUPT 86413730)
73:862aa044 portcls!CInterruptSyncServiceRoutine (KINTERRUPT 862aa008)
82:86594314 atapi!IdePortInterrupt (KINTERRUPT 865942d8)
83:86591bec SCSIPORT!ScsiPortInterrupt (KINTERRUPT 86591bb0)
92:862b53dc serial!SerialCIsrSw (KINTERRUPT 862b53a0)
93:86435844 i8042prt!I8042KeyboardInterruptService (KINTERRUPT 86435808)
a3:863b366c i8042prt!I8042MouseInterruptService (KINTERRUPT 863b3630)
a4:8636bbec USBPORT!USBPORT_InterruptService (KINTERRUPT 8636bbb0)
b1:86585bec ACPI!ACPIInterruptServiceRoutine (KINTERRUPT 86585bb0)
b2:863c0524 serial!SerialCIsrSw (KINTERRUPT 863c04e8)
b4:86391a54 NDIS!ndisMIsr (KINTERRUPT 86391a18)
USBPORT!USBPORT_InterruptService (KINTERRUPT 863ae890)
c1:806ba9d0 hal!HalpBroadcastCallService
d1:806b9dd4 hal!HalpClockInterrupt
e1:806baf30 hal!HalpIpiHandler
e3:806baca8 hal!HalpLocalApicErrorService
fd:806bb460 hal!HalpProfileInterrupt
关于ISR和IDT的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
关于如何显示Itanium目标机上的中断向量表(interrupt vector table),查看!ivt。
!ih 显示指定处理器上的中断历史纪录。
!ih Processor
Processor
指定某个处理器。如果省略Processor ,则使用当前处理器。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该命令只能对Itanium目标机使用。
该扩展在不涉及程序计数器符号(program counter symbols)的情况下显示中断历史纪录。要使用程序计数器符号来显示中断历史纪录,使用!ihs扩展。在引导入口选项中添加/configflag=32来启用中断历史纪录。
下面是该命令输出的示例:
kd> !ih
Total # of interruptions = 2093185
Vector IIP IPSR ExtraField
VHPT FAULT e0000000830d3190 1010092a6018 IFA= 6fc00a0200c
VHPT FAULT e0000000830d33d0 1010092a6018 IFA= 1ffffe00001de2d0
VHPT FAULT e0000000830d33d0 1010092a6018 IFA= 1ffffe01befff338
VHPT FAULT e0000000830d3190 1010092a6018 IFA= 6fc00a0200c
VHPT FAULT e0000000830d33d0 1010092a6018 IFA= 1ffffe00001d9188
VHPT FAULT e0000000830d3880 1010092a6018 IFA= 1ffffe01befff250
VHPT FAULT e0000000830d3fb0 1010092a6018 IFA= e0000165f82dc1c0
VHPT FAULT e000000083063390 1010092a6018 IFA= e0000000fffe0018
THREAD SWITCH e000000085896040 e00000008588c040 OSP= e0000165f82dbd40
VHPT FAULT e00000008329b130 1210092a6018 IFA= e0000165f7edaf30
VHPT FAULT e0000165f7eda640 1210092a6018 IFA= e0000165fff968a9
PROCESS SWITCH e0000000818bbe10 e000000085896040 OSP= e0000165f8281de0
VHPT FAULT e00000008307cfc0 1010092a2018 IFA= e00000008189fe50
EXTERNAL INTERRUPT e0000000830623b0 1010092a6018 IVR= d0
VHPT FAULT e00000008314e310 1010092a2018 IFA= e0000165f88203f0
VHPT FAULT e000000083580760 1010092a2018 IFA= e0000000f00ff3fd
PROCESS SWITCH e00000008558c990 e0000000818bbe10 OSP= e00000008189fe20
VHPT FAULT e00000008307cfc0 1010092a2018 IFA= e0000165f02433f0
VHPT FAULT 77cfbda0 1013082a6018 IFA= 77cfbda0
VHPT FAULT 77cfbdb0 1213082a6018 IFA= 6fbfee0ff98
DATA ACCESS BIT 77b8e150 1213082a6018 IFA= 77c16ab8
VHPT FAULT 77ed5d60 1013082a6018 IFA= 6fbfffa6048
DATA ACCESS BIT 77ed5d60 1213082a6018 IFA= 77c229c0
DATA ACCESS BIT 77b8e1b0 1013082a6018 IFA= 77c1c320
USER SYSCALL 77cafa40 10082a6018 Num= 42
VHPT FAULT e00000008344dc20 1010092a6018 IFA= e000010600703784
...
!ihs 扩展使用程序计数器符号(program counter symbols)来显示指定处理器的中断历史纪录。
!ihs Processor
Processor
指定某个处理器。如果省略Processor ,则使用当前处理器。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该命令只能对Itanium目标机使用。
使用!ih 扩展在不引用程序计数器符号的情况下显示中断历史纪录。在引导入口选项中添加/configflag=32来启用中断历史纪录。
下面是该扩展命令的输出示例:
kd> !ihs
Total # of interruptions = 2093185
Vector IIP IPSR ExtraField IIP Symbol
VHPT FAULT e0000000830d3190 1010092a6018 IFA= 6fc00a0200c nt!MiAgeAndEstimateAvailableInWorkingSet+0x70
VHPT FAULT e0000000830d33d0 1010092a6018 IFA= 1ffffe00001de2d0 nt!MiAgeAndEstimateAvailableInWorkingSet+0x2b0
VHPT FAULT e0000000830d33d0 1010092a6018 IFA= 1ffffe01befff338 nt!MiAgeAndEstimateAvailableInWorkingSet+0x2b0
VHPT FAULT e0000000830d3190 1010092a6018 IFA= 6fc00a0200c nt!MiAgeAndEstimateAvailableInWorkingSet+0x70
VHPT FAULT e0000000830d33d0 1010092a6018 IFA= 1ffffe00001d9188 nt!MiAgeAndEstimateAvailableInWorkingSet+0x2b0
VHPT FAULT e0000000830d3880 1010092a6018 IFA= 1ffffe01befff250 nt!MiAgeAndEstimateAvailableInWorkingSet+0x760
VHPT FAULT e0000000830d3fb0 1010092a6018 IFA= e0000165f82dc1c0 nt!MiCheckAndSetSystemTrimCriteria+0x190
VHPT FAULT e000000083063390 1010092a6018 IFA= e0000000fffe0018 nt!KeQuerySystemTime+0x30
THREAD SWITCH e000000085896040 e00000008588c040 OSP= e0000165f82dbd40
VHPT FAULT e00000008329b130 1210092a6018 IFA= e0000165f7edaf30 nt!IopProcessWorkItem+0x30
VHPT FAULT e0000165f7eda640 1210092a6018 IFA= e0000165fff968a9 netbios!RunTimerForLana+0x60
PROCESS SWITCH e0000000818bbe10 e000000085896040 OSP= e0000165f8281de0
VHPT FAULT e00000008307cfc0 1010092a2018 IFA= e00000008189fe50 nt!SwapFromIdle+0x1e0
EXTERNAL INTERRUPT e0000000830623b0 1010092a6018 IVR= d0 nt!Kil_TopOfIdleLoop
VHPT FAULT e00000008314e310 1010092a2018 IFA= e0000165f88203f0 nt!KdReceivePacket+0x10
VHPT FAULT e000000083580760 1010092a2018 IFA= e0000000f00ff3fd hal!READ_PORT_UCHAR+0x80
PROCESS SWITCH e00000008558c990 e0000000818bbe10 OSP= e00000008189fe20
VHPT FAULT e00000008307cfc0 1010092a2018 IFA= e0000165f02433f0 nt!SwapFromIdle+0x1e0
VHPT FAULT 77cfbda0 1013082a6018 IFA= 77cfbda0 0x0000000077cfbda0
VHPT FAULT 77cfbdb0 1213082a6018 IFA= 6fbfee0ff98 0x0000000077cfbdb0
DATA ACCESS BIT 77b8e150 1213082a6018 IFA= 77c16ab8 0x0000000077b8e150
VHPT FAULT 77ed5d60 1013082a6018 IFA= 6fbfffa6048 0x0000000077ed5d60
DATA ACCESS BIT 77ed5d60 1213082a6018 IFA= 77c229c0 0x0000000077ed5d60
DATA ACCESS BIT 77b8e1b0 1013082a6018 IFA= 77c1c320 0x0000000077b8e1b0
USER SYSCALL 77cafa40 10082a6018 Num= 42 0x0000000077cafa40
VHPT FAULT e00000008344dc20 1010092a6018 IFA= e000010600703784 nt!ExpLookupHandleTableEntry+0x20
...
!ioresdes 扩展显示指定地址处的IO_RESOURCE_DESCRIPTOR结构。
!ioresdes Address
Address
指定IO_RESOURCE_DESCRIPTOR 结构的16进制地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
查看Plug and Play调试获得该扩展命令的应用。关于IO_RESOURCE_DESCRIPTOR结构的信息,查看 Windows Driver Kit (WDK) 文档。
!ioreslist 扩展显示一个IO_RESOURCE_REQUIREMENTS_LIST结构。
!ioreslist Address
Address
指定IO_RESOURCE_REQUIREMENTS_LIST 结构的16进制地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
下面是该扩展输出的示例:
kd> !ioreslist 0xe122b768
IoResList at 0xe122b768 : Interface 0x5 Bus 0 Slot 0xe
Alternative 0 (Version 1.1)
Preferred Descriptor 0 - Port (0x1) Device Exclusive (0x1)
Flags (0x01) - PORT_IO
0x000100 byte range with alignment 0x000100
1000 - 0x10ff
Alternative Descriptor 1 - Port (0x1) Device Exclusive (0x1)
Flags (0x01) - PORT_IO
0x000100 byte range with alignment 0x000100
0 - 0xffffffff
Descriptor 2 - DevicePrivate (0x81) Device Exclusive (0x1)
Flags (0000) -
Data: : 0x1 0x0 0x0
Preferred Descriptor 3 - Memory (0x3) Device Exclusive (0x1)
Flags (0000) - READ_WRITE
0x001000 byte range with alignment 0x001000
40080000 - 0x40080fff
Alternative Descriptor 4 - Memory (0x3) Device Exclusive (0x1)
Flags (0000) - READ_WRITE
0x001000 byte range with alignment 0x001000
0 - 0xffffffff
Descriptor 5 - DevicePrivate (0x81) Device Exclusive (0x1)
Flags (0000) -
Data: : 0x1 0x1 0x0
Descriptor 6 - Interrupt (0x2) Shared (0x3)
Flags (0000) - LEVEL_SENSITIVE
0xb - 0xb
IO_RESOURCE_REQUIREMENTS_LIST包含这些信息:
有四种类型的资源: I/O、内存、IRQ、DMA。
每个首选设置都有一个"Preferred" 描述符和数个"Alternative"描述符。
资源列表包含下面这些需求:
申请了0x1000 到0x10FF 的范围,但是只要按0x100对齐的话,可以使用从0到0xFFFFFFFF 之间任何0x100 长度的范围,(例如,可以访问0x1100 到0x11FF。)
申请了0x40080000 到0x40080FFF的范围,但是可以使用0到0xFFFFFFFF 之间以0x1000对齐的任何大小为0x1000的范围。
必须使用 IRQ 0xB。
中断和DMA通道是以开始和结束相同的区域的形式。
查看Plug and Play 调试获得该扩展命令的应用。IO_RESOURCE_REQUIREMENTS_LIST结构的信息,查看Windows Driver Kit (WDK)文档。
cc682/NetRoc
http://netroc682.spaces.live.com/
!eb 和!ed 扩展向指定的物理地址写入一系列值。
这些命令不能和e* (Enter Values) 命令混淆。
!eb [Flag] PhysicalAddress Data [ ... ]
!ed [Flag] PhysicalAddress Data [ ... ]
Flag
可以是下面这些值中的一个。Flag 必须包含在中括号中:
[c]
写入已缓冲内存(cached memory)。
[uc]
写入未缓冲内存(uncached memory)。
[wc]
写入写聚合内存(write-combined memory)。
PhysicalAddress
指定在目标机物理内存中要写入的开始地址,以16进制。
Data
指定要连续写入物理内存的一个或多个值。以16进制输入这些值。对于!eb 扩展,每个值都必须是1字节(两个16进制数字)。对于!ed 扩展,每个值都必须是一个DWRODe(8个16进制数字)。一行中可以包含任意数量的 Data 值。使用逗号或者空格分隔多个值。
Windows NT 4.0 |
Kext.dll |
Windows 2000 |
Kext.dll |
Windows XP和之后 |
Kext.dll |
使用!d* 扩展来读取物理内存。内存操作的概述和其他内存相关命令的描述,查看 读写内存。
!ecb、!ecd和!ecw 扩展向PCI配置空间(PCI configuration space)进行写入。
!ec Bus.Device.Function Offset Data
Bus
指定总线。Bus可以从0到0xFF。
Device
指定设备的插槽设备号(slot device number)。
Function
指定设备的插槽功能号(slot function number)。
Offset
指定要写入的地址。
Data
要写入的数据。对于!ecb 扩展,Data 必须是1字节(两个16进制数字)。对于!ecw 扩展,Data 必须是WORD(4个16进制数字)。 对于!ecd 扩展,Data 必须是DWORD (8个16进制数字)。
Windows NT 4.0 |
Kext.dll |
Windows 2000 |
Kext.dll |
Windows XP和之后 |
Kext.dll |
这些命令只能对x86目标机使用。
不能用这几个命令来写入一系列Data值。要这样做,只有通过重复使用它们。
使用!pci 100 Bus Device Function来显示PCI配置空间(PCI configuration space)。
查看Plug and Play调试获得该扩展命令的应用,以及更多的例子。关于PCI总线的信息,查看Windows Driver Kit (WDK)文档。
!ecs 扩展已经废弃。要编辑PCI配置空间(PCI configuration space),使用!ecb、 !ecd、或者!ecw。
!errlog 扩展显示I/O系统的错误日志中任何挂起的条目(pending entry)的内容。
!errlog
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
该命令显示I/O系统错误日志中的任何挂起事件(pending event)的信息。这些是通过调用IoWriteErrorLogEntry 函数排队的事件,用来写入系统的事件日志中提供Event Viewer查看。
只有被IoWriteErrorLogEntry 排队但是还没有提交给错误日志的条目会被显示出来。
该命令可以在系统崩溃后用作诊断的辅助,因为它会显示系统崩溃时还没来得及提交给错误日志的那些挂起的错误信息。
关于 IoWriteErrorLogEntry的更多信息,查看Windows Driver Kit (WDK)文档。
!exca 扩展显示PC-Card Interrupt Controller (PCIC) Exchangable Card Architecture (ExCA) registers。
!exca BasePort.SocketNumber
BasePort
指定PCIC的基础端口(base port)。
SocketNumber
指定PCIC的ExCA寄存器的socket number。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kext.dll |
Windows XP和之后 |
Kext.dll |
!exca 扩展仅对x86目标机可用。
!cbreg 扩展可以用来通过地址显示CardBus Socket registers 和CardBus ExCA registers。
!exqueue 扩展显示ExWorkerQueue 工作队列(work queue)中当前被排队的项目列表。
!exqueue [Flags]
Flags
可以是下面这些值的任意组合。默认值为0x0,只显示很有限的信息。
Bit 0 (0x1) |
如果没有设置0x02的话,显示时间和优先级统计。 |
Bit 1 (0x2) |
显示工作队列关联的线程和事件列表,以及它们的等待状态。 |
Bit 2 (0x4) |
显示和工作队列关联的线程列表。如果没有同时使用0x2,则每个线程显示在单独的一行上。如果使用了0x2,每个线程和一个堆栈回溯一起显示。 |
Bit 3 (0x8) |
(Windows XP和之后) 在队列的每个线程的显示中加入返回地址、堆栈指针、以及(在Itanium系统中)bsp寄存器的值。不会显示函数的参数。 |
Bit 4 (0x10) |
只显示临界工作队列(critical work queue)。 |
Bit 5 (0x20) |
只显示被延时工作队列(delayed work queue)。 |
Bit 6 (0x40) |
只显示超临界工作队列(hypercritical work queue)。 |
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
如果Flags 不包含bit 4、5、6,则显示中包括临界工作队列 (critical work queue)、延时工作队列(delayed work queue),以及超临界工作队列(hypercritical work queue)。
下面是该命令输出的示例:
kd> !exqueue
Dumping ExWorkerQueue: 8046A5C0
**** Critical WorkQueue( current = 0 maximum = 1 )
THREAD fe502940 Cid 8.c Teb: 00000000 Win32Thread: 00000000 WAIT
THREAD fe5026c0 Cid 8.10 Teb: 00000000 Win32Thread: 00000000 WAIT
THREAD fe502440 Cid 8.14 Teb: 00000000 Win32Thread: 00000000 WAIT
THREAD fe5021c0 Cid 8.18 Teb: 00000000 Win32Thread: 00000000 WAIT
THREAD fe501020 Cid 8.1c Teb: 00000000 Win32Thread: 00000000 WAIT
**** Delayed WorkQueue( current = 0 maximum = 1 )
THREAD fe501da0 Cid 8.20 Teb: 00000000 Win32Thread: 00000000 WAIT
THREAD fe501b20 Cid 8.24 Teb: 00000000 Win32Thread: 00000000 WAIT
THREAD fe5018a0 Cid 8.28 Teb: 00000000 Win32Thread: 00000000 WAIT
**** HyperCritical WorkQueue( current = 0 maximum = 1 )
THREAD fe501620 Cid 8.2c Teb: 00000000 Win32Thread: 00000000 WAIT
在!exqueue 输出中的重要信息有:
参数 |
含义 |
current |
队列中的运行中线程的数量;即队列中非等待状态的线程数量。 |
maximum |
队列中任何给定时间点允许运行的线程数量。这个一般是由系统中处理器数量决定的。 |
系统会执行任何current 值比maximum 值小的队列中的work item。如果current 大于或等于maximum ,则在有更多的队列中的线程完成执行或者进入等待状态之前,不会有新的work item被执行。该规则当某个CPU密集型work item正在执行并且不会进入等待状态时会延迟系统,因为它会阻止新的work item被执行,即使队列中还有空闲线程。
关于工作者线程的更多信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!filecache 扩展显示系统文件缓存和PTE使用的信息。
!filecache
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
该扩展命令的输出中,每一行都是一个虚拟地址控制块(virtual address control block (VACB))。当命名文件(named file)被映射到VACB中时,还会显示这些文件的名字。如果出现"no name for file" ,则表示该VACB是用于缓存元数据(metadata)的。
下面是在Windows 2000系统上的一个示例:
kd> !filecache
***** Dump file cache******
File Cache Information
Current size 7088 kb
Peak size 11376 kb
loading file cache database...
File cache has 129 valid pages
Usage Summary in KiloBytes (Kb):
Control Valid Standby Dirty Shared Locked PageTables name
80994c08 248 0 0 0 0 0 No Name for File
80995c88 528 0 0 0 0 0 No Name for File
80992a28 120 0 0 0 0 0 No Name for File
80993d28 32 0 0 0 0 0 No Name for File
8098c1e8 8 0 0 0 0 0 mapped_file( SysEvent.Evt )
8091a908 8 0 0 0 0 0 No Name for File
8091d708 16 0 0 0 0 0 No Name for File
80992f08 8 0 0 0 0 0 No Name for File
8098ca48 8 0 0 0 0 0 No Name for File
80949ea8 8 0 0 0 0 0 No Name for File
80992828 16 0 0 0 0 0 No Name for File
8155c688 8 0 0 0 0 0 mapped_file( cmd.exe )
下面是在Windows XP系统上的一个示例:
kd> !filecache
***** Dump file cache******
Reading and sorting VACBs ...
Removed 1811 nonactive VACBs, processing 235 active VACBs ...
File Cache Information
Current size 28256 kb
Peak size 30624 kb
235 Control Areas
Skipping view @ c1040000 - no VACB, but PTE is valid!
Loading file cache database (100% of 131072 PTEs)
SkippedPageTableReads = 44
File cache has 4056 valid pages
Usage Summary (in Kb):
Control Valid Standby/Dirty Shared Locked Name
817da668 4 0 0 0 $MftMirr
8177ae68 304 920 0 0 $LogFile
81776160 188 0 0 0 $BitMap
817cf370 4 0 0 0 $Mft
81776a00 8 0 0 0 $Directory
817cfdd0 4 0 0 0 $Directory
81776740 36 0 0 0 No Name for File
817cf7c8 20 0 0 0 $Directory
817cfb98 304 0 0 0 $Directory
8177be40 16 0 0 0 $Directory
817dadc0 2128 68 0 0 $Mft
817cf008 4 0 0 0 $Directory
817d0258 8 4 0 0 $Directory
817763f8 4 0 0 0 $Directory
...
8173f058 4 0 0 0 $Directory
8173e628 32 0 0 0 $Directory
8173e4c8 32 0 0 0 $Directory
8173da38 4 0 0 0 $Directory
817761f8 4 0 0 0 $Directory
81740530 32 0 0 0 $Directory
8173d518 4 0 0 0 $Directory
817d9560 8 0 0 0 $Directory
8173f868 4 0 0 0 $Directory
8173fc00 4 0 0 0 $Directory
81737278 4 0 0 0 $MftMirr
81737c88 44 0 0 0 $LogFile
81735fa0 48 0 0 0 $Mft
81737e88 188 0 0 0 $BitMap
817380b0 4 0 0 0 $Mft
817399e0 4 0 0 0 $Directory
817382b8 4 0 0 0 $Directory
817388d8 12 0 0 0 No Name for File
81735500 8 0 0 0 $Directory
81718e38 232 0 0 0 default
81735d40 48 20 0 0 SECURITY
81723008 8632 0 0 0 software
816da3a0 24 44 0 0 SAM
8173dfa0 4 0 0 0 $Directory
...
8173ba90 4 0 0 0 $Directory
8170ee30 4 36 4 0 AppEvent.Evt
816223f8 4 0 0 0 $Directory
8170ec28 8 28 4 0 SecEvent.Evt
816220a8 4 0 0 0 $Directory
8170ea20 4 32 4 0 SysEvent.Evt
8170d188 232 0 0 0 NTUSER.DAT
81709f10 8 0 0 0 UsrClass.dat
81708918 232 0 0 0 NTUSER.DAT
81708748 8 0 0 0 UsrClass.dat
816c58f8 12 0 0 0 change.log
815c3880 4 0 0 0 $Directory
81706aa8 4 0 0 0 SchedLgU.Txt
815ba2d8 4 0 0 0 $Directory
815aa5f8 8 0 0 0 $Directory
8166d728 44 0 0 0 Netlogon.log
81701120 8 16 4 0 es.dll
816ff0a8 4 8 4 0 stdole2.tlb
8159a358 4 0 0 0 $Directory
8159da70 4 0 0 0 $Directory
8159c158 4 0 0 0 $Directory
815cb9b0 4 0 0 0 00000001
81779b20 4 0 0 0 $Directory
8159ac20 4 0 0 0 $Directory
815683f8 4 0 0 0 $Directory
81566978 580 0 0 0 NTUSER.DAT
81568460 4 0 0 0 $Directory
815675d8 68 0 0 0 UsrClass.dat
81567640 4 0 0 0 $Directory
...
81515878 4 0 0 0 $Directory
81516870 8 0 0 0 $Directory
8150df60 4 0 0 0 $Directory
...
816e5300 4 0 0 0 $Directory
8152afa0 16 212 0 0 msmsgs.exe
8153bbd8 4 32 0 0 stdole32.tlb
8172f950 488 392 0 0 OBJECTS.DATA
8173e9c0 4 0 0 0 $Directory
814f4538 4 0 0 0 $Directory
81650790 344 48 0 0 INDEX.BTR
814f55f8 4 0 0 0 $Directory
...
814caef8 4 0 0 0 $Directory
8171cd90 1392 36 0 0 system
815f07f0 4 0 0 0 $Directory
814a2298 4 0 0 0 $Directory
81541538 4 0 0 0 $Directory
81585288 28 0 0 0 $Directory
8173f708 4 0 0 0 $Directory
...
8158cf10 4 0 0 0 $Directory
关于文件系统驱动的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon编写的 Microsoft Windows Internals。
!filelock 扩展显示某个文件锁结构(file lock structure)。
Windows NT 4.0 和Windows 2000的语法
!filelock FileLockAddress
Windows XP和之后系统的语法
!filelock FileLockAddress
!filelock ObjectAddress
FileLockAddress
指定文件锁结构的16进制地址。
ObjectAddress
(Windows XP和之后) 指定拥有文件锁的文件对象的16进制地址。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
关于文件对象的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon编写的 Microsoft Windows Internals 。
!fileobj 扩展显示FILE_OBJECT 结构的详细信息。
!fileobj FileObject
FileObject
指定FILE_OBJECT结构的地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kexts.dll |
如果 FILE_OBJECT 结构拥有关联的缓存,!fileobj 会尝试解析并显示缓存信息。
关于文件对象的信息,查看Microsoft Windows SDK文档、Windows Driver Kit (WDK)文档、以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!filetime 扩展将一个64位FILETIME 结构转换成可读的时间形式。
!filetime Time
Time
指定一个64位FILETIME结构。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
下面是该扩展的输出的示例:
kd> !filetime 1c4730984712348
7/26/2004 04:10:18.712 (Pacific Standard Time)
!finddata 扩展显示某个指定的文件对象给定偏移地址处的已缓存数据(cached data)。
!finddata FileObject Offset
FileObject
指定文件对象的地址。
Offset
指定偏移。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
关于缓存管理的信息,查看Microsoft Windows SDK 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
关于其他缓存管理扩展命令的信息,查看!cchelp 命令。
!findfilelockowner 扩展通过在所有线程中检查某个阻塞在IopSynchronousServiceTail 断言上,并且使用文件对象作为参数的线程,来查找该文件对象的所有者。
!findfilelockowner [FileObject]
FileObject
指定文件对象的地址。如果省略FileObject,则命令搜索当前进程中所有在IopAcquireFileObjectLock 等待的线程并且从堆栈回溯中获得文件对象的地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kexts.dll |
当经历了某次临界区(critical section)超时,并且超时的线程是在IopAcquireFileObjectLock 中等待文件时,该扩展是最有用的。找到这个出问题的线程后,扩展命令会尝试复原该请求的IRP,并且显示正在处理该IRP的驱动程序。
该扩展命令由于要遍历系统中所有线程的调用堆栈,直到找到出问题的线程,所以可能要花费一些时间。可以通过按下CTRL+BREAK (WinDbg中) 或者 CTRL+C (KD中)来中断它。
关于文件对象的信息,查看Microsoft Windows SDK 文档、 Windows Driver Kit (WDK) 文档、以及Mark Russinovich 和David Solomon编写的 Microsoft Windows Internals。
!for_each_process 扩展对目标机中的每个进程执行一次指定的调试器命令。
!for_each_process ["CommandString"]
!for_each_process -?
CommandString
指定要为每个进程执行的调试器命令。
如果CommandString包含多条命令,则需要用分号(;)分隔他们,并且将CommandString包含在引号(")中。如果CommandString 被包含在引号中,则CommandString 中的命令不能包含引号。在CommandString中,@#Process 用来替换成进程的地址。
-?
在调试器命令窗口中显示该扩展的帮助。
该扩展仅在内核模式下使用,即使它是在Ext.dll中的。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP和之后 |
Ext.dll |
如果不提供参数,调试器会列出所有进程,以及时间和优先级统计。这和使用!process @#Process 0 作为CommandString值一样。
To terminate execution at any point, press CTRL+BREAK (in WinDbg) or CTRL+C (in KD).
关于进程的一般信息,查看线程和进程。进程操作和获取进程信息,查看控制进程和线程。
!for_each_thread 扩展对目标机中每个线程执行一次指定的调试器命令。
!for_each_thread ["CommandString"]
!for_each_thread -?
CommandString
指定要为每个线程执行的调试器命令。如果CommandString 包括多条命令,则需要用分号(;)分隔他们,并且将CommandString包含在引号(")中。如果CommandString 被包含在引号中,则CommandString 中的命令不能包含引号。在CommandString中,@# Thread用来替换成线程的地址。
-?
在调试器命令窗口中显示该扩展的帮助。
该扩展仅在内核模式下使用,即使它是在Ext.dll中的。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP和之后 |
Ext.dll |
如果未提供参数,调试器列举所有线程,以及它们的等待状态。这相当于使用!thread @#Thread 2 作为CommandString的值。
可以通过按下CTRL+BREAK (WinDbg中) 或者CTRL+C (KD中)来中止操作。
关于线程的常规信息,查看线程和进程。线程的操作和信息获取,查看控制进程和线程。
!fpsearch 扩展在已释放的特殊池(freed special pool)中搜索指定地址。
!fpsearch [Address] [Flag]
Address
指定一个虚拟地址。
Flag
如果设置,调试器在搜索freed special pool时显示free list中每个页面的原始内容。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
针对每个地址的显示包括虚拟地址、页面帧编号(page frame number (PFN))、pool tag、大小、该地址的数据是否可分页,以及释放该内存时的线程ID和调用堆栈。
如果Address是-1,调试器显示整个freed special pool。
如果调试器在freed special pool中找不到指定地址,则不会显示任何东西。下面是该命令的一个输出示例:
kd> !fpsearch -1 1
Searching the free page list (8 entries) for all freed special pool
1EC4000 04000200 e56b6f54 000001f4 0000059c ....Tok.........
1EC4000 00000800 00000000 00000000 00000000 ................
1EC4000 bad0b0b0 82100000 00000000 00000000 ................
1EC4000 72657355 20203233 0000bac5 00000000 User32 ........
1EC4000 00028b94 00000000 0000bac9 00000000 ................
1EC4000 00000000 00000000 ffffffff 7fffffff ................
1EC4000 8153b1b8 00028aff 00000000 00000000 ..S.............
1EC4000 0000001b 00000000 00000012 00000514 ................
26A2000 000a0008 00adecb0 000e000c 00adecba ................
26A2000 000a0008 00adecc8 000e000c 00adecd2 ................
26A2000 000e000c 00adece0 000e000c 00adecee ................
26A2000 00120010 00adecfc 000e000c 00aded0e ................
26A2000 000e000c 00aded1c 000e000c 00aded2a ............*...
26A2000 000e000c 00aded38 000e000c 00aded46 ....8.......F...
26A2000 000a0008 00aded54 000e000c 00aded5e ....T.......^...
26A2000 00120010 00aded6c 000e000c 00aded7e ....l.......~...
2161000 000a0008 00adeccc 000e000c 00adecd6 ................
2161000 000a0008 00adece4 000e000c 00adecee ................
2161000 000e000c 00adecfc 000e000c 00aded0a ................
2161000 00120010 00aded18 000e000c 00aded2a ............*...
2161000 000e000c 00aded38 000e000c 00aded46 ....8.......F...
2161000 000e000c 00aded54 000e000c 00aded62 ....T.......b...
2161000 000a0008 00aded70 000e000c 00aded7a ....p.......z...
2161000 00120010 00aded88 000e000c 00aded9a ................
...
CEC8000 0311ffa4 03120000 0311c000 00000000 ................
CEC8000 00001e00 00000000 7ff88000 00000000 ................
CEC8000 00000328 00000704 00000000 00000000 (...............
CEC8000 7ffdf000 00000000 00000000 00000000 ................
CEC8000 e18ba8c0 00000000 00000000 00000000 ................
CEC8000 00000000 00000000 00000000 00000000 ................
CEC8000 00000000 00000000 00000000 00000000 ................
CEC8000 00000000 00000000 00000000 00000000 ................
CEAD000 00000000 00000000 00000000 00000000 ................
CEAD000 00000000 00000000 00000000 00000000 ................
CEAD000 00000000 00000000 00000000 00000000 ................
CEAD000 00000000 00000000 00000000 00000000 ................
CEAD000 00000000 00000000 00000000 00000000 ................
CEAD000 00000000 00000000 00000000 00000000 ................
CEAD000 00000000 00000000 00000000 00000000 ................
CEAD000 00000000 00000000 00000000 00000000 ................
可以按下CTRL+BREAK (WinDbg中) 或者CTRL+C (KD中)来中止命令。
!frag 扩展显示目标系统的内存池的碎片信息。
!frag [Flags]
Flags
指定输出级别。可以是下面这些位的任意组合,默认值为0。
Bit 0 (0x1)
对每个索引(index)显示碎片的数量和大小。
Bit 1 (0x2)
显示分配信息。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
如果内存池碎片非常多的话,会降低性能。下面是该命令的输出示例:
kd> !frag 1
NonPaged Pool Fragmentation
index: 0 number of fragments: 4 bytes: 128
index: 1 number of fragments: 0 bytes: 0
index: 2 number of fragments: 2 bytes: 192
index: 3 number of fragments: 0 bytes: 0
...
index: 20 number of fragments: 0 bytes: 0
index: 21 number of fragments: 0 bytes: 0
index: 22 number of fragments: 1 bytes: 7232
index: 23 number of fragments: 0 bytes: 0
index: 24 number of fragments: 0 bytes: 0
Number of fragments: 11 consuming 9344 bytes
NonPagedPool Usage: 1105920 bytes
kd> !frag 2
NonPaged Pool Fragmentation
818718a0 size: 20 previous size: a0 Cc
81870720 size: 20 previous size: 60 Cc
80d1ae80 size: 20 previous size: a0 Cc
818703c0 size: 20 previous size: 60 Cc
80962600 size: 60 previous size: a0 ScsD
8098c180 size: 60 previous size: 100 ScsD
81937680 size: 160 previous size: 40 Lric
81870e00 size: 120 previous size: 20 None
81937d80 size: 260 previous size: 20 Thre
81936000 size: 220 previous size: 0 Proc
81610260 size: 1c40 previous size: 260 à
Number of fragments: 11 consuming 9344 bytes
NonPagedPool Usage: 1105920 bytes
关于内存管理的更多信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!frozen 扩展显示每个处理器的状态。
!frozen
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
下面是该命令的输出示例:
0: kd> !frozen
Processor states:
0 : Current
1 : Frozen
!fwver 扩展显示Itanium固件版本。
!fwver
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该扩展命令只能对Itanium目标机使用。
下面是该扩展的输出示例:
kd> !fwver
Firmware Version
Sal Revision: 0
SAL_A_VERSION: 0
SAL_B_VERSION: 0
PAL_A_VERSION: 6623
PAL_B_VERSION: 6625
smbiosString: W460GXBS2.86E.0117A.P08.200107261041
更多信息,查看Intel架构手册。
cc682/NetRoc
http://netroc682.spaces.live.com/
!defwrites 扩展显示缓存管理器(cache manager)使用到的内核变量的值。
!defwrites
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
当延迟写入("脏页面(dirty pages)")太大时,会造成页面写入减速(throttled)。该扩展命令允许查看是否系统到达了这个点。
下面是一个示例:
kd> !defwrites
*** Cache Write Throttle Analysis ***
CcTotalDirtyPages: 0 ( 0 Kb)
CcDirtyPageThreshold: 1538 ( 6152 Kb)
MmAvailablePages: 2598 ( 10392 Kb)
MmThrottleTop: 250 ( 1000 Kb)
MmThrottleBottom: 30 ( 120 Kb)
MmModifiedPageListHead.Total: 699 ( 2796 Kb)
Write throttles not engaged
这种情况下,没有脏页面。如果CcTotalDirtyPages 到达 1538 (CcDirtyPageThreshold 的值),在脏页面变少之前,写入都会变慢。
关于写入延迟(write throttling)的信息,查看Mark Russinovich and David Solomon 编写的Microsoft Windows Internals。
关于其他缓存管理器扩展的信息,使用!cchelp扩展。
!devext 扩展显示各种总线上的设备的总线相关设备扩展信息(bus-specific device extension information)。
!devext Address TypeCode
Address
指定要显示的设备扩展的16进制地址。
TypeCode
指示拥有要显示的设备扩展的对象类型。类型代码不区分大小写,可能的类型代码如下:
类型代码 |
对象 |
PCI |
(仅Windows 2000) PCI设备扩展(device extension) |
ISAPNP |
ISA PnP设备扩展 |
PCMCIA |
PCMCIA设备扩展 |
HID |
HID 设备扩展 |
USBD |
(仅Windows 2000) USB 总线驱动扩展 |
UHCD |
(仅Windows 2000) UHCD host controller 扩展 |
OpenHCI |
(仅Windows 2000) Open HCI host controller 扩展 |
USBHUB |
(仅Windows 2000) USB hub 扩展 |
MF |
(仅Windows 2000) MF 设备扩展 |
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
!usbhub、 !hidfdo、以及 !hidpdo 扩展命令已经废除,它们的功能被整合到!devext中。
对于!devext不再支持的对象类型,可以使用dt (Display Type) 调试器命令。
下面是一个ISA PnP设备扩展的示例:
kd> !devext e0000165fff32190 ISAPNP
ISA PnP FDO @ 0x00000000, DevExt @ 0xe0000165fff32190, Bus # 196639
Flags (0x854e2530) DF_ACTIVATED, DF_QUERY_STOPPED,
DF_STOPPED, DF_RESTARTED_NOMOVE,
DF_BUS
Unknown flags 0x054e2000
NumberCSNs - -536870912
ReadDataPort - 0x0000000d (mapped)
AddressPort - 0x00000000 (not mapped)
CommandPort - 0x00000000 (not mapped)
DeviceList - 0xe000000085007b50
CardList - 0x00000000
PhysicalBusDevice - 0x00000000
AttachedDevice - 0x00000000
SystemPowerState - Unspecified
DevicePowerState - Unspecified
下面是一个PCI设备的示例:
kd> !devext e0000000858c31b0 PCI
PDO Extension, Bus 0x0, Device 0, Function 0.
DevObj 0xe0000000858c3060 PCI Parent Bus FDO DevExt 0xe0000000858c4960
Device State = PciNotStarted
Vendor ID 8086 (INTEL) Device ID 123D
Class Base/Sub 08/00 (Base System Device/Interrupt Controller)
Programming Interface: 20, Revision: 01, IntPin: 00, Line Raw/Adj 00/00
Enables ((cmd & 7) = 106): BM Capabilities Pointer =
CurrentState: System Working, Device D0
WakeLevel: System Unspecified, Device Unspecified
Requirements:
查看 Plug and Play调试获得该扩展命令的应用。关于设备扩展的更多信息,查看Windows Driver Kit (WDK)文档。
!devnode 扩展显示设备树中的某个节点的信息。
!devnode Address [Flags] [Service]
!devnode 1
!devnode 2
Address
指定要显示节点的设备扩展的16进制地址。如果为0,则显示主设备树的根(the root of the main device tree)。
Flags
指定输出的显示级别。可以是下面这些位的任意组合:
Bit 0 (0x1)
显示该设备节点的所有孩子。
Bit 1 (0x2)
显示使用的资源 (CM_RESOURCE_LIST)。包含IRP_MN_QUERY_RESOURCES 报告的引导配置(boot configuration ),以及为IRP_MN_START_DEVICE 的AllocatedResources参数中的设备分配的资源。
Bit 2 (0x4)
显示中包含IRP_MN_FILTER_RESOURCE_REQUIREMENTS报告的必须的资源(IO_RESOURCE_REQUIREMENTS_LIST)。
Bit 3 (0x8)
显示中包含为IRP_MN_START_DEVICE 的AllocatedResourcesTranslated 参数中的设备分配的已转换资源(translated resources)的列表。
Bit 4 (0x10)
只显示未启动的设备节点。
Bit 5 (0x20)
只显示有问题的设备节点。(包含标志位DNF_HAS_PROBLEM 或DNF_HAS_PRIVATE_PROBLEM的节点)
Service
指定服务的名字。如果包含,则只显示该服务所驱动的设备节点。(如果Flags 包含位0x1,则显示该服务驱动的设备节点以及所有子节点。)
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
!devnode 1 命令显示设备对象的pending removals列表。
!devnode 2 命令列出设备对象的所有pending ejects。
使用!devnode 0 1查看整个设备树。
查看Plug and Play调试获得该扩展命令的应用。关于设备树的更多信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon编写的 Microsoft Windows Internals。
!devobj 扩展显示DEVICE_OBJECT 对象的详细信息。
!devobj DeviceObject
DeviceObject
指定设备对象。在Windows NT 4.0中,必须是DEVICE_OBJECT 结构的16进制地址。在Windows 2000和之后的系统中,可以是该结构的16进制地址或者设备名。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
如果DeviceObject 指定设备名,但是没有提供前缀,则假定使用/Device/前缀。注意命令会在使用表达式求职器之前检查DeviceObject 是否是合法的地址或者设备名。
显示的信息中包含对象的设备名、设备的当前IRP的信息、以及设备的队列中挂起的IRP的地址列表。还包含该对象上层的设备对象(作为"AttachedDevice"列出)的信息,以及在该设备下层的信息(在"AttachedTo"中列出)。
可以使用!drvobj 或!devnode 获得设备对象地址。
下面是一个示例:
kd> !devnode
Dumping IopRootDeviceNode (= 0x80e203b8)
DevNode 0x80e203b8 for PDO 0x80e204f8
Parent 0000000000 Sibling 0000000000 Child 0x80e56dc8
InstancePath is "HTREE/ROOT/0"
State = DeviceNodeStarted (0x308)
Previous State = DeviceNodeEnumerateCompletion (0x30d)
StateHistory[04] = DeviceNodeEnumerateCompletion (0x30d)
StateHistory[03] = DeviceNodeStarted (0x308)
StateHistory[02] = DeviceNodeEnumerateCompletion (0x30d)
StateHistory[01] = DeviceNodeStarted (0x308)
StateHistory[00] = DeviceNodeUninitialized (0x301)
StateHistory[19] = Unknown State (0x0)
.....
StateHistory[05] = Unknown State (0x0)
Flags (0x00000131) DNF_MADEUP, DNF_ENUMERATED,
DNF_IDS_QUERIED, DNF_NO_RESOURCE_REQUIRED
DisableableDepends = 11 (from children)
kd> !devobj 80e204f8
Device object (80e204f8) is for:
/Driver/PnpManager DriverObject 80e20610
Current Irp 00000000 RefCount 0 Type 00000004 Flags 00001000
DevExt 80e205b0 DevObjExt 80e205b8 DevNode 80e203b8
ExtensionFlags (0000000000)
Device queue is not busy.
查看Plug and Play调试获得该扩展命令的应用。关于设备对象的更多信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon编写的 Microsoft Windows Internals。
!devstack 扩展显示设备对象关联的设备栈的格式化后的信息。
!devstack DeviceObject
DeviceObject
指定设备对象。可以是DEVICE_OBJECT 结构的16进制地址或者设备名。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
如果DeviceObject 指定设备名,但是没有提供前缀,则假定使用/Device/前缀。注意命令会在使用表达式求职器之前检查DeviceObject 是否是合法的地址或者设备名。
下面是示例:
kd> !devstack e000000085007b50
!DevObj !DrvObj !DevExt ObjectName
e0000165fff32040 /Driver/kmixer e0000165fff32190
> e000000085007b50 /Driver/swenum e000000085007ca0 KSENUM#00000005
!DevNode e0000165fff2e010 :
DeviceInst is "SW/{b7eafdc0-a680-11d0-96d8-00aa0051e51d}/{9B365890-165F-11D0-A195-0020AFD156E4}"
ServiceName is "kmixer"
关于设备栈的更多信息,查看Windows Driver Kit (WDK) 文档。
!dflink 扩展以前序显示链表。
!dflink Address [Count] [Bias]
Address
指定LIST_ENTRY 结构的地址。从这个节点开始进行显示。
Count
指定要显示的链表成员的最大个数。如果省略,默认值为32。
Bias
指定每个指针要忽略的位的掩码。在跟随到下一个位置之前,每个Flink 地址都会进行AND运算(和NOT Bias)。默认值为0(即不忽略任何位)。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
!dflink 扩展通过LIST_ENTRY 结构的Flink 域进行遍历,并显示每个地址的最多4个ULONG。要用其它方向来遍历,使用!dblink。
dl (Display Linked List) 命令比!dblink 和!dflink更加通用。
!diskspace 扩展显示目标机硬盘的可用空间总数。
!diskspace Drive:
Drive
指定磁盘的盘符。Drive之后的冒号 (:) 可选。
Windows NT 4.0 |
Kext.dll |
Windows 2000 |
Kext.dll |
Windows XP和之后 |
Kext.dll |
示例如下:
kd> !diskspace c:
Checking Free Space for c: ..........
Cluster Size 0 KB
Total Clusters 4192901 KB
Free Clusters 1350795 KB
Total Space 1 GB (2096450 KB)
Free Space 659.567871 MB (675397 KB)
kd> !diskspace f:
Checking Free Space for f:
f: is a CDROM drive. This function is not supported!
!dma 扩展显示直接内存访问(Direct Memory Access (DMA))子系统的信息,以及驱动程序验证器的DMA Verifier 选项。
!dma
!dma Adapter [Flags]
Adapter
指定要显示的DMA适配器的16进制地址。如果是0,则显示所有的DMA适配器。
Flags
指定显示中包含的信息。可以是下面这些位的任意组合。默认值为0x1。
Bit 0 (0x1)
显示一般的适配器信息。
Bit 1 (0x2)
显示映射记录(map register)信息。(仅当DMA Verification激活时。)
Bit 2 (0x4)
显示公共缓冲区(common buffer)信息。 (仅当DMA Verification激活时。)
Bit 3 (0x8)
显示分散/聚合列表(scatter/gather list)信息。 (仅当DMA Verification激活时。)
Bit 4 (0x10)
显示硬件设备的设备描述(device description)。 (仅当DMA Verification激活时。)
Bit 5 (0x20)
显示等待上下文块(Wait context block)的信息。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
使用非法参数(例如,!dma 1)会显示简单的帮助文本。
不带参数使用!dma 扩展时,显示所有DMA适配器和它们的地址的简明列表。这可以用来获得在更长的命令形式中使用的适配器地址。
下面是一个如何在驱动程序验证器的DMA Verification 选项打开时使用该扩展的示例:
0:kd> !dma
Dumping all DMA adapters...
Adapter: 82faebd0 Owner: SCSIPORT!ScsiPortGetUncachedExtension
Adapter: 82f88930 Owner: SCSIPORT!ScsiPortGetUncachedExtension
Adapter: 82f06cd0 Owner: NDIS!NdisMAllocateMapRegisters
Master adapter: 80076800
从输出中,可以看到系统中有三个DMA适配器。SCSIPORT 有两个, NDIS拥有第三个。要查看NDIS适配器的详细信息,可以对它的地址使用!dma:
0:kd> !dma 82f06cd0
Adapter: 82f06cd0 Owner: NDIS!NdisMAllocateMapRegisters (0x9fe24351)
MasterAdapter: 00000000
Adapter base Va 00000000
Map register base: 00000000
WCB: 82f2b604
Map registers: 00000000 mapped, 00000000 allocated, 00000002 max
Dma verifier additional information:
DeviceObject: 82f98690
Map registers: 00000840 allocated, 00000000 freed
Scatter-gather lists: 00000000 allocated, 00000000 freed
Common buffers: 00000004 allocated, 00000000 freed
Adapter channels: 00000420 allocated, 00000420 freed
Bytes mapped since last flush: 000000f2
第一块数据是HAL开发者可以用来调试问题的特定数据。对于自己的情况,"Dma verifier additional information"下面才是感兴趣的数据。在这个例子中,可以看到NDIS分配了0x840个映射记录( map registers)。 这是一个很大的数字,特别是因为NDIS指出了它只需要使用最多2个映射记录。该适配器显然没有用到分散/聚合列表(scatter/gather lists),并且释放了(put away)它所有的adapter channel。查看映射寄存记录更详细的信息:
0:kd> !dma 82f06cd0 2
Adapter: 82f06cd0 Owner: NDIS!NdisMAllocateMapRegisters
...
Map register file 82f06c58 (0/2 mapped)
Double buffer mdl: 82f2c188
Map registers:
82f06c80: Not mapped
82f06c8c: Not mapped
Map register file 82f06228 (1/2 mapped)
Double buffer mdl: 82f1b678
Map registers:
82f06250: 00bc bytes mapped to f83c003c
82f0625c: Not mapped
Map register file 82fa5ad8 (1/2 mapped)
Double buffer mdl: 82f1b048
Map registers:
82fa5b00: 0036 bytes mapped to 82d17102
82fa5b0c: Not mapped
...
例中,可以看到特定的映射记录已经被映射了。每个map register file 是驱动分配的一个映射记录。即,它对应于一次AllocateAdapterChannel 调用。当一些驱动在需要时每次创建一个,并且用完之后又释放掉的情况下,NDIS搜集了大量的这种映射记录文件(map register file)。
映射记录文件也是以"MapRegisterBase"为名字返回给设备的地址。注意DMA验证器仅hook每个驱动的前64个映射记录(map register)。剩下的由于空间原因被忽略掉(每个映射记录对应三个物理页面)。
这个例子中,有两个映射记录文件正在被使用。这意味着驱动已经映射了对硬件可见的缓冲区。对第一个来说,有 0xBC个字节映射到了系统虚拟地址 0xF83C003C。
下面是对公共缓冲区的查看:
0:kd> !dma 82f06cd0 4
Adapter: 82f06cd0 Owner: NDIS!NdisMAllocateMapRegisters
...
Common buffer allocated by NDIS!NdisMAllocateSharedMemory:
Length: 1000
Virtual address: 82e77000
Physical address: 2a77000
Common buffer allocated by NDIS!NdisMAllocateSharedMemory:
Length: 12010
Virtual address: 82e817f8
Physical address: 2a817f8
Common buffer allocated by NDIS!NdisMAllocateSharedMemory:
Length: 4300
Virtual address: 82e95680
Physical address: 2a95680
Common buffer allocated by NDIS!NdisMAllocateSharedMemory:
Length: 4800
Virtual address: 82e9d400
Physical address: 2a9d400
这里是比较清楚直接,有四个不同长度的公共缓冲区。物理地址和虚拟地址也显示出来了。
关于驱动程序验证器的更多信息,查看Windows Driver Kit (WDK) 文档。关于DMA的信息,查看Windows Driver Kit (WDK) 文档以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!dpa 扩展显示池(pool)的分配信息。
!dpa Options
!dpa -?
Options
必须是下面这些选项中的一个:
-c
显示当前的池分配统计。
-v
显示当前所有的池分配。
-vs
显示中包含堆栈回溯。
-f
显示失败的池分配。
-r
显示free pool allocations。
-p Ptr
显示所有包含指针Ptr的池分配。
-?
在调试器命令窗口中显示该扩展的简单帮助文本。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该扩展药工作,必须在Win32k.sys 中启用了pool instrumentation。
!dpcs 扩展显示指定的处理器上的延迟过程调用(DPC)队列。
!dpcs [Processor]
Processor
指定处理器。如果省略Processor ,则显示所有处理器的DPC队列。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
关于DPC的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich and David Solomon 编写的Microsoft Windows Internals。
!driveinfo 扩展显示指定驱动器上的卷信息(volume information)。
!driveinfo Drive[:]
!driveinfo
Drive
指定一个驱动器。驱动器名后面的冒号是可选的。
无参数
在调试器命令窗口中显示简单的帮助文本。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kdexts.dll |
该扩展命令显示的驱动器信息是通过查询基础的文件系统获得的,例如:
kd> !driveinfo c:
Drive c:, DriveObject e136cd88
Directory Object: e1001408 Name: C:
Target String is '/Device/HarddiskVolume1'
Drive Letter Index is 3 (C:)
Volume DevObj: 82254a68
Vpb: 822549e0 DeviceObject: 82270718
FileSystem: /FileSystem/Ntfs
Volume has 0x229236 (free) / 0x2ee1a7 (total) clusters of size 0x1000
8850.21 of 12001.7 MB free
在Windows XP之前的操作系统中,!drivers 扩展命令显示目标机上所有已加载驱动的列表,以及它们的内存使用的摘要信息。
在Windows XP和之后版本的Windows中,!drivers扩展命令已经废除。使用 lm 命令来显示已加载驱动和其他的模块。命令 lm t n显示的信息和旧的!drivers扩展非常类似。
!drivers [Flags]
Flags
可以是下面这些值得任意组合。(默认值为0x0。)
Bit 0 (0x1)
显示常驻(resident)内存和备用(standby)内存的信息。
Bit 1 (0x2)
在Windows NT 4.0中,显示更长更详细的驱动映像列表的信息。包括头信息。如果设置了位2 (0x4),则还包括节信息。
在Windows 2000中,如果设置了该位而第二位 (0x4)未设置,则显示的信息中包括常驻、备用和已锁定内存,以及 加载器入口地址(loader entry address)。如果设置了位2 ,则功能和Windows NT 4.0中一样。
Bit 2 (0x4)
显示驱动映像的更长更详细的信息列表。包括每个节的信息。如果设置了bit 1 (0x2),则还包括头信息。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
不可用 |
该命令显示的说明如下表:
列 |
含义 |
|
Base |
设备驱动代码的16进制起始地址。当造成崩溃的代码的内存地址落在某个驱动的基地址以及列表中下一个驱动的基地址之间时,它一般就是造成错误的驱动。例如,Ncrc810.sys 的基地址是0x80654000。则该地址和0x8065a000之间的任何地址都是属于改驱动的。 |
|
Code Size |
驱动代码的大小,以KB为单位,包括16进制和10进制。 |
|
Data Size |
分配给驱动的数据的总大小,以KB为单位,包括16进制和10进制。 |
|
Locked |
(仅当使用标志0x2 时) 被驱动程序锁定的内存总数。 |
|
Resident |
(仅当使用0x1 或0x2时) 驱动实际驻留在物理内存中的内存大小。 |
|
Standby |
(仅当使用0x1 或0x2时) 备用的驱动内存大小。 |
|
Loader Entry |
(仅当使用标志0x2 时) 加载器入口点(loader entry)的地址。 |
|
Driver Name |
驱动文件名。 |
|
Creation Time |
驱动的链接日期。不要将它和可以被外部工具改变的驱动的文件时间混淆。链接日期是由编译器在驱动或可执行文件编译时设置的。它和文件时间可能比较接近,但不会总是一样的。 |
下面是一个被删节的该命令的示例:
kd> !drivers
Loaded System Driver Summary
Base Code Size Data Size Driver Name Creation Time
80080000 f76c0 (989 kb) 1f100 (124 kb) ntoskrnl.exe Fri May 26 15:13:00
80400000 d980 ( 54 kb) 4040 ( 16 kb) hal.dll Tue May 16 16:50:34
80654000 3f00 ( 15 kb) 1060 ( 4 kb) ncrc810.sys Fri May 05 20:07:04
8065a000 a460 ( 41 kb) 1e80 ( 7 kb) SCSIPORT.SYS Fri May 05 20:08:05
查看Plug and Play 调试获得该扩展命令的应用。关于驱动程序和它们的内存使用的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon编写的 Microsoft Windows Internal。
!drvobj 扩展命令显示DRIVER_OBJECT 的详细信息。
Windows NT 4.0的语法
!drvobj DriverObject
Windows 2000和之后的语法
!drvobj DriverObject [Flags]
DriverObject
指定驱动对象。在Windows NT 4.0中,这必须是 DRIVER_OBJECT 结构的16进制地址。在Windows 2000和之后的系统中,可以是DRIVER_OBJECT的16进制地址或者驱动的名字。
Flags
(Windows 2000和之后) 可以是下面这些位的任意组合。(默认为0x01。)
Bit 0 (0x1)
显示驱动拥有的设备对象。
Bit 1 (0x2)
显示驱动的dispatch例程的入口点。
Bit 2 (0x4)
显示驱动的设备对象的详细信息(需要设置bit 0)。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
如果DriverObject 指定设备名,但是没有带前缀,则假定使用/Driver/ 前缀。注意该命令在使用表达式求值器前会检查DriverObject是否是合法地址或者设备名。
如果DriverObject 是一个地址,它必须是DRIVER_OBJECT结构的地址。这可以通过检查传递给DriverEntry 函数的参数得到。
该扩展命令会显示指定的驱动程序创建的所有设备对象的立标。还会显示该驱动对象注册的所有fast I/O例程。
下面是一个Symbios Logic 810 SCSI 小端口驱动程序的例子:
kd> bp DriverEntry // breakpoint at DriverEntry
kd> g
symc810!DriverEntry+0x40:
80006a20: b07e0050 stl t2,50(sp)
kd> r a0 //address of DevObj (the first parameter)
a0=809d5550
kd> !drvobj 809d5550 // display the driver object
Driver object is for:
/Driver/symc810
Device Object list:
809d50d0
还可以使用!devobj 809d50d0 来获得设备对象的信息。
查看Plug and Play 调试获得该扩展命令的应用。关于驱动对象的信息,查看Windows Driver Kit (WDK)文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internal。
!dskheap 扩展显示指定会话的桌面堆信息(desktop heap information)。
!dskheap [-v] [-s SessionID]
-v
显示更详细的输出。
-s SessionID
指定会话。如果省略该参数,则显示会话0的桌面堆信息。
Windows NT 4.0 |
未使用 |
Windows 2000 |
未使用 |
Windows XP和之后 |
Kdexts.dll |
桌面堆信息是由窗口站(window station) 来维护的。
下面是两个例子:
kd> !dskheap -s 3
Winstation/Desktop Heap Size(KB) Used Rate(%)
------------------------------------------------------------
WinSta0/Screen-saver 3072 0%
WinSta0/Default 3072 0%
WinSta0/Disconnect 64 4%
WinSta0/Winlogon 128 5%
------------------------------------------------------
Total Desktop: ( 6336 KB - 4 desktops)
Session ID: 3
============================================================
kd> !dskheap
Winstation/Desktop Heap Size(KB) Used Rate(%)
------------------------------------------------------------
WinSta0/Default 3072 0%
WinSta0/Disconnect 64 4%
WinSta0/Winlogon 128 9%
Service-0x0-3e7$/Default 512 4%
Service-0x0-3e5$/Default 512 0%
Service-0x0-3e4$/Default 512 1%
SAWinSta/SADesktop 512 0%
------------------------------------------------------
Total Desktop: ( 5312 KB - 7 desktops)
Session ID: 0
============================================================
关于桌面或桌面堆的信息,查看Microsoft Windows SDK 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
cc682/NetRoc
http://netroc682.spaces.live.com/
!ca 扩展命令显示指定的节(section)的控制域(control area)。
!ca Address
Address
指定节的16进制地址。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
要获得所有已映射的文件的控制域列表,可以使用!memusage 扩展。
下面是示例:
kd> !memusage
loading PFN database
loading (99% complete)
Zeroed: 16 ( 64 kb)
Free: 0 ( 0 kb)
Standby: 2642 ( 10568 kb)
Modified: 720 ( 2880 kb)
ModifiedNoWrite: 0 ( 0 kb)
Active/Valid: 13005 ( 52020 kb)
Transition: 0 ( 0 kb)
Unknown: 0 ( 0 kb)
TOTAL: 16383 ( 65532 kb)
Building kernel map
Finished building kernel map
Usage Summary (in Kb):
Control Valid Standby Dirty Shared Locked PageTables name
ff8636e8 56 376 0 0 0 0 mapped_file( browseui.dll )
ff8cf388 24 0 0 0 0 0 mapped_file( AVH32DLL.DLL )
ff8d62c8 12 0 0 0 0 0 mapped_file( PSAPI.DLL )
ff8dd468 156 28 0 0 0 0 mapped_file( INOJOBSV.EXE )
fe424808 136 88 0 52 0 0 mapped_file( oleaut32.dll )
fe4228a8 152 44 0 116 0 0 mapped_file( MSVCRT.DLL )
ff8ec848 4 0 0 0 0 0 No Name for File
ff859de8 0 32 0 0 0 0 mapped_file( timedate.cpl )
. . . . .
kd> !ca ff8636e8
ControlArea @ff8636e8
Segment: e1b74548 Flink 0 Blink: 0
Section Ref 0 Pfn Ref 6c Mapped Views: 1
User Ref 1 Subsections 5 Flush Count: 0
File Object ff86df88 ModWriteCount 0 System Views: 0
WaitForDel 0 Paged Usage 380 NonPaged Usage e0
Flags (10000a0) Image File HadUserReference
File: /WINNT/System32/browseui.dll
Segment @ e1b74548:
Base address 0 Total Ptes c8 NonExtendPtes: c8
Image commit 1 ControlArea ff8636e8 SizeOfSegment: c8000
Image Base 0 Committed 0 PTE Template: 31b8438
Based Addr 76e10000 ProtoPtes e1b74580 Image Info: e1b748a4
Subsection 1. @ ff863720
ControlArea: ff8636e8 Starting Sector 0 Number Of Sectors 2
Base Pte e1b74580 Ptes In subsect 1 Unused Ptes 0
Flags 15 Sector Offset 0 Protection 1
ReadOnly CopyOnWrite
Subsection 2. @ ff863740
ControlArea: ff8636e8 Starting Sector 2 Number Of Sectors 3d0
Base Pte e1b74584 Ptes In subsect 7a Unused Ptes 0
Flags 35 Sector Offset 0 Protection 3
ReadOnly CopyOnWrite
Subsection 3. @ ff863760
ControlArea: ff8636e8 Starting Sector 3D2 Number Of Sectors 7
Base Pte e1b7476c Ptes In subsect 1 Unused Ptes 0
Flags 55 Sector Offset 0 Protection 5
ReadOnly CopyOnWrite
Subsection 4. @ ff863780
ControlArea: ff8636e8 Starting Sector 3D9 Number Of Sectors 21f
Base Pte e1b74770 Ptes In subsect 44 Unused Ptes 0
Flags 15 Sector Offset 0 Protection 1
ReadOnly CopyOnWrite
Subsection 5. @ ff8637a0
ControlArea: ff8636e8 Starting Sector 5F8 Number Of Sectors 3a
Base Pte e1b74880 Ptes In subsect 8 Unused Ptes 0
Flags 15 Sector Offset 0 Protection 1
ReadOnly CopyOnWrite
关于控制域的更多信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!callback 扩展显示指定线程的陷阱(trap)相关的回调数据(callback data)。
!callback Address [Number]
Address
指定线程的16进制地址。如果为-1或者省略,则使用当前线程。
Number
指定需要的回调帧(callback frame)的数量。这些帧在显示中会标注出来。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
该命令只能对x86目标机使用。
如果系统还没有经历过系统陷阱(system trap),则该扩展命令不会产生有用的数据。
关于系统陷阱的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!calldata 扩展以命名表(named table)中的函数调用统计(procedure call statistics)的形式显示性能信息。
!calldata Table
Table
用于搜集调用数据的表的名字。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
在老版本的Windows NT 4.0中,使用调用数据(call data)来测量调用性能。
!can_write_kdump 扩展用来验证目标机上是否有足够的磁盘空间用来创建指定类型的内核dump文件。
!can_write_kdump [-dn] [Options]
-dn
表示目标机上的文件系统是NTFS。如果省略该参数,就不能计算目标机上的磁盘空闲空间总数,会显示一条警告信息。但是,仍然会显示需要的空间数量。
Options
可以使用下面这些选项:
-t
表示要验证是否有足够空间用来创建minidump。
-s
表示要验证是否有足够空间用来创建摘要内核转储(summary kernel dump)。这是默认值。
-f
表示要验证是否有足够空间用于创建完整内核转储。
Windows NT 4.0 |
Kext.dll |
Windows 2000 |
Kext.dll |
Windows XP和之后 |
Kext.dll |
如果未指定Option,则该命令会检查是否有足够空间用于摘要内核转储(summary kernel dump)。
下面的例子中,没有指定文件系统:
kd> !can_write_kdump
Checking kernel summary dump...
WARNING: Can't predict how many pages will be used, assuming worst-case.
Physical memory: 285560 KB
Page file size: 1572864 KB
NO: Page file too small
!cbreg 扩展显示CardBus Socket 寄存器,以及CardBus Exchangable Card Architecture (ExCA) 寄存器。
!cbreg [%%]Address
%%
表示Address 是一个物理地址而不是虚拟地址。
Address
指定要显示的寄存器地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kext.dll |
Windows XP和之后 |
Kext.dll |
!cbreg 扩展仅对x86目标机可用。
!exca扩展命令可以用来以套接字号(socket number)显示PCIC ExCA寄存器。
!cchelp 扩展用于在调试器命令窗口中显示一些缓存管理扩展命令的简要帮助文本。
!cchelp
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
关于缓存管理(cache management)的信息,可以查看Microsoft Windows SDK 文档,以及Mark Russinovich 和David Solomon编著的Microsoft Windows Internals。
!cchelp 扩展命令会显示!bcb、 !defwrites、 !finddata和!scm 命令的帮助。其他的缓存管理扩展还包括!openmaps 和!pcm。
!chklowmem 扩展检查使用/pae 和/nolowmem选项引导的计算机上,4GB以下的物理内存页是否使用了指定的填充模板来填充。
!chklowmem
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
该扩展命令在用于验证内核模式驱动是否在4GB分界线以上的物理内存上进行正确操作时有用。一般来说驱动程序将物理地址截断为32位,然后向4GB边界以下写入的时候会出现错误。!chklowmem 扩展命令可以检查对4GB边界以下的任何写入。
!cmreslist 扩展显示指定的设备对象(device object)的CM_RESOURCE_LIST 结构。
!cmreslist Address
Address
指定CM_RESOURCE_LIST 结构的16进制地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
查看Plug and Play 调试获得该扩展命令的应用。关于CM_RESOURCE_LIST 结构的更多信息,查看Windows Driver Kit (WDK)文档。
!cpuinfo 扩展显示目标机的CPU的详细信息。
Windows 2000中的语法
!cpuinfo
Windows XP和之后的语法
!cpuinfo Processor
!cpuinfo
Processor
(Windows XP和之后) 指定要显示的处理器。如果省了,则显示所有处理器。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kdexts.dll |
!cpuinfo 扩展命令可以在本地内核调试时使用。在Windows 2000目标机上使用时,会显示所有处理器的信息。
下面是示例:
kd> !cpuinfo
CP F/M/S Manufacturer MHz Update Signature Features
0 6,1,9 GenuineIntel 198 000000d200000000 000000ff
第一个数字是处理器号。
关于调试多处理器计算机的更多信息,查看多处理器语法。
!db、 !dc、 !dd、 !dp、!dq、 !du和 !dw 扩展命令显示目标机上的指定物理地址的数据。
这些扩展命令不能和d* (Display Memory)命令或者!ntsdexts.dp 扩展命令混淆。
!db [Caching] [-m] [PhysicalAddress] [L Size]
!dc [Caching] [-m] [PhysicalAddress] [L Size]
!dd [Caching] [-m] [PhysicalAddress] [L Size]
!dp [Caching] [-m] [PhysicalAddress] [L Size]
!dq [Caching] [-m] [PhysicalAddress] [L Size]
!du [Caching] [-m] [PhysicalAddress] [L Size]
!dw [Caching] [-m] [PhysicalAddress] [L Size]
Caching
可以是下面这些值中任意一个。Caching 值必须包含在中括号中:
[c]
使得该扩展从已缓存内存(cached memory)中读取。
[uc]
使得该扩展从未缓存内存(uncached memory)中读取。
[wc]
使得该扩展从写聚合内存(write-combined memory)中读取。
-m
每次读取一个内存单元。例如,!db -m 以8位为单位读取内存块,!dw –m以16位为单位读取。如果硬件不支持对32位物理内存的读取,则可能需要使用-m选项。该选项不会影响输出的长度或者形式 — 只会影响对内存的访问方式。
PhysicalAddress
以16进制格式指定要显示的物理地址。如果在第一次使用该命令时省略,则默认地址为0。如果在后续的命令中省略,则从上一次显示的末尾开始。
L Size
指定要显示的内存块个数。每个块的大小由使用的具体命令决定。
Windows NT 4.0 |
Kext.dll |
Windows 2000 |
Kext.dll |
Windows XP和之后 |
Kext.dll |
这些命令都用于显示物理内存,但是它们的显示格式和默认的长度不同:
因此,对这些扩展命令中的两个使用一样的Size常常显示出来的结果的长度是不同的。例如,使用!db L 32 会显示32字节(显示16进制字节值),而!dd L 32 会显示128个字节(显示DWORD值)。
下面是使用了缓存属性标志(caching attribute flag)的示例:
kd> !dc e9000
physical memory read at e9000 failed
If you know the caching attributes used for the memory,
try specifying [c], [uc] or [wc], as in !dd [c]
WARNING: Incorrect use of these flags will cause unpredictable
processor corruption. This may immediately (or at any time in
the future until reboot) result in a system hang, incorrect data
being displayed or other strange crashes and corruption.
kd> !dc [c] e9000
# e9000 000ea002 000ea002 000ea002 000ea002 ................
# e9010 000ea002 000ea002 000ea002 000ea002 ................
使用!e* 扩展命令来写入物理内存。关于内存操作的概述和内存相关命令的描述,查看读写内存。
!dbgprint 扩展显示之前发送给DbgPrint 缓冲区的字符串。
!dbgprint
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
DbgPrint、KdPrint、 DbgPrintEx、以及KdPrintEx 内核例程会向目标机的缓冲区发送一个格式化后的字符串。如果没有禁用的话,则该字符串会自动在主控机的调试器命令窗口中显示出来。
一般来说,发送给该缓冲区的信息都会自动在调试器命令窗口中显示出来。但是,这种显示可以通过全局标志实用程序 (gflags.exe)禁用。另外,这种显示不会在本地内核调试时显示。更多信息,查看DbgPrint缓冲区。
!dbgprint 扩展使得缓冲区中的内容被显示出来(不管自动显示是否被禁用)。它不会显示被以组件和重要性级别过滤掉了的信息。 (关于这种过滤的详细信息,查看 读取和过滤调试信息。)
关于DbgPrint、 KdPrint、DbgPrintEx、以及KdPrintEx的更多信息,查看向调试器发送输出。
!dblink 扩展以反序显示一个链表。
Windows NT 4.0的语法
!dblink Address [Count]
Windows XP和之后的语法
!dblink Address [Count] [Bias]
Address
指定LIST_ENTRY 结构的地址。将会从这个节点开始显示。
Count
指定要显示的链表项的最大个数。如果省略,则Windows NT 4.0中默认为24,Windows 2000和之后的系统中为32。
Bias
(Windows 2000和之后) 指定每个指针中要忽略的位的掩码。每个Blink 地址在跟随到下一个位置之前会进行AND运算(和Bias的NOT)。默认值为0(即不忽略任何位)。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Kexts.dll |
!dblink 扩展通过LIST_ENTRY 结构的Blink 字段来进行遍历,并且对每个地址显示最多4个ULONG。可以使用!dflink进行其它方向的遍历。
dl (Display Linked List)命令比!dblink 和!dflink更加通用。
!dcr 扩展显示指定地址处的默认控制寄存器(default control register (DCR))。
!dcr Expression [DisplayLevel]
Expression
指定要显示的DCR的16进制地址。@dcr 可以用作该参数。这种情况下,会显示当前处理器的DCR信息。
DisplayLevel
可以是下面这些选项中的一个:
0
只显示每个DCR字段的值。这是默认值。
1
对每个非保留和非忽略的DCR字段显示更深入的信息。
2
对所有DCR字段显示深入信息,包括被忽略或保留的那些。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kexts.dll |
该扩展命令只能对Itanium目标机使用。
DCR 指定了中断时的处理器状态寄存器值的默认参数。DCR也指定了一些附加的全局控制信息,例如speculative load faults 是否被延迟。
下面是两个示例:
kd> !dcr @dcr
dcr:pp be lc dm dp dk dx dr da dd
1 0 1 1 1 1 1 1 1 1
kd> !dcr @dcr 2
pp : 1 : Privileged Performance Monitor Default
be : 0 : Big-Endian Default
lc : 1 : IA-32 Lock check Enable
rv : 0 : reserved1
dm : 1 : Defer TLB Miss faults only
dp : 1 : Defer Page Not Present faults only
dk : 1 : Defer Key Miss faults only
dx : 1 : Defer Key Permission faults only
dr : 1 : Defer Access Rights faults only
da : 1 : Defer Access Bit faults only
dd : 0 : Defer Debug faults only
rv : 0 : reserved2
!dcs 扩展已经废除。要显示PCI配置空间(configuration space),使用!pci 100 Bus Device Function。
!deadlock 扩展显示通过驱动程序验证器(Driver Verifier)的Deadlock Detection 选项搜集的死锁(deadlock)信息。
!deadlock
!deadlock 1
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Kexts.dll |
该扩展命令只有在驱动程序验证器的Deadlock Detection 选项检测到加锁层次违例(lock hierarchy violation)并产生bug check 0xC4 (DRIVER_VERIFIER_DETECTED_VIOLATION)时,才能提供有用的信息。
不带任何参数时,!deadlock 扩展显示基本的加锁的拓扑层次。如果问题不是一帮的循环死锁,该命令会描述遇到了什么情况。
!deadlock 1 扩展显示堆栈回溯。该堆栈是锁被请求时活动的调用堆栈。
下面是一个示例:
0:kd> !deadlock
Deadlock detected (2 resources in 2 threads):
Thread 0: A B
Thread 1: B A
Where:
Thread 0 = 8d3ba030
Thread 1 = 8d15c030
Lock A = bba2af30 Type 'Spinlock'
Lock B = dummy!GlobalLock Type 'Spinlock'
显示出了相关的锁和线程。但是,这只是一个摘要信息,可能还不足以调试遇到的问题。
使用!deadlock 1 来打印出死锁相关的每个锁被请求时的堆栈回溯。由于这是运行时堆栈回溯,所以在使用调试版时会更加完整。在free版上,它们可能在一行之后就被截断了。
0:kd> !deadlock 1
Deadlock detected (2 resources in 2 threads):
Thread 0 (8D14F750) took locks in the following order:
Lock A -- b7906f30 (Spinlock)
Stack: dummy!DummyActivateVcComplete+0x63
dummy!dummyOpenVcChannels+0x2E1
dummy!DummyAllocateRecvBufferComplete+0x436
dummy!DummyAllocateComplete+0x55
NDIS!ndisMQueuedAllocateSharedHandler+0xC9
NDIS!ndisWorkerThread+0xEE
Lock B -- dummy!GlobalLock (Spinlock)
Stack: dummy!dummyQueueRecvBuffers+0x2D
dummy!DummyActivateVcComplete+0x90
dummy!dummyOpenVcChannels+0x2E1
dummy!DummyAllocateRecvBufferComplete+0x436
dummy!DummyAllocateComplete+0x55
Thread 1 (8D903030) took locks in the following order:
Lock B -- dummy!GlobalLock (Spinlock)
Stack: dummy!dummyRxInterruptOnCompletion+0x25D
dummy!DummyHandleInterrupt+0x32F
NDIS!ndisMDpcX+0x3C
ntkrnlpa!KiRetireDpcList+0x5D
Lock A -- b7906f30 (Spinlock)
Stack: << Current stack >>
除了当前堆栈之外,这些基本上就是所有需要的信息了。
0: kd> k
ChildEBP RetAddr
f78aae6c 80664c58 ntkrnlpa!DbgBreakPoint
f78aae74 8066523f ntkrnlpa!ViDeadlockReportIssue+0x2f
f78aae9c 806665df ntkrnlpa!ViDeadlockAnalyze+0x253
f78aaee8 8065d944 ntkrnlpa!VfDeadlockAcquireResource+0x20b
f78aaf08 bfd6df46 ntkrnlpa!VerifierKeAcquireSpinLockAtDpcLevel+0x44
f78aafa4 b1bf2d2d dummy!dummyRxInterruptOnCompletion+0x2b5
f78aafc4 bfde9d8c dummy!DummyHandleInterrupt+0x32f
f78aafd8 804b393b NDIS!ndisMDpcX+0x3c
f78aaff4 804b922b ntkrnlpa!KiRetireDpcList+0x5d
从上面这些可以知道有哪些相关的锁,以及它们在什么地方被请求的。这对于调试死锁来说已经包含了足够信息。如果可以使用源码,则还可以使用调试器来查看问题具体出现在什么地方:
0: kd> .lines
Line number information will be loaded
0: kd> u dummy!DummyActivateVcComplete+0x63 l1
dummy!DummyActivateVcComplete+63 [d:/nt/drivers/dummy/vc.c @ 2711]:
b1bfe6c9 837d0c00 cmp dword ptr [ebp+0xc],0x0
0: kd> u dummy!dummyQueueRecvBuffers+0x2D l1
dummy!dummyQueueRecvBuffers+2d [d:/nt/drivers/dummy/receive.c @ 2894]:
b1bf4e39 807d0c01 cmp byte ptr [ebp+0xc],0x1
0: kd> u dummy!dummyRxInterruptOnCompletion+0x25D l1
dummy!dummyRxInterruptOnCompletion+25d [d:/nt/drivers/dummy/receive.c @ 1424]:
b1bf5d05 85f6 test esi,esi
0: kd> u dummy!dummyRxInterruptOnCompletion+0x2b5 l1
dummy!dummyRxInterruptOnCompletion+2b5 [d:/nt/drivers/dummy/receive.c @ 1441]:
b1bf5d5d 8b4648 mov eax,[esi+0x48]
现在就知道了源文件的名字,以及请求锁的位置的行号。这种情况下,源文件表明了这些线程的行为如下:
通过这点,死锁原因就清楚了。
关于驱动程序验证器的信息,查看Windows Driver Kit (WDK) 文档。
cc682/NetRoc
http://netroc682.spaces.live.com/
本参考节主要描述主要在内核模式调试时使用的扩展命令。
调试器会自动加载这些扩展命令的适当版本。如果没有自己加载不同的版本,则不需要了解究竟使用的是哪个DLL版本。查看使用调试器扩展命令获得默认的模块搜索顺序的说明。查看 加载调试器扩展DLL获得如何加载扩展模块的说明。
每条扩展命令的参考中都列出了引出该命令的DLL。使用下面的规则来确定扩展DLL是从哪个目录加载的:
另外,winext/kext.dll 中的内核模式扩展命令是不针对于特定操作系统的。
!ahcache 扩展显示应用程序兼容性缓存(application compatibility cache)。
!ahcache [Flags]
Flags
指定输出中要包含的信息。可以是下面这些位的任意组合(默认值为0):
Bit 0 (0x1)
显示RTL_GENERIC_TABLE 列表,而不是LRU列表。
Bit 4 (0x10)
详细输出:包含所有条目的详细信息,而不仅仅是名字。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP 和之后 |
Kdexts.dll |
!alignmentfaults 扩展显示位置(location)和映像(image)的所有当前类型对齐错误(type alignment faults),以发生频率排序。
!alignmentfaults
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP 和之后 |
Kdexts.dll |
仅在调试版系统中可用。
关于对齐错误的更多信息,查看Microsoft Windows SDK文档。
!analyzebugcheck 扩展命令已经废除,使用!analyze来替代。
!apc 扩展格式化并显示一个或多个异步过程调用(APC)的内容。
!apc
!apc proc Process
!apc thre Thread
!apc KAPC
Process
指定要显示的APC所在进程的地址。
Thread
指定要显示的APC所在线程的地址。
KAPC
指定要显示的内核APC的地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP 和之后 |
Kdexts.dll |
不带参数时,!apc显示所有APC。
下面是一个示例:
kd> !apc
*** Enumerating APCs in all processes
Process e0000000858ba8b0 System
Process e0000165fff86040 smss.exe
Process e0000165fff8c040 csrss.exe
Process e0000165fff4e1d0 winlogon.exe
Process e0000165fff101d0 services.exe
Process e0000165fffa81d0 lsass.exe
Process e0000165fff201d0 svchost.exe
Process e0000165fff8e040 svchost.exe
Process e0000165fff3e040 svchost.exe
Process e0000165fff6e040 svchost.exe
Process e0000165fff24040 spoolsv.exe
Process e000000085666640 wmiprvse.exe
Process e00000008501e520 wmiprvse.exe
Process e0000000856db480 explorer.exe
Process e0000165fff206a0 ctfmon.exe
Process e0000000850009d0 ctfmon.exe
Process e0000165fff51600 conime.exe
Process e000000085496340 taskmgr.exe
Process e000000085489c30 userinit.exe
关于APC的信息,查看Windows Driver Kit (WDK) 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!apicerr 扩展显示本地的高级可编程中断控制器(Advanced Programmable Interrupt Controller (APIC))错误日志。
!apicerr [Format]
Format
指定显示错误日志内容的顺序。可以是下面这些值的任意一个:
0x0
按照发生次序显示。
0x1
按照不同处理器显示错误日志。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP 和之后 |
Kdexts.dll |
该扩展命令只能针对基于x86或x64的目标机使用。
关于APIC的信息,查看Mark Russinovich 和David Solomon 所著的Microsoft Windows Internals。
!arbinst 扩展显示指定的arbiter的信息。
!arbinst Address [Flags]
Address
指定要显示的arbiter的16进制地址。
Flags
指定对每个arbiter要显示多少信息。目前唯一的标志是0x100。如果设置了它,则会显示别名(alias)。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP 和之后 |
Kdexts.dll |
对于指定的arbiter,!arbinst 会显示系统资源每个已分配的范围,一些可选标志、附加到该范围的PDO(即该范围的所有者)、以及该所有者得服务名(如果已知的话)。
下面是一个示例:
kd> !arbinst e0000106002ee8e8
Port Arbiter "PCI I/O Port (b=02)" at e0000106002ee8e8
Allocated ranges:
0000000000000000 - 0000000000001fff 00000000
0000000000002000 - 00000000000020ff P e0000000858bea20 (ql1280)
0000000000003000 - ffffffffffffffff 00000000
Possible allocation:
< none >
kd> !arbinst e0000106002ec458
Memory Arbiter "PCI Memory (b=02)" at e0000106002ec458
Allocated ranges:
0000000000000000 - 00000000ebffffff 00000000
00000000effdef00 - 00000000effdefff B e0000000858be560
00000000effdf000 - 00000000effdffff e0000000858bea20 (ql1280)
00000000f0000000 - ffffffffffffffff 00000000
Possible allocation:
< none >
参见!arbiter扩展。
!arbiter 扩展显示当前的system resource arbiter和arbitrated range。
!arbiter [Flags]
Flags
指定要显示哪种类型的arbiter。如果省略,则显示所有arbiter。这些位可以自由组合。
Bit 0 (0x1)
I/O arbiters.
Bit 1 (0x2)
Memory arbiters.
Bit 2 (0x4)
IRQ arbiters.
Bit 3 (0x8)
DMA arbiters.
Bit 4 (0x10)
Bus number arbiters.
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP 和之后 |
Kdexts.dll |
对每个arbiter,!arbiter会显示系统资源每个已分配的范围,一些可选标志、附加到该范围的PDO(即该范围的所有者)、以及该所有者得服务名(如果已知的话)。
标志的意义如下:
标志 |
意义 |
S |
区域被共享 |
C |
区域有冲突(conflict) |
B |
区域是boot-allocated的 |
D |
区域是driver-exclusive的 |
A |
区域别名(alias) |
P |
Range positive decode |
下面是一个例子:
kd> !arbiter 4
DEVNODE 80e203b8 (HTREE/ROOT/0)
Interrupt Arbiter "" at 80167140
Allocated ranges:
0000000000000000 - 0000000000000000 B 80e1d3d8
0000000000000001 - 0000000000000001 B 80e1d3d8
.....
00000000000001a2 - 00000000000001a2
00000000000001a2 - 00000000000001a2 CB 80e1d3d8
00000000000001a2 - 00000000000001a2 CB 80e52538 (Serial)
00000000000001a3 - 00000000000001a3 80e52778 (i8042prt)
00000000000001b3 - 00000000000001b3 80e1b618 (i8042prt)
Possible allocation:
< none >
这个例子中, 倒数第二行显示了资源范围(只由0x1A3组成)、0x80E52778的PDO、服务为i8042prt.sys 。这一行没有列出标志。
现在可以对PDO地址使用 !devobj 来找到设备扩展(device extension)和设备节点(device node)的地址:
kd> !devobj 80e52778
Device object (80e52778) is for:
00000034 /Driver/PnpManager DriverObject 80e20610
Current Irp 00000000 RefCount 1 Type 00000004 Flags 00001040
DevExt 80e52830 DevObjExt 80e52838 DevNode 80e52628
ExtensionFlags (0000000000)
AttachedDevice (Upper) 80d78b28 /Driver/i8042prt
Device queue is not busy.
查看Plug and Play 调试获得该扩展命令的应用。
!ate 扩展显示指定地址处的预备页表(alternate page table entry (ATE))。
!ate Address
Address
指定要显示的ATE。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP 和之后 |
Kdexts.dll |
该扩展仅在Itanium计算机上可用。
ATE 的状态标志在下表中列出。!ate 的显示以大写字母或者虚线来表示这些位,并且还添加其他附加的信息。
位设置时的显示 |
位清除时的显示 |
含义 |
V |
- |
提交 |
G |
- |
未访问过 |
E |
- |
执行 |
W |
R |
可写或者只读 |
L |
- |
已锁定。该ATE已被锁定,因此在包含该ATE的页面上的任何错误都会重试直到错误被修正。这在多处理器系统上可能发生。 |
Z |
- |
填充为0。 |
N |
- |
没有访问(No access)。 |
C |
- |
写时复制(Copy on Write) |
I |
- |
间接PTE(PTE indirect),该ATE间接引用另外的物理页面。包含该ATE的页面可能有两个不一样的ATE属性(ATE attributes)。 |
P |
- |
保留。 |
关于页表和页目录的信息,查看Mark Russinovich 和David Solomon 编著的Microsoft Windows Internals。
!bcb 扩展显示指定的缓冲区控制块(buffer control block)。
!bcb Address
Address
指定缓冲区控制块的地址。
Windows NT 4.0 |
不可用 |
Windows 2000 |
Kdextx86.dll |
Windows XP 和之后 |
不可用(查看注释节) |
该扩展仅在Windows 2000上可用。在Windows XP或之后的系统中,使用dt nt!_BCB Address 命令来直接显示缓冲区控制块。
关于缓存管理的信息,查看Microsoft Windows SDK 文档,以及Mark Russinovich 和David Solomon 编著的Microsoft Windows Internals。
关于缓存管理得其他扩展命令的信息,使用!cchelp命令。
!blockeddrv 扩展显示目标机上的blocked drivers列表。
!blockeddrv
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP 和之后 |
Kdexts.dll |
下面是一个示例:
kd> !blockeddrv
Driver: Status GUID
afd.sys 0: {00000008-0206-0001-0000-000030C964E1}
agp440.sys 0: {0000005C-175A-E12D-5000-010020885580}
atapi.sys 0: {0000005C-B04A-E12E-5600-000020885580}
audstub.sys 0: {0000005C-B04A-E12E-5600-000020885580}
Beep.SYS 0: {0000005C-B04A-E12E-5600-000020885580}
Cdfs.SYS 0: {00000008-0206-0001-0000-000008F036E1}
.....
!bpid 扩展要求目标机上的某个进程中断到调试器中,或者要求用户模式调试器附加到目标机上的某个进程上。
!bpid [Options] PID
Option
控制该命令的其他行为。
Option 的合法值有下面这些。
-a |
将一个新的用户模式调试器附加到PID指定的进程上。该用户模式调试器在目标机上运行。 |
-s |
在WinLogon进程中添加一个在PID指定的用户模式进程中断前立即触发的断点。这使得在尝试操作之前有一次机会来验证该请求。 |
-w |
将请求保存在目标机的内存中。之后目标系统可以重复该请求,但是一般不需要这样。 |
PID
指定目标机上的进程ID。如果使用该命令来控制目标机上的用户模式调试器,则PID应该是目标进程的ID,而不是用户模式调试器的ID。(由于进程ID一般以10进制列出来,所以可能需要在前面加上0n前缀来转换成16进制格式。)
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP 和之后 |
Kdexts.dll |
该扩展命令仅在x86、x64和Itanium目标机上支持。
该命令在将用户模式调试器的输入输出重定向到内核调试器时特别有用。它使得用户模式目标程序中断到用户模式调试器中,并且从内核调试器请求输入。查看从内核调试器控制用户模式调试器获得详细信息。
如果在其他情况下使用该命令,用户模式进程会调用DbgBreakPoint。这一般会直接中断到内核调试器中。
-s 选项使得指定进程的断点触发之前先在WinLogon中触发一个断点。如果想在WinLogon的进程上下文中进行一些调试操作时有用。g (Go)命令可以转移到第二个断点。
有些情况该扩展会失败:
!btb 扩展显示Itanium处理器、分支跟踪缓存(branch traces buffer (BTB))配置、以及当前处理器上的跟踪寄存器(trace registers)。
!btb
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP 和之后 |
Kdexts.dll |
该扩展命令只能在Itanium目标机上使用。
]!bth 扩展显示指定处理器上的Itanium分支跟踪记录。
!bth [Processor]
Processor
指定处理器。如果省略Processo,则显示所有处理器上的分支跟踪记录(branch trace history)。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP 和之后 |
Kdexts.dll |
该扩展命令只能在Itanium目标机上使用。
!bugdump 扩展命令格式化并显示在bug check回调缓冲区(bug check callback buffers)中的信息。
!bugdump [Component]
Component
指定要查看回调数据的组件。如果省略,则显示所有的bug check回调数据。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP 和之后 |
Kdexts.dll |
该扩展仅在发生了bug check之后,或者调试内核模式dump文件时使用。
Component 参数对应KeRegisterBugCheckCallback 使用的最后一个参数。
小内存转储中不包含回调数据的缓冲区。这些缓冲区仅在内核内存转储和完整内存转储中存在。但是,在Windows XP SP1、Windows Server 2003和之后版本的Windows中,dump文件是在驱动的BugCheckCallback 被调用之前创建的,所以这些缓冲区中不会包含由这些函数写入的数据。
如果对崩溃的系统进行活动调试,则存在所有的回调数据。
更多信息,查看读取Bug Check回调数据。
!bushnd 扩展显示HAL BUS_HANDLER结构。
!bushnd [Address]
Address
指定HAL BUS_HANDLER 结构的16进制地址。如果省略,!bushnd 显示总线的列表以及handler 的基地址。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP 和之后 |
Kdexts.dll |
cc682/NetRoc
http://netroc682.spaces.live.com/
!mui 扩展命令显示多语言用户接口(Multilingual User Interface (MUI))缓存信息。MUI的实现在Windows Vista中被显著的改良了。所以该功能在早期的实现上可能是不明确的。
用户模式语法
!mui –c
!mui –f
!mui -i
!mui -r ModuleAddress
!mui -t
!mui -?
内核模式语法
!mui -c
!mui –f
!mui -i
!mui -s
!mui -r ModuleAddress
!mui -t
!mui -?
-c
输出中包含语言标识符(language identifier (ID))、指向模块的指针、指向资源配置数据(resource configuration data)的指针、以及指向每个模块关联的MUI DLL的指针。
-f
输出中包含加载器合并的语言后备列表(loader merged language fallback list)。
-i
输出中包含已安装和授权的MUI语言,以及它们的关联信息。
-r ModuleAddress
显示ModuleAddress 模块的资源配置数据(resource configuration data)。包括文件类型、校验和的值、以及资源类型。
-s
(仅内核模式) 输出中包含模块和每个模块关联的MUI DLL的完整路径。
-t
输出中包含线程的首选语言(preference language)。
-?
在调试器命令窗口中显示该扩展命令的简要帮助文本。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP |
不可用 |
Windows Vista 和之后 |
Exts.dll |
关于MUI和资源配置数据格式(resource configuration data format)的更多信息,查看Microsoft Windows SDK 文档。
!net_send 扩展通过本地网络发送一条消息。
!net_send SendingMachine TargetMachine Sender Message
SendingMachine
指定要处理该命令的计算机。建议使用调试器所运行的计算机的名字,因为网络配置可能会拒绝发送这条消息。SendingMachine 不能在开头包括反斜线(//)。
TargetMachine
指定发送消息的对象。TargetMachine 不能在开头包含反斜线(//)。
Sender
指定消息的发送者。建议Sender 和SendingMachine 一样,因为网络配置可能会拒绝发送该消息。当这条消息被显示出来时,该字符串会作为消息的发送者。
Message
指定消息本身。Sender 参数后面的所有文本都会被当作Message 的一部分,包括空格和引号,分号会结束Message并且开始一条新的命令。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP和之后 |
Ext.dll |
!obja 扩展命令显示对象管理器中某个对象的属性。
!obja Address
Address
指定要查看的对象头的16进制地址。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP和之后 |
Ext.dll |
指定对象所具备的属性会被列举出来。合法的属性包括:
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_VALID_ATTRIBUTES 0x000001F2L
下面是一个示例:
kd> !obja 80967768
Obja +80967768 at 80967768:
OBJ_INHERIT
OBJ_PERMANENT
OBJ_EXCLUSIVE
关于对象和对象管理器的更多信息,查看Microsoft Windows SDK 文档、Windows Driver Kit (WDK) 文档、以及Mark Russinovich 和David Solomon 编著的Microsoft Windows Internals。
!owner 扩展用于显示某个模块或者函数的所有者。
!owner [Module[!Symbol]]
Module
指定要查看所有者的模块。Module 后面如果带一个星号(*),则表示任意多个其他字符。
Symbol
指定要查看所有者的Module 模块中的符号。Symbol 后如果带一个星号 (*) ,表示任意多个其他字符。如果省略Symbol ,则显示整个模块的所有者。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP和之后 |
Ext.dll |
如果没有使用参数并且发生了错误,!owner 会显示发生错误的模块或函数的所有者名字。
传递了模块或函数名给!owner 时,调试器会显示单词 Followup ,后面跟指定的模块或函数的所有者。
要该命令显示有用的信息,必须首先创建包含模块和函数所有者名字的triage.ini 文件。
triage.ini 文件的详细信息和!owner 命令的示例,查看指定模块和函数的所有者。
!peb 扩展显示进程环境块(PEB)信息的格式化形式。
!peb [PEB-Address]
PEB-Address
要查看的PEB的16进制地址。(不是从进程的内核进程块中获得的PEB地址。) 如果在用户模式下省略PEB-Address,则使用当前进程的PEB。如果在内核模式下省略,则显示当前进程上下文对应的PEB。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Exts.dll |
PEB是Microsoft Windows进程控制结构的用户模式部分。
如果内核模式下不带参数使用!peb 命令时出错,则需要用!process扩展命令来 获得需要的进程的PEB地址。 要确认进程上下文是设置成需要的进程的,并且将该PEB地址作为!peb的参数。
具体显示出来的输出根据不同的Windows版本以及是在内核模式还是用户模式下调试会有所不同。下面是一个附加到Windows Server 2003目标机上的内核调试器的输出示例:
kd> !peb
PEB at 7ffdf000
InheritedAddressSpace: No
ReadImageFileExecOptions: No
BeingDebugged: No
ImageBaseAddress: 4ad00000
Ldr 77fbe900
Ldr.Initialized: Yes
Ldr.InInitializationOrderModuleList: 00241ef8 . 00242360
Ldr.InLoadOrderModuleList: 00241e90 . 00242350
Ldr.InMemoryOrderModuleList: 00241e98 . 00242358
Base TimeStamp Module
4ad00000 3d34633c Jul 16 11:17:32 2002 D:/WINDOWS/system32/cmd.exe
77f40000 3d346214 Jul 16 11:12:36 2002 D:/WINDOWS/system32/ntdll.dll
77e50000 3d3484ef Jul 16 13:41:19 2002 D:/WINDOWS/system32/kernel32.dll
....
SubSystemData: 00000000
ProcessHeap: 00140000
ProcessParameters: 00020000
WindowTitle: 'D:/Documents and Settings/Administrator/Desktop/Debuggers.lnk'
ImageFile: 'D:/WINDOWS/system32/cmd.exe'
CommandLine: '"D:/WINDOWS/system32/cmd.exe" '
DllPath: 'D:/WINDOWS/system32;D:/WINDOWS/system32;....
Environment: 00010000
ALLUSERSPROFILE=D:/Documents and Settings/All Users
APPDATA=D:/Documents and Settings/UserTwo/Application Data
CLIENTNAME=Console
....
windir=D:/WINDOWS
类似的!teb 扩展命令用于显示线程环境块。
关于进程环境块的更多信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals。
!psr 扩展显示Itanium处理器状态字(processor status word (PSR))。
!psr PSR [DisplayLevel]
!psr @ipsr [DisplayLevel]
PSR
指定要显示的PSR的16进制地址。
@ipsr
显示ipsr寄存器。
DisplayLevel
可以使下面选项中任意一个:
0
只显示每个PSR字段(field)的值。这是默认情况。
1
显示中包含非保留或者忽略的PSR字段的更深入的信息。
2
显示中包含所有的PSR字段的深入信息,包括忽略和保留(ignored or reserved)的那些。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Exts.dll |
该命令只能在Itanium的目标机上使用。
下面是两个例子:
0:000> !psr @ipsr
psr:ia bn ed ri ss dd da id it mc is cpl rt tb lp db
0 1 0 0 0 0 0 0 1 0 0 3 1 0 0 0
si di pp sp dfh dfl dt pk i ic | mfh mfl ac up be
0 0 1 0 0 0 1 0 1 1 | 0 1 0 0 0
kd> !psr @ipsr 1
be : 0 : Big-Endian
up : 0 : User Performance monitor enable
ac : 1 : Alignment Check
mfl : 1 : Lower floating-point registers written
mfh : 0 : Upper floating-point registers written
ic : 1 : Interruption Collection
i : 0 : Interrupt enable
pk : 0 : Protection Key enable
dt : 1 : Data Address Translation enable
dfl : 0 : Disabled Floating-point Low register set
dfh : 1 : Disabled Floating-point High register set
sp : 0 : Secure Performance monitors
pp : 1 : Privileged Performance monitor enable
di : 0 : Disable Instruction set transition
si : 0 : Secure Interval timer
db : 0 : Debug Breakpoint fault enable
lp : 0 : Lower Privilege transfer trap enable
tb : 0 : Taken Branch trap enable
rt : 1 : Register stack translation enable
cpl : 0 : Current Privilege Level
is : 0 : Instruction Set
mc : 0 : Machine Abort Mask delivery disable
it : 1 : Instruction address Translation enable
id : 0 : Instruction Debug fault disable
da : 0 : Disable Data Access and Dirty-bit faults
dd : 0 : Data Debug fault disable
ss : 0 : Single Step enable
ri : 0 : Restart Instruction
ed : 0 : Exception Deferral
bn : 1 : register Bank
ia : 0 : Disable Instruction Access-bit faults
更多信息,查看Itanium 架构,或者Intel架构手册。
!rtlavl 扩展显示某个RTL_AVL_TABLE 结构的条目。
!rtlavl Address [Module!Type]
!rtlavl -?
Address
指定要显示的RTL_AVL_TABLE 的地址。
Module
指定定义该数据结构的模块。
Type
指定数据结构的名字。
-?
在调试器命令窗口中显示该命令的简要帮助文本。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP和之后 |
Ext.dll |
包含Module!Type 选项会使得列表中每个条目都被当成给定类型的。
任何时候通过按下CTRL+BREAK (WinDbg中) 或者CTRL+C (KD 或CDB中)都可以打断命令的输出。
使用!gentable 扩展命令来显示AVL表。
!sd 显示指定地址处的安全描述符(security descriptor)。
Windows NT 4.0 和Windows 2000中的语法:
!sd Address
Windows XP和之后的语法:
!sd Address [Flags]
Address
指定SECURITY_DESCRIPTOR 结构的16进制地址。
Flags
(Windows XP 和之后) 如果设置为1,则显示更友好的名字。包括安全描述符(security identifier (SID))类型,以及该SID的域(domain)和用户名。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Exts.dll |
这里有一个例子:
kd> !sd e1a96a80 1
->Revision: 0x1
->Sbz1 : 0x0
->Control : 0x8004
SE_DACL_PRESENT
SE_SELF_RELATIVE
->Owner : S-1-5-21-518066528-515770016-299552555-2981724 (User: MYDOMAIN/myuser)
->Group : S-1-5-21-518066528-515770016-299552555-513 (Group: MYDOMAIN/Domain Users)
->Dacl :
->Dacl : ->AclRevision: 0x2
->Dacl : ->Sbz1 : 0x0
->Dacl : ->AclSize : 0x40
->Dacl : ->AceCount : 0x2
->Dacl : ->Sbz2 : 0x0
->Dacl : ->Ace[0]: ->AceType: ACCESS_ALLOWED_ACE_TYPE
->Dacl : ->Ace[0]: ->AceFlags: 0x0
->Dacl : ->Ace[0]: ->AceSize: 0x24
->Dacl : ->Ace[0]: ->Mask : 0x001f0003
->Dacl : ->Ace[0]: ->SID: S-1-5-21-518066528-515770016-299552555-2981724 (User: MYDOMAIN/myuser)
->Dacl : ->Ace[1]: ->AceType: ACCESS_ALLOWED_ACE_TYPE
->Dacl : ->Ace[1]: ->AceFlags: 0x0
->Dacl : ->Ace[1]: ->AceSize: 0x14
->Dacl : ->Ace[1]: ->Mask : 0x001f0003
->Dacl : ->Ace[1]: ->SID: S-1-5-18 (Well Known Group: NT AUTHORITY/SYSTEM)
->Sacl : is NULL
关于该命令的应用和例子,查看查看对象的ACL。关于安全描述符的更多信息,查看 Microsoft Windows SDK文档、 Windows Driver Kit (WDK)文档、以及Mark Russinovich和David Solomon编写的 Microsoft Windows Internals。还可以参见!sid 和!acl。
!sid 扩展显示指定地址处的安全描述符 (SID)。
Windows NT 4.0 和Windows 2000的语法:
!sid Address
Windows XP和之后的系统中的语法:
!sid Address [Flags]
Address
指定SID结构的地址。
Flags
(Windows XP和之后) 如果设置为1,则SID类型、域和该SID的用户名都会显示出来。
(Windows XP and later) 如果设置为1,则显示更加友好的名字。包括安全描述符(SID)类型,以及该SID的域(domain)和用户名。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Exts.dll |
这里有两个示例,一个没有显示友好名,一个有显示:
kd> !sid 0xe1bf35b8
SID is: S-1-5-21-518066528-515770016-299552555-513
kd> !sid 0xe1bf35b8 1
SID is: S-1-5-21-518066528-515770016-299552555-513 (Group: MYGROUP/Domain Users)
关于SID的更多信息,查看Microsoft Windows SDK 文档、Windows Driver Kit (WDK)文档,或者Mark Russinovich 和David Solomon编写的 Microsoft Windows Internals 。也可以参见!sd 和!acl。
!slist 扩展显示一个单链表(singly-linked list (SList))。
!slist Address [ Symbol [Offset] ]
!slist -?
Address
指定SLIST_HEADER 的地址。
Symbol
指定要用来显示的数据类型。如果指定了Symbol,调试器显示的时候会假定单链表中每个实例具有该数据类型。
Offset
指定单链表指针在该结构中的字节偏移。
-?
在调试器命令窗口中显示该命令的简要帮助文本。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Exts.dll |
如果知道链接的结构的类型,那么Symbol 和Offset 参数是非常有用的。要查看区别,这里有两个例子;第一个省略了Symbol 和Offset 参数,第二个包含了。
0:000> !slist ListHead
SLIST HEADER:
+0x000 Alignment : a000a002643e8
+0x000 Next : 2643e8
+0x004 Depth : a
+0x006 Sequence : a
SLIST CONTENTS:
002643e8 002642c0 0000000a 6e676953 72757461
002642c0 00264198 00000009 6e676953 72757461
00264198 00264070 00000008 6e676953 72757461
00264070 00263f48 00000007 6e676953 72757461
00263f48 00261420 00000006 6e676953 72757461
00261420 002612f8 00000005 6e676953 72757461
002612f8 002611d0 00000004 6e676953 72757461
002611d0 002610a8 00000003 6e676953 72757461
002610a8 00260f80 00000002 6e676953 72757461
00260f80 00000000 00000001 6e676953 72757461
0:000> !slist ListHead _PROGRAM_ITEM 0
SLIST HEADER:
+0x000 Alignment : a000a002643e8
+0x000 Next : 2643e8
+0x004 Depth : a
+0x006 Sequence : a
SLIST CONTENTS:
002643e8
+0x000 ItemEntry : _SINGLE_LIST_ENTRY
+0x004 Signature : 0xa
+0x008 Description : [260] "Signature is: 10"
002642c0
+0x000 ItemEntry : _SINGLE_LIST_ENTRY
+0x004 Signature : 9
+0x008 Description : [260] "Signature is: 9"
00264198
+0x000 ItemEntry : _SINGLE_LIST_ENTRY
+0x004 Signature : 8
+0x008 Description : [260] "Signature is: 8"
00264070
+0x000 ItemEntry : _SINGLE_LIST_ENTRY
+0x004 Signature : 7
+0x008 Description : [260] "Signature is: 7"
00263f48
+0x000 ItemEntry : _SINGLE_LIST_ENTRY
+0x004 Signature : 6
+0x008 Description : [260] "Signature is: 6"
00261420
+0x000 ItemEntry : _SINGLE_LIST_ENTRY
+0x004 Signature : 5
+0x008 Description : [260] "Signature is: 5"
002612f8
+0x000 ItemEntry : _SINGLE_LIST_ENTRY
+0x004 Signature : 4
+0x008 Description : [260] "Signature is: 4"
002611d0
+0x000 ItemEntry : _SINGLE_LIST_ENTRY
+0x004 Signature : 3
+0x008 Description : [260] "Signature is: 3"
002610a8
+0x000 ItemEntry : _SINGLE_LIST_ENTRY
+0x004 Signature : 2
+0x008 Description : [260] "Signature is: 2"
00260f80
+0x000 ItemEntry : _SINGLE_LIST_ENTRY
+0x004 Signature : 1
+0x008 Description : [260] "Signature is: 1"
cc682/NetRoc
http://netroc682.spaces.live.com/
!std_map 扩展用来显示std::map 树的内容。
!std_map Address [Module!Type [TypeSize]]
!std_map -?
Address
指定要显示的std::map 树的地址。
Module
指定定义该数据结构的模块。
Type
指定数据结构的名字。必须是明确的Module!std::pair<Type1,Type2> 格式。如果使用了TypeSize参数,则这个参数必须包含在引号中。
TypeSize
指定数据结构的大小,以使得符号更加明确。
-?
在调试器命令窗口中显示该扩展的简短帮助文本。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP和之后 |
Ext.dll |
包含Module!Type 选项使得表中的每个条目都被当作给定类型。
使用dt -ve (Module!std::pair<Type1,Type2>) 来显示可能的大小。
要显示其它标准模板库 (STL)定义的模板,查看 !stl。
!stl 扩展命令显示一些已知的标准模板库(STL)的模板。
!stl [Options] Template
!stl -?
Options
可以包含任意的下面这些选项:
-v
显示详细输出。
-V
显示更加详细的输出,例如包含特定函数何时被调用以及何时返回这样的扩展命令执行过程的信息。
Template
指定要显示的模板的名字。
-?
在调试器命令窗口中显示简要的命令帮助文本。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Exts.dll |
只有在调试器的详细输出模式打开之后,详细输出的选项才能起作用。
该扩展命令当前支持的STL模板包括:string、 wstring、 vector<string>、 vector<wstring>、 list<string>、 list<wstring>、以及任何指向前面这几个类型的指针。
!str 扩展命令显示ANSI_STRING 或OEM_STRING 结构。
!str Address
Address
指定ANSI_STRING 或OEM_STRING 结构的16进制地址。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP和之后 |
Ext.dll |
ANSI 字符串包含的是8位的字符,用下面的结构定义:
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} STRING;
typedef STRING ANSI_STRING;
typedef STRING OEM_STRING;
如果字符串是NULL结尾的,Length 不能包含尾部的NULL。
关于ANSI_STRING 结构的更多信息,查看Microsoft Windows SDK文档。
!sym 扩展控制显示详细的符号加载和符号提示。
!sym
!sym noisy
!sym quiet
!sym prompts
!sym prompts off
noisy
激活详细符号加载(noisy symbol loading)。
quiet
禁止详细符号加载。
prompts
当SymSrv 接收到认证请求时,允许弹出对话框。
prompts off
禁止SymSrv 在接收到认证请求时显示认证对话框。这可能使得SymSrv 不能通过internet访问符号。
Windows NT 4.0 |
Dbghelp.dll |
Windows 2000 |
Dbghelp.dll |
Windows XP和之后 |
Dbghelp.dll |
如果不带参数使用!sym ,则显示当前的详细符号加载和符号提示的设置状态。
!sym noisy 和!sym quiet 扩展命令用来控制详细符号加载。关于其它显示和修改该选项的方法,查看SYMOPT_DEBUG。
!sym prompts 和!sym prompts off 扩展用来控制SymSrv接收到认证请求时是否弹出认证对话框。这些命令之后必须再使用.reload (Reload Module) 才能起效。认证请求可能是由代理服务器、internet防火墙、智能卡读卡器(smart card readers),以及安全页面(secure websites)发起的。关于其它显示和修改该选项的方法,查看防火墙和代理服务器。
注意 详细符号加载不能和详细源码加载混淆 — 它是使用.srcnoisy (Noisy Source Loading) 命令来控制的。
!symsrv 命令关闭符号服务器客户端(symbol server client)。
!symsrv close
Windows NT 4.0 |
Dbghelp.dll |
Windows 2000 |
Dbghelp.dll |
Windows XP和之后 |
Dbghelp.dll |
!symsrv close 会关闭任何活动的符号服务器客户端。
这在重新同步连接时有用。
如果之前拒绝过internet的认证请求,需要使用!symsrv close来重新连接符号存储。查看 防火墙和代理服务器获得详细信息。
!teb 扩展以的格式化后的形式显示线程环境块(TEB)的信息。
!teb [TEB-Address]
TEB-Address
要查看的TEB 的16进制地址。(这不是从该线程在内核的线程块中获得的TEB。) 如果在用户模式下省略TEB-Address,则使用当前进程的TEB。如果在内核模式下省略,则显示当前寄存器上下文对应的TEB。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Exts.dll |
TEB是用户模式下的Microsoft Windows线程控制结构。
如果在内核模式下不带参数使用 !teb 出现错误,则应该用!process扩展来查看需要的线程的TEB地址。确认寄存器上下文是设置成需要的线程的,然后再将该TEB地址用作!teb 的参数。
下面是在用户模式下使用该命令的一个例子:
0:001> ~
0 id: 324.458 Suspend: 1 Teb 7ffde000 Unfrozen
. 1 id: 324.48c Suspend: 1 Teb 7ffdd000 Unfrozen
0:001> !teb
TEB at 7FFDD000
ExceptionList: 76ffdc
Stack Base: 770000
Stack Limit: 76f000
SubSystemTib: 0
FiberData: 1e00
ArbitraryUser: 0
Self: 7ffdd000
EnvironmentPtr: 0
ClientId: 324.48c
Real ClientId: 324.48c
RpcHandle: 0
Tls Storage: 0
PEB Address: 7ffdf000
LastErrorValue: 0
LastStatusValue: 0
Count Owned Locks:0
HardErrorsMode: 0
类似的 !peb 扩展命令用于显示进程环境块。
关于线程环境块的更多信息,查看Mark Russinovich 和David Solomon 编著的Microsoft Windows Internals 。
!tls 扩展命令用于显示一个线程本地存储槽(TLS slot)。
!tls Slot [TEB]
Slot
指定TLS slot。可以是0到1088之间的任何10进制值。如果Slot 是-1,则显示所有slot。
TEB
指定线程环境块(TEB)。如果为0或者省略,则使用当前线程。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Exts.dll |
这里有一个例子:
0:000> !tls -1
TLS slots on thread: c08.f54
0x0000 : 00000000
0x0001 : 003967b8
0:000> !tls 0
c08.f54: 00000000
!token 扩展命令用来显示格式化后的安全令牌对象(security token object)的信息。
Windows NT 4.0 和Windows 2000的语法 (内核模式)
!token [Address]
Windows XP和之后系统中,内核模式:
!token [-n] [Address]
!token -?
Windows XP和之后系统,用户模式:
!token [-n] [Handle]
!token -?
Address
(仅内核模式) 指定要显示的令牌的地址。如果为0 或省略,则显示活动线程的令牌。
Handle
(仅用户模式) 指定要显示的令牌的句柄。如果为0或者省略,则显示目标进程关联的令牌。
-n
(Windows XP 和之后;仅用户模式) 显示更加友好的名字。包括安全描述符(SID)类型,以及SID的域和用户名。该选项在调试LSASS时不能使用。
-?
(Windows XP 和之后) 在调试器命令窗口中显示简要的命令帮助文本。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP和之后 |
Exts.dll |
在Windows NT 4.0 和Windows 2000中, !token仅在内核调试时可用。在Windows XP和之后的操作系统中, !token 可以在内核调试和用户模式活动调试时使用。调试用户模式dump文件时不能使用。
TOKEN 结构用来代表一个已认证的用户进程的安全对象类型。每个进程都被指派了一个令牌,作为该进程中所有线程的默认令牌。但是每个单独线程都可以指派一个令牌来重载默认的那个。
可以从!process的输出中得到令牌的地址。要显示TOKEN结构的每个单独字段的清单,可以在Windows NT 4.0或者Windows 2000中使用 !tokenfields 扩展命令,或者在Windows XP或之后的系统中使用 dt nt!_TOKEN 命令。
下面是一个例子:
kd> !process 81464da8 1
PROCESS 81464da8 SessionId: 0 Cid: 03bc Peb: 7ffdf000 ParentCid: 0124
DirBase: 0dec2000 ObjectTable: e1a31198 TableSize: 275.
Image: MSMSGS.EXE
VadRoot 81468cc0 Vads 170 Clone 0 Private 455. Modified 413. Locked 0.
DeviceMap e1958438
Token e1bed030
ElapsedTime 0:44:15.0142
UserTime 0:00:00.0290
KernelTime 0:00:00.0300
QuotaPoolUsage[PagedPool] 49552
QuotaPoolUsage[NonPagedPool] 10872
Working Set Sizes (now,min,max) (781, 50, 345) (3124KB, 200KB, 1380KB)
PeakWorkingSetSize 1550
VirtualSize 57 Mb
PeakVirtualSize 57 Mb
PageFaultCount 2481
MemoryPriority BACKGROUND
BasePriority 8
CommitCharge 2497
kd> !exts.token -n e1bed030
_TOKEN e1bed030
TS Session ID: 0
User: S-1-5-21-518066528-515770016-299552555-2981724 (User: MYDOMAIN/myuser)
Groups:
00 S-1-5-21-518066528-515770016-299552555-513 (Group: MYDOMAIN/Domain Users)
Attributes - Mandatory Default Enabled
01 S-1-1-0 (Well Known Group: localhost/Everyone)
Attributes - Mandatory Default Enabled
02 S-1-5-32-544 (Alias: BUILTIN/Administrators)
Attributes - Mandatory Default Enabled Owner
03 S-1-5-32-545 (Alias: BUILTIN/Users)
Attributes - Mandatory Default Enabled
04 S-1-5-21-518066528-515770016-299552555-2999049 (Group: MYDOMAIN/AllUsers)
Attributes - Mandatory Default Enabled
05 S-1-5-21-518066528-515770016-299552555-2931095 (Group: MYDOMAIN/SomeGroup1)
Attributes - Mandatory Default Enabled
06 S-1-5-21-518066528-515770016-299552555-2931096 (Group: MYDOMAIN/SomeGroup2)
Attributes - Mandatory Default Enabled
07 S-1-5-21-518066528-515770016-299552555-3014318 (Group: MYDOMAIN/SomeGroup3)
Attributes - Mandatory Default Enabled
08 S-1-5-21-518066528-515770016-299552555-3053352 (Group: MYDOMAIN/Another Group)
Attributes - Mandatory Default Enabled
09 S-1-5-21-518066528-515770016-299552555-2966661 (Group: MYDOMAIN/TestGroup)
Attributes - Mandatory Default Enabled
10 S-1-5-21-2117033040-537160606-1609722162-17637 (Group: MYOTHERDOMAIN/someusers)
Attributes - Mandatory Default Enabled
11 S-1-5-21-518066528-515770016-299552555-3018354 (Group: MYDOMAIN/TestGroup2)
Attributes - Mandatory Default Enabled
12 S-1-5-21-518066528-515770016-299552555-3026602 (Group: MYDOMAIN/SomeGroup4)
Attributes - Mandatory Default Enabled
13 S-1-5-21-518066528-515770016-299552555-2926570 (Group: MYDOMAIN/YetAnotherGroup)
Attributes - Mandatory Default Enabled
14 S-1-5-21-661411660-2927047998-133698966-513 (Group: MYDOMAIN/Domain Users)
Attributes - Mandatory Default Enabled
15 S-1-5-21-518066528-515770016-299552555-2986081 (Alias: MYDOMAIN/an_alias)
Attributes - Mandatory Default Enabled GroupResource
16 S-1-5-21-518066528-515770016-299552555-3037986 (Alias: MYDOMAIN/AReallyLongGroupName1)
Attributes - Mandatory Default Enabled GroupResource
17 S-1-5-21-518066528-515770016-299552555-3038991 (Alias: MYDOMAIN/AReallyLongGroupName2)
Attributes - Mandatory Default Enabled GroupResource
18 S-1-5-21-518066528-515770016-299552555-3037999 (Alias: MYDOMAIN/AReallyLongGroupName3)
Attributes - Mandatory Default Enabled GroupResource
19 S-1-5-21-518066528-515770016-299552555-3038983 (Alias: MYDOMAIN/AReallyReallyLongGroupName)
Attributes - Mandatory Default Enabled GroupResource
20 S-1-5-5-0-71188 (no name mapped)
Attributes - Mandatory Default Enabled LogonId
21 S-1-2-0 (Well Known Group: localhost/LOCAL)
Attributes - Mandatory Default Enabled
22 S-1-5-4 (Well Known Group: NT AUTHORITY/INTERACTIVE)
Attributes - Mandatory Default Enabled
23 S-1-5-11 (Well Known Group: NT AUTHORITY/Authenticated Users)
Attributes - Mandatory Default Enabled
Primary Group: S-1-5-21-518066528-515770016-299552555-513 (Group: MYDOMAIN/Domain Users)
Privs:
00 0x000000017 SeChangeNotifyPrivilege Attributes - Enabled Default
01 0x000000008 SeSecurityPrivilege Attributes -
02 0x000000011 SeBackupPrivilege Attributes -
03 0x000000012 SeRestorePrivilege Attributes -
04 0x00000000c SeSystemtimePrivilege Attributes -
05 0x000000013 SeShutdownPrivilege Attributes -
06 0x000000018 SeRemoteShutdownPrivilege Attributes -
07 0x000000009 SeTakeOwnershipPrivilege Attributes -
08 0x000000014 SeDebugPrivilege Attributes -
09 0x000000016 SeSystemEnvironmentPrivilege Attributes -
10 0x00000000b SeSystemProfilePrivilege Attributes -
11 0x00000000d SeProfileSingleProcessPrivilege Attributes -
12 0x00000000e SeIncreaseBasePriorityPrivilege Attributes -
13 0x00000000a SeLoadDriverPrivilege Attributes - Enabled
14 0x00000000f SeCreatePagefilePrivilege Attributes -
15 0x000000005 SeIncreaseQuotaPrivilege Attributes -
16 0x000000019 SeUndockPrivilege Attributes - Enabled
17 0x00000001c SeManageVolumePrivilege Attributes -
Authentication ID: (0,11691)
Impersonation Level: Anonymous
TokenType: Primary
Source: User32 TokenFlags: 0x9 ( Token in use )
Token ID: 18296 ParentToken ID: 0
Modified ID: (0, 18298)
RestrictedSidCount: 0 RestrictedSids: 00000000
关于内核模式TOKEN结构的更多信息,查看Mark Russinovich 和David Solomon编写的Microsoft Windows Internals。用户模式下TOKEN结构的更多信息,查看Microsoft Windows SDK 文档。
!tp 扩展用于显示线程池的信息。
!tp pool Address [Flags]
!tp tqueue Address [Flags]
!tp ItemType Address [Flags]
!tp ThreadType [Address]
!tp -?
Address
指定一个地址。
pool
显示位于Address 的整个线程池。如果Address是0,则显示所有的线程池。
tqueue
显示位于Address 的活动定时器队列(active timer queue)。
ItemType
指定要显示的线程池项(item)的类型。ItemType可以包含任意的下面这些可能的值:
obj
显示常规的内存池项 (例如IO项)。
timer
显示定时器项。
wait
显示等待项(wait item)。
work
显示工作项(work item)。
ThreadType
指定要显示的线程的类型。如果包含了Address,则只会显示该地址处的线程。 如果Address 为0,则指定类型的所有线程都会显示出来。如果省略Address,只显示当前线程(疑为进程 — 译者)关联的线程。ThreadType 可以包含任意下面这些可能的值:
waiter
显示线程池等待者线程(thread pool waiter thread)。
worker
显示线程池工作者线程(thread pool worker thread)。
Flags
指定显示中要包含的内容。可以是下面这些位值的和 (默认值为0x0):
Bit 0 (0x1)
单行显示。当显示ItemType 时,这一位的设置无效。
Bit 1 (0x2)
显示中包含成员信息(member information)。
Bit 2 (0x4)
显示中包含池工作队列(pool work queue)。这一位只有使用pool标志时才有意义。
-?
在调试器命令窗口中显示该扩展命令的简单帮助文本。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP和之后 |
Exts.dll |
关于线程池的更多信息,查看Microsoft Windows SDK 文档。
!triage 扩展命令已经废除。使用!analyze 来替代。
!ustr 扩展命令显示UNICODE_STRING结构。
!ustr Address
Address
指定UNICODE_STRING 结构的16进制地址。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP和之后 |
Ext.dll |
Unicode 字符串是由16位字符组成的,下面是结构的定义:
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
如果字符串是NULL结尾,则Length 不能包含NULL字符。
大多数Win32字符串参数在实际使用前都会转换成Unicode字符串。
UNICODE_STRING 结构的更多信息,查看Microsoft Windows SDK文档。
!version 扩展命令显示扩展DLL的版本信息。
该命令不能和 version (Show Debugger Version) 命令混淆。
![ExtensionDLL.]version
ExtensionDLL
指定要显示版本号的扩展DLL。
大多数扩展DLL都支持该命令。
如果扩展DLL的版本和调试器版本不匹配,则会显示错误信息。
该命令在Windows XP和之后版本的Windows中都不支持。要显示版本信息,应该使用version (Show Debugger Version) 命令。
该扩展命令原本的意图是用来确认DLL版本和目标版本匹配,因为在很多扩展中版本不匹配都会造成错误的结果。新的DLL不再限制为只支持一个版本的Windows,所以这个扩展命令已经废除。
cc682/NetRoc
http://netroc682.spaces.live.com/
!help 命令显示扩展DLL中的扩展命令的帮助文本。
不要将该命令和? (Command Help) 或.help (Meta-Command Help)混淆。
![ExtensionDLL.]help [-v] [CommandName]
ExtensionDLL
显示指定的扩展DLL的帮助。使用不带.dll扩展名的文件名。如果该DLL不在扩展搜索路径 (使用.chain (List Debugger Extensions)来显示)中,则需要包含路径。例如,要显示uext.dll的帮助,需要输入!uext.help 或!Path/winext/uext.help。
如果省略ExtensionDLL,调试器将显示已加载的扩展DLL列表中第一个的帮助文本。
-v
尽可能显示最详细的帮助文本。该功能可能不是每个DLL都支持。
CommandName
仅显示指定命令的帮助文本。不是所有DLL都支持该功能。
大多数扩展DLL都支持这条命令。
一些命令本身也可以在使用/?或者-? 参数时显示帮助文本。
!homedir 设置符号服务器和源码服务器使用的默认目录。
!homedir Directory
!homedir
Directory
指定要设置为主目录的新目录。
Windows NT 4.0 |
Dbghelp.dll |
Windows 2000 |
Dbghelp.dll |
Windows XP 和之后 |
Dbghelp.dll |
如果不带参数使用!homedir ,则显示当前的主目录。
如果没有特别指定的话,符号服务器的缓存位于主目录下的src 子目录。符号服务器的下游存储默认是在主目录下的sym子目录。
WinDbg启动时,主目录是Windows调试工具包安装目录。!homedir可以用来改变这个值。
!htrace 扩展用于显示一个或多个句柄的堆栈回溯信息。
用户模式语法
!htrace [Handle [Max_Traces]]
!htrace -enable [Max_Traces]
!htrace -snapshot
!htrace -diff
!htrace -disable
!htrace -?
内核模式语法
!htrace [Handle [Process [Max_Traces]]]
!htrace -?
Handle
指定要显示堆栈回溯的句柄。如果Handle 为0 或者省略,则显示进程中所有句柄的堆栈回溯。
Process
(仅内核模式) 指定要显示句柄的进程。如果Process 为0或者省略,则使用当前进程。用户模式下总是使用当前进程。
Max_Traces
指定要显示的堆栈回溯的最大层数。用户模式下如果省略该参数,则显示目标进程中的所有堆栈回溯。
-enable
(仅用户模式) 启用句柄跟踪,并且为-diff 选项使用的初始状态产生第一次句柄信息的快照。
-snapshot
(仅用户模式) 抓取当前的句柄信息的快照用作-diff 选项的初始状态。
-diff
(仅用户模式) 将当前的句柄信息和上一次句柄快照的信息进行对比。显示所有仍然打开的句柄。
-disable
(仅用户模式;仅Windows Server 2003和之后的系统) 禁止句柄跟踪。在Windows XP中,只有结束目标进程才能禁用句柄跟踪。
-?
在调试器命令窗口中显示一些简要的帮助文本。
Windows NT 4.0 |
不可用 |
Windows 2000 |
不可用 |
Windows XP 和之后 |
Kdexts.dll |
!htrace 能够使用之前,必须针对目标进程激活应用程序验证器(Application Verifier),并且必须选择 Detect invalid handle usage选项。通过激活应用程序验证器,进程每次打开句柄、关闭句柄或者饮用非法句柄时,都会保存堆栈回溯的信息。这就是!htrace 显示出来的那些堆栈回溯。详细信息,查看应用程序验证器。
下面的例子显示了进程0x81400300中所有句柄的信息:
kd> !htrace 0 81400300
Process 0x81400300
ObjectTable 0xE10CCF60
--------------------------------------
Handle 0x7CC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7CC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE23B2: KERNEL32!CreateSemaphoreA+0x66
0x010011C5: badhandle!main+0x45
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - BAD REFERENCE:
0x8018F709: ntoskrnl!ExMapHandleToPointerEx+0xEA
0x801E10F2: ntoskrnl!ObReferenceObjectByHandle+0x12C
0x801902BE: ntoskrnl!NtSetEvent+0x6C
0x80154965: ntoskrnl!_KiSystemService+0xC4
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE265C: KERNEL32!CreateEventA+0x66
0x010011A0: badhandle!main+0x20
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Parsed 0x6 stack traces.
Dumped 0x5 stack traces.
关于句柄的更多信息,查看Microsoft Windows SDK 文档,以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals 。要显示指定句柄的信息,查看!handle扩展命令。
!imggp 扩展显示64位映像的全局指针目录中的条目(global pointer (GP) directory entry)的值。
!imggp Address
Address
指定映像的基地址。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP 和之后 |
Ext.dll |
!imgreloc 扩展显示每个已加载模块的地址,以及重定位之前它们原本的地址。
!imgreloc Address
Address
指定映像的基地址。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP 和之后 |
Ext.dll |
下面是一个示例:
0:000> !imgreloc 00400000
00400000 Prymes - at preferred address
010e0000 appvcore - RELOCATED from 00400000
5b2f0000 verifier - at preferred address
5d160000 ShimEng - at preferred address
!kuser 扩展显示共享的用户模式页面 (KUSER_SHARED_DATA)。
!kuser
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP 和之后 |
Exts.dll |
KUSER_SHARED_DATA 页面包含当前登录用户的资源和其他信息。
这里是一个示例。注意例中tick count 使用原始格式和圆括号中的更可读的格式显示了两次。这种可读格式仅在Windows XP和之后的系统中可用。
kd> !kuser
_KUSER_SHARED_DATA at 7ffe0000
TickCount: fa00000 * 00482006 (0:20:30:56.093)
TimeZone Id: 2
ImageNumber Range: [14c .. 14c]
Crypto Exponent: 0
SystemRoot: 'F:/WINDOWS'
!list 扩展为链表中每个成员都执行指定的调试器命令。
!list -t [Module!]Type.Field -x "Commands" [-a "Arguments"] [Options] StartAddress
!list " -t [Module!]Type.Field -x /"Commands/" [-a /"Arguments/"] [Options] StartAddress "
!list -h
Module
用于指定定义该结构的模块的可选参数。如果Type 可能匹配另外的模块中的合法符号,则需要包含Module 来避免混淆。
Type
指定数据结构的名字。
Field
指定包含链表的字段。这实际上可以是以点号分隔的字段序列(即 Type.Field.Subfield.Subsubfield,等等)。
-x "Commands"
指定要执行的命令。可以是任何调试器命令的组合。必须用括号括起来。如果指定了多条命令,需要用分号来分隔它们,并且将整个!list 的参数集合用引号括起来,并且对引号中的其他引号使用转义字符( / )。如果省略Commands,默认命令是 dp (Display Memory)。
-a "Arguments"
指定传递给Commands的参数。必须包含在引号中。Arguments除了不能包含银号之外,可以是允许跟在命令后的任意合法参数的字符串。如果Commands 中包含伪寄存器$extret,可以省略 -a "Arguments" 参数。
Options
可以是任意数量的下面这些选项:
-e
回显对每个成员执行的命令。
-m Max
指定要执行命令的成员的最大个数。
StartAddress
指定第一个数据结构的地址。这可以是结构的首地址,而不一定必须是链表字段的地址。
-h
在调试器命令窗口中显示该扩展命令的简单帮助文本。
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP 和之后 |
Ext.dll |
!list 扩展将会遍历列表,并对每个成员执行指定命令。
$extret 伪寄存器的值会设置成每个成员的链表入口(list-entry)的地址。对每个成员,都会执行命令字符串Commands 。该命令字符串可以使用@$extret 语法来引用这个伪寄存器。如果没有在命令字符串中使用它,在执行之前链表入扣的地址会被添加到末尾。如果想控制这个值出现在命令的什么位置,则必须显式指定该伪寄存器。
命令序列会一直运行直到遇到以null指针标识的链表结束位置,或者指向第一个成员的位置。如果链表循环回了非第一个成员的位置,则命令不会 结束。但是,可以在KD和CDB中使用CTRL+C,或者 WinDbg中使用Debug | Break 或CTRL+BREAK 来停止。
每次执行命令时,如果命令字符串使用了可选的地址参数,则当前结构的地址会作为默认地址 。
下面是在用户模式下使用该命令的两个例子。注意内核模式下也可以使用但是语法不同。
首先是简单一点的例子,假设有一个名为MYTYPE 的结构,链表字段是.links.Flink 和.links.Blink。有一个从0x6BC000处的结构开始的链表。下面的命令会遍历该链表,并对每个成员执行一次dd L2 命令。由于dd 命令没有指定地址,所以会使用链表成员的地址。所以最后显示了每个结构的前两个DWORD。
0:000> !list -t MYTYPE.links.Flink -x "dd" -a "L2" 0x6bc00
下面是更复杂一些的例子用来说明$extret 的使用。它会遍历RtlCriticalSectionList 的_LIST_ENTRY 类型的链表。对每个成员,显示开头的4个DWORD,然后显示以链表成员的Flink 字段之前8个字节开始的_RTL_CRITICAL_SECTION_DEBUG 结构。
0:000> !list "-t ntdll!_LIST_ENTRY.Flink -e -x /"dd @$extret l4; dt ntdll!_RTL_CRITICAL_SECTION_DEBUG @$extret-0x8/" ntdll!RtlCriticalSectionList"
dd @$extret l4; dt ntdll!_RTL_CRITICAL_SECTION_DEBUG @$extret-0x8
7c97c0c8 7c97c428 7c97c868 01010000 00000080
+0x000 Type : 1
+0x002 CreatorBackTraceIndex : 0
+0x004 CriticalSection : (null)
+0x008 ProcessLocksList : _LIST_ENTRY [ 0x7c97c428 - 0x7c97c868 ]
+0x010 EntryCount : 0x1010000
+0x014 ContentionCount : 0x80
+0x018 Spare : [2] 0x7c97c100
dd @$extret l4; dt ntdll!_RTL_CRITICAL_SECTION_DEBUG @$extret-0x8
7c97c428 7c97c448 7c97c0c8 00000000 00000000
+0x000 Type : 0
+0x002 CreatorBackTraceIndex : 0
+0x004 CriticalSection : 0x7c97c0a0
+0x008 ProcessLocksList : _LIST_ENTRY [ 0x7c97c448 - 0x7c97c0c8 ]
+0x010 EntryCount : 0
+0x014 ContentionCount : 0
+0x018 Spare : [2] 0
!lmi 扩展显示某个模块的详细信息。
!lmi Module
Module
用名字或者基地址指定一个已加载的模块。
Windows NT 4.0 |
Dbghelp.dll |
Windows 2000 |
Dbghelp.dll |
Windows XP 和之后 |
Dbghelp.dll |
可以使用lm (List Loaded Modules) 命令获得模块基地址。
!lmi 扩展分析模块头,并格式化显示它包含的摘要信息。如果模块头被页换出了,则显示一条错误信息。要查看更多头信息,使用!dh 扩展命令。
该命令会显示很多具有不同标题的字段。某些标题有特殊的意义:
下面是一个例子:
0:000> lm
start end module name
00400000 0042d000 Prymes C (pdb symbols) Prymes.pdb
77e80000 77f35000 KERNEL32 (export symbols) C:/WINNT/system32/KERNEL32.dll
77f80000 77ffb000 ntdll (export symbols) ntdll.dll
0:000> !lmi 00400000
Loaded Module Info: [00400000]
Module: Prymes
Base Address: 00400000
Image Name: Prymes.exe
Machine Type: 332 (I386)
Time Stamp: 3c76c346 Fri Feb 22 14:16:38 2002
Size: 2d000
CheckSum: 0
Characteristics: 230e stripped
Debug Data Dirs: Type Size VA Pointer
MISC 110, 0, 77a00 [Data not mapped]
Symbol Type: EXPORT - PDB not found
Load Report: export symbols
例子中的Characteristics 行显示的缩写的说明,查看符号状态缩写。
cc682/NetRoc
http://netroc682.spaces.live.com/
!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。
-?
(仅用户模式) 在调试器命令窗口中显示该扩展的帮助文本。
Windows NT 4.0 |
Kdextx86.dll |
Windows 2000 |
Kdextx86.dll |
Windows XP 和之后 |
Kdexts.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
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 扩展显示堆使用信息,控制堆管理器中的断点,检测泄露的堆块,搜索堆块或者显示页堆(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] -?
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 后可跟alloc、realloc或者 free,用于指定断点是否在分配、重新分配或者释放内存时激活。如果BreakAddress 用来指定块的地址,可以省略断点类型。如果Heap用来指定堆地址或者堆序号,则必须包含类型和Tag参数。
Tag
指定堆中的标签名。
-B
使得调试器在堆管理器中移除一个条件断点。必须指定断点类型(alloc、 realloc或 free),并且必须和-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和之后的系统中可用。)
Windows NT 4.0 |
Ext.dll |
Windows 2000 |
Ext.dll |
Windows XP 和之后 |
Ext.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
_HEAP @ 00090000
in HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state
00099B58: 0018 : 0005 [01] - 00099B60 (000000B8) - (busy)
ole32!CALLFRAME_CACHE
下面的图表是堆块的格式。这是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。