Debugging Tools for Windows

!verifier

!verifier扩展命令显示驱动程序验证器(Driver Verifier)的状态和它的行为。

Driver Verifier在Windows 2000和之后版本的Windows中都包含。它在调试版和发行版系统中都可以使用。关于Driver Verifier的信息,查看Windows Driver Kit (WDK) 文档中的Driver Verifier主题。

语法

Windows 2000的语法

!verifier [Flags [Image]] 

Windows XP和之后的语法

!verifier [Flags [Image]] 
!verifier 4 [Quantity
!verifier 8 [Quantity
!verifier 0x20 [CompletionTime CancelTime ForceCancellation
!verifier 0x40 [Quantity
!verifier 0x80 [Quantity]
!verifier 0x80 Address
!verifier 0x100 [Quantity]
!verifier 0x100 Address
!verifier ? 

参数

Flags
指定命令输出中显示哪些信息。如果Flags的值等于4、 8、 0x20、0x40、 0x80、或者0x100,那么!verifier其他的参数是根据这些标志指定的值来解析的。如果Flags是任何其他的值,即使设置了这些位中的一个或几个,也只允许使用FlagsImage参数。Flags可以是这些bit值的和,默认为0:
Bit 0 (0x1)
显示被验证的所有驱动程序的名字。同时还会显示当前分配给每个驱动的分页和非分页池的字节数。
Bit 1 (0x2)
显示内存池的信息(pool size、 headers和pool tags),以及已卸载驱动遗留下来的还未释放掉(outstanding)的内存。如果没有同时设置bit 0(0x1),则这个flag无效
Bit 2 (0x4)
(Windows XP和之后) 显示fault injection information。每个分配(each allocation)的代码的返回地址、符号名字和偏移都会显示出来。如果Flags刚好是0x4 并且使用了Quantity参数,则可以选择显示的记录的数量。否则,会显示4条记录。
Bit 3 (0x8)
(Windows XP和之后) 显示被验证的驱动程序最近的一次IRQL改变。包括旧IRQL、新IRQL、处理器和时间戳。如果Flags刚好是0x8并且包含了Quantity参数,则可以选择显示出来的记录个数,否则会显示4条记录。
Bit 5 (0x20)
(Windows Vista和之后) 显示和驱动程序验证器的Driver Hang Verification选项相关的信息。如果指定了CompletionTimeCancelTime、和ForceCancellation参数,它们会替换先前的Driver Hang Verification 设置。
Bit 6 (0x40)
(Windows Vista和之后) 显示驱动程序验证器的Force Pending I/O Requests选项的信息,包括从forced pending IRP日志中获得的纪录。 

Quantity参数指定要显示的记录个数。默认情况下会显示整个日志。

Bit 7 (0x80)
(Windows Vista和之后) 显示kernel pool Allocate/Free log 的信息。

Quantity参数指定显示的记录数量。默认情况下显示整个日志。

如果指定了Address,则只显示kernel pool Allocate/Free log 中和这个地址相关的信息。

Bit 8 (0x100)
(Windows Vista和之后) 显示IoAllocateIrp 、IoCompleteRequest 和IoCancelIrp 调用的日志信息。

Quantity参数指定要显示的记录条数,默认显示所有记录。

如果指定了Address,则只显示和指定的IRP关联的记录。

Image
如果使用了Flags,并且不等于4、 8或0x10, Image用于指定驱动程序的名字。Image用来过滤Flags值为0x1和0x2时显示的信息:只保留指定的驱动程序。这个驱动程序必须当前是被验证状态。
Quantity
(Windows XP和之后) 如果Flags恰好等于0x4, Quantity指定要显示的fault injection records的数量。如果Flags恰好等于0x8, Quantity指定要显示的IRQL日志的条数。如果Flags刚好为0x40,Quantity指定显示的forced pending IRP日志中的记录条数。如果Flags刚好为0x80,Quantity指定要显示的kernel pool Allocate/Free log 记录条数。如果Flags等于0x100,Quantity指定要显示的IoAllocateIrp 、IoCompleteRequest 和IoCancelIrp 调用日志的记录条数。
CompletionTime
(Windows Vista和之后) 指定IRP完成的时间限制,以毫秒为单位。默认值为0x2710 (10 秒)。如果驱动程序超出了这个限制,则会在 Driver Hang Verification 日志中记录completion routine。当CompletionTime为0时,Driver Verifier 不会监视IRP完成。Driver Hang Verification 参数仅在Flags设置为0x20时才支持。
CancelTime
(Windows Vista和之后) 指定取消(canceling)一个IRP的时间限制,以毫秒为单位。默认值为0x1388 (5 秒)。如果驱动超出这个限制,则Driver Hang Verification日志中会记录cancellation routine。CancelTime0时,Driver Verifier不会监视IRP的取消。 Driver Hang Verification参数仅在Flags设置为0x20时支持。
ForceCancellation
(Windows Vista和之后) 启用或禁用对CompletionTime时间内没有完成的IRP的取消(cancellation)。 将ForceCancellation设置为1来启用强制取消(forced cancellation)。ForceCancellation设置为0来禁用强制取消。默认值为0。Driver Hang Verification参数仅在Flags为 0x20时可用。
?
(Windows XP和之后) 在调试器命令窗口中显示该扩展命令的简单帮助。

DLL

Windows NT 4.0 Unavailable
Windows 2000 Kdextx86.dll
Windows XP和之后 Kdexts.dll

注释

用驱动程序验证器来测试图形驱动程序时,要使用!gdikdx.verifier扩展命令来替代!verifier

4、 8、0x20、 0x40、 0x80和0x100 是Flags的特殊值。使用这些值的时候,会用到参数部分列出的特殊参数,并且只会显示和这些标志值相关的信息。

如果Flags使用了任何其他值,即使设置了这些特殊位的一个或者多个,也只允许使用FlagsImage参数。这种情况下,除了其他信息之外,!verifier还会显示激活的驱动程序验证器选项,以及内存池分配、IRQL提升、自旋锁和 trims 的统计。

如果Flags等于0x20,驱动程序验证器的Driver Hang Verification选项将使用CompletionTimeCancelTimeForceCancellation。这些新的值会立即生效并且持续到下一次启动。重新启动计算机时,它们会恢复到默认值。

同样,如果Flags等于0x20 (使用或不使用附加参数),则打印Driver Hang Verification日志。关于对这个日志的解读,查看Windows Driver Kit (WDK)文档中驱动程序验证器文档的Driver Hang Verification小节。

下面是Windows XP计算机上!verifier扩展命令的示例。注意输出是按照驱动程序名排序:

kd> !verifier 0xf

Verify Level 1f ... enabled options are:
      special pool
      special irql
      inject random pool failures
      all pool allocations checked on unload
      Io subsystem checking enabled

Summary of All Verifier Statistics

RaiseIrqls                             0x0
AcquireSpinLocks                       0x22a
Synch Executions                       0xbcd7
Trims                                  0x20e

Pool Allocations Attempted             0x48
Pool Allocations Succeeded             0x48
Pool Allocations Succeeded SpecialPool 0x48
Pool Allocations With NO TAG           0x0
Pool Allocations Failed                0x0
Pool Allocations Failed Deliberately   0x0

Current paged pool allocations         0x8 for 000002D8 bytes
Peak paged pool allocations            0xa for 00000494 bytes
Current nonpaged pool allocations      0xb for 00003038 bytes
Peak nonpaged pool allocations         0xb for 00003038 bytes

Driver Verification List

Entry     State           NonPagedPool   PagedPool   Module

fe527df8 Loaded           00002094       000002b8    ftdisk.sys

Current Pool Allocations  00000007    00000005
Current Pool Bytes        000002b8    00002094
Peak Pool Allocations     00000009    00000005
Peak Pool Bytes           00000338    00002094

PoolAddress  SizeInBytes    Tag       CallersAddress
f7b1bff0     0x00000010     ScFt      fdbac7af
f7b1df88     0x00000078     ScFt      fdbb6e9f
f7bfbfd0     0x00000030     ScFt      fdbac7af
fe4e4000     0x00002000     ScFt      fdba01e6
f7c19ff8     0x00000004     ScFt      fdba2677
f7c2bfb0     0x00000050     ScFt      fdbac2c1
f7c2df60     0x000000a0     ScFt      fdba672e
f7c47fe0     0x00000020     ScFt      fdba6968
f7c73f60     0x000000a0     ScFt      fdba672e
f7c8dfe0     0x00000020     ScFt      fdba6968
f7cb9f60     0x000000a0     ScFt      fdba672e
f7cd3fe0     0x00000020     ScFt      fdba6968

fe527d68 Loaded           00000f84       00000000    i8042prt.sys

Current Pool Allocations  00000000    00000005
Current Pool Bytes        00000000    00000f84
Peak Pool Allocations     00000002    00000005
Peak Pool Bytes           000001bc    00000f84

PoolAddress  SizeInBytes    Tag       CallersAddress
f8a6ff40     0x000000c0     8042      fdde2eec
f8a71f88     0x00000074     8042      fdde2f3e
f8cf1b50     0x000004b0     8042      fdddf64c
f93bb6a0     0x00000960     8042      fdde0990
f93b9fc0     0x00000040     8042      fdddfd0e

fe527cd8 Loaded           00000020       00000020    flpydisk.sys

Current Pool Allocations  00000001    00000001
Current Pool Bytes        00000020    00000020
Peak Pool Allocations     00000001    00000001
Peak Pool Bytes           00000020    00000020

PoolAddress  SizeInBytes    Tag       CallersAddress
f93abfe0     0x00000020     Flop      fdf5dcb5
f93affe0     0x00000020     Flop      fdf5b75d

----------------------------------------------- 
Fault injection trace log                       
----------------------------------------------- 
No fault injection traces found. 
----------------------------------------------- 
Track irql trace log                            
----------------------------------------------- 

Size of track irql queue is 0x80 

Thread:             FFFFFFFFFE4FA880
Old irql:           0
New irql:           2
Processor:          0
Time stamp:         5B97C

    FFFFFFFF80535D9E ntoskrnl!VerifierKfAcquireSpinLock+0x28
    FFFFFFFFFDB9ED56 +0xfffffffffdb9ed56
    FFFFFFFFFDB9F2CA +0xfffffffffdb9f2ca
    FFFFFFFF804175BD ntoskrnl!IopfCallDriver+0x31
    FFFFFFFFFDBEA69B +0xfffffffffdbea69b

Thread:             FFFFFFFFFE4FA880
Old irql:           2
New irql:           0
Processor:          0
Time stamp:         5B979

    FFFFFFFF80535E57 ntoskrnl!VerifierKfReleaseSpinLock+0x67
    FFFFFFFFFDB9EEED +0xfffffffffdb9eeed
    FFFFFFFFFDB9F2CA +0xfffffffffdb9f2ca
    FFFFFFFF804175BD ntoskrnl!IopfCallDriver+0x31
    FFFFFFFFFDBEA69B +0xfffffffffdbea69b

Thread:             FFFFFFFFFE4FA880
Old irql:           0
New irql:           2
Processor:          0
Time stamp:         5B979

    FFFFFFFF80535D9E ntoskrnl!VerifierKfAcquireSpinLock+0x28
    FFFFFFFFFDB9ED56 +0xfffffffffdb9ed56
    FFFFFFFFFDB9F2CA +0xfffffffffdb9f2ca
    FFFFFFFF804175BD ntoskrnl!IopfCallDriver+0x31
    FFFFFFFFFDBEA69B +0xfffffffffdbea69b

Thread:             FFFFFFFFFE4FA880
Old irql:           2
New irql:           0
Processor:          0
Time stamp:         5B974

    FFFFFFFF80535E57 ntoskrnl!VerifierKfReleaseSpinLock+0x67
    FFFFFFFFFDB9EEED +0xfffffffffdb9eeed
    FFFFFFFFFDB9F2CA +0xfffffffffdb9f2ca
    FFFFFFFF804175BD ntoskrnl!IopfCallDriver+0x31
    FFFFFFFFFDBEA69B +0xfffffffffdbea69b

下面是!verifier扩展命令在Windows Vista计算机上打开了bit 7并且指定Address的示例。

0: kd> !verifier 80 a2b1cf20
Parsing 00004000 array entries, searching for address a2b1cf20.
=======================================
Pool block a2b1ce98, Size 00000168, Thread a2b1ce98
808f1be6 ndis!ndisFreeToNPagedPool+0x39
808f11c1 ndis!ndisPplFree+0x47
808f100f ndis!NdisFreeNetBufferList+0x3b
8088db41 NETIO!NetioFreeNetBufferAndNetBufferList+0xe
8c588d68 tcpip!UdpEndSendMessages+0xdf
8c588cb5 tcpip!UdpSendMessagesDatagramsComplete+0x22
8088d622 NETIO!NetioDereferenceNetBufferListChain+0xcf
8c5954ea tcpip!FlSendNetBufferListChainComplete+0x1c
809b2370 ndis!ndisMSendCompleteNetBufferListsInternal+0x67
808f1781 ndis!NdisFSendNetBufferListsComplete+0x1a
8c04c68e pacer!PcFilterSendNetBufferListsComplete+0xb2
809b230c ndis!NdisMSendNetBufferListsComplete+0x70
8ac4a8ba test1!HandleCompletedTxPacket+0xea
=======================================
Pool block a2b1ce98, Size 00000164, Thread a2b1ce98
822af87f nt!VerifierExAllocatePoolWithTagPriority+0x5d
808f1c88 ndis!ndisAllocateFromNPagedPool+0x1d
808f11f3 ndis!ndisPplAllocate+0x60
808f1257 ndis!NdisAllocateNetBufferList+0x26
80890933 NETIO!NetioAllocateAndReferenceNetBufferListNetBufferMdlAndData+0x14
8c5889c2 tcpip!UdpSendMessages+0x503
8c05c565 afd!AfdTLSendMessages+0x27
8c07a087 afd!AfdTLFastDgramSend+0x7d
8c079f82 afd!AfdFastDatagramSend+0x5ae
8c06f3ea afd!AfdFastIoDeviceControl+0x3c1
8217474f nt!IopXxxControlFile+0x268
821797a1 nt!NtDeviceIoControlFile+0x2a
8204d16a nt!KiFastCallEntry+0x127

附加信息

关于驱动程序验证器的信息,查看Windows Driver Kit (WDK)文档。

Build machine: CAPEBUILD