NetRoc's Blog

N-Tech

 

WinDbg 文档翻译----76

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

注释

DbgPrintKdPrintDbgPrintEx、以及KdPrintEx 内核例程会向目标机的缓冲区发送一个格式化后的字符串。如果没有禁用的话,则该字符串会自动在主控机的调试器命令窗口中显示出来。

一般来说,发送给该缓冲区的信息都会自动在调试器命令窗口中显示出来。但是,这种显示可以通过全局标志实用程序 (gflags.exe)禁用。另外,这种显示不会在本地内核调试时显示。更多信息,查看DbgPrint缓冲区

!dbgprint 扩展使得缓冲区中的内容被显示出来(不管自动显示是否被禁用)。它不会显示被以组件和重要性级别过滤掉了的信息。 (关于这种过滤的详细信息,查看 读取和过滤调试信息。)

附加信息

关于DbgPrintKdPrintDbgPrintEx、以及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) 文档。

posted on 2008-07-20 14:27 NetRoc 阅读(871) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。

导航

统计

常用链接

留言簿(7)

随笔档案(99)

文章分类(35)

文章档案(32)

Friends

Mirror

搜索

最新评论

阅读排行榜

评论排行榜