cc682/NetRoc
http://netroc682.spaces.live.com/
!ca
!ca 扩展命令显示指定的节(section)的控制域(control area)。
语法
!ca Address
参数
Address
指定节的16进制地址。
DLL
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
!callback 扩展显示指定线程的陷阱(trap)相关的回调数据(callback data)。
语法
!callback Address [Number]
参数
Address
指定线程的16进制地址。如果为-1或者省略,则使用当前线程。
Number
指定需要的回调帧(callback frame)的数量。这些帧在显示中会标注出来。
DLL
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
!calldata 扩展以命名表(named table)中的函数调用统计(procedure call statistics)的形式显示性能信息。
语法
!calldata Table
参数
Table
用于搜集调用数据的表的名字。
DLL
Windows NT 4.0
|
Kdextx86.dll
|
Windows 2000
|
Kdextx86.dll
|
Windows XP和之后
|
Kdexts.dll
|
注释
在老版本的Windows NT 4.0中,使用调用数据(call data)来测量调用性能。
!can_write_kdump
!can_write_kdump 扩展用来验证目标机上是否有足够的磁盘空间用来创建指定类型的内核dump文件。
语法
!can_write_kdump [-dn] [Options]
参数
-dn
表示目标机上的文件系统是NTFS。如果省略该参数,就不能计算目标机上的磁盘空闲空间总数,会显示一条警告信息。但是,仍然会显示需要的空间数量。
Options
可以使用下面这些选项:
-t
表示要验证是否有足够空间用来创建minidump。
-s
表示要验证是否有足够空间用来创建摘要内核转储(summary kernel dump)。这是默认值。
-f
表示要验证是否有足够空间用于创建完整内核转储。
DLL
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
!cbreg 扩展显示CardBus Socket 寄存器,以及CardBus Exchangable Card Architecture (ExCA) 寄存器。
语法
!cbreg [%%]Address
参数
%%
表示Address 是一个物理地址而不是虚拟地址。
Address
指定要显示的寄存器地址。
DLL
Windows NT 4.0
|
不可用
|
Windows 2000
|
Kext.dll Kdextx86.dll
|
Windows XP和之后
|
Kext.dll
|
!cbreg 扩展仅对x86目标机可用。
附加信息
!exca扩展命令可以用来以套接字号(socket number)显示PCIC ExCA寄存器。
!cchelp
!cchelp 扩展用于在调试器命令窗口中显示一些缓存管理扩展命令的简要帮助文本。
语法
!cchelp
DLL
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
!chklowmem 扩展检查使用/pae 和/nolowmem选项引导的计算机上,4GB以下的物理内存页是否使用了指定的填充模板来填充。
语法
!chklowmem
DLL
Windows NT 4.0
|
不可用
|
Windows 2000
|
Kdextx86.dll
|
Windows XP和之后
|
Kdexts.dll
|
注释
该扩展命令在用于验证内核模式驱动是否在4GB分界线以上的物理内存上进行正确操作时有用。一般来说驱动程序将物理地址截断为32位,然后向4GB边界以下写入的时候会出现错误。!chklowmem 扩展命令可以检查对4GB边界以下的任何写入。
!cmreslist
!cmreslist 扩展显示指定的设备对象(device object)的CM_RESOURCE_LIST 结构。
语法
!cmreslist Address
参数
Address
指定CM_RESOURCE_LIST 结构的16进制地址。
DLL
Windows NT 4.0
|
不可用
|
Windows 2000
|
Kdextx86.dll
|
Windows XP和之后
|
Kdexts.dll
|
附加信息
查看Plug and Play 调试获得该扩展命令的应用。关于CM_RESOURCE_LIST 结构的更多信息,查看Windows Driver Kit (WDK)文档。
!cpuinfo
!cpuinfo 扩展显示目标机的CPU的详细信息。
语法
Windows 2000中的语法
!cpuinfo
Windows XP和之后的语法
!cpuinfo Processor
!cpuinfo
参数
Processor
(Windows XP和之后) 指定要显示的处理器。如果省了,则显示所有处理器。
DLL
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
!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
指定要显示的内存块个数。每个块的大小由使用的具体命令决定。
DLL
Windows NT 4.0
|
Kext.dll Kdextx86.dll
|
Windows 2000
|
Kext.dll Kdextx86.dll
|
Windows XP和之后
|
Kext.dll
|
注释
这些命令都用于显示物理内存,但是它们的显示格式和默认的长度不同:
- !db 扩展显示16进制字节值以及它们对应的ASCII字符。默认的长度为128字节。
- !dc 显示DWORD值和对应的ASCII字符。默认长度为32个DWORD (共128字节)。
- !dd 显示DWORD值。默认为32个DWORDs (共128字节)。
- !dp 显示ULONG_PTR 值。根据指令大小,可能是32位或者64位字。默认长度是一共128个字节。
- !dq 扩展显示ULONG64_PTR值。它们是32位字。默认长度为一共128字节。
- !du 扩展显示UNICODE字符。默认长度为16个字符(共32字节),或者直到遇到NULL字符。
- !dw扩展显示WORD值。默认长度为64个WORD (共128字节)。
因此,对这些扩展命令中的两个使用一样的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] <params>.
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 缓冲区的字符串。
语法
!dbgprint
DLL
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
!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(即不忽略任何位)。
DLL
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
!dcr 扩展显示指定地址处的默认控制寄存器(default control register (DCR))。
语法
!dcr Expression [DisplayLevel]
参数
Expression
指定要显示的DCR的16进制地址。@dcr 可以用作该参数。这种情况下,会显示当前处理器的DCR信息。
DisplayLevel
可以是下面这些选项中的一个:
0
只显示每个DCR字段的值。这是默认值。
1
对每个非保留和非忽略的DCR字段显示更深入的信息。
2
对所有DCR字段显示深入信息,包括被忽略或保留的那些。
DLL
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
!dcs 扩展已经废除。要显示PCI配置空间(configuration space),使用!pci 100 Bus Device Function。
!deadlock
!deadlock 扩展显示通过驱动程序验证器(Driver Verifier)的Deadlock Detection 选项搜集的死锁(deadlock)信息。
语法
!deadlock
!deadlock 1
DLL
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]
现在就知道了源文件的名字,以及请求锁的位置的行号。这种情况下,源文件表明了这些线程的行为如下:
- 线程1: DummyActivateVcComplete 获得了 dummy 小端口锁(miniport lock)。然后调用dummyQueueRecvBuffers,它会请求dummy global lock。
- 线程2: dummyRxInterruptOnCompletion 获得了global lock。然后,几行之后又请求小端口锁。
通过这点,死锁原因就清楚了。
附加信息
关于驱动程序验证器的信息,查看Windows Driver Kit (WDK) 文档。