カーネル デバッグを使用した、Device Fundamentals 信頼性テストのエラーのデバッグ
ここでは、一般的なカーネルデバッグコマンドを使用して、Device Fundamentals 信頼性テストのエラーをデバッグする方法について説明します。
シンボルを設定する
Windows Hardware Lab Kit のコンテンツ シンボルは、Microsoft Public Symbols Server サイトで確認することができます。 Microsoft Public Symbols Server についての詳細は、「Microsoft Symbol Serverを使用してデバッグ用シンボルファイルを取得する」を参照してください。 .sympath (Set Symbol Path) のコマンドを実行することで、カーネル デバッガーにシンボルを設定することができます。
例:
この例では、.sympath のコマンドはデバッガー内のパブリック シンボル サーバー パスを設定します。
.sympath SRV*c:\localsymbols*https://msdl.microsoft.com/download/symbols
!analyze -v
カーネル デバッガーによるシステムバグチェックに起因するテストのエラーを調査する際、シンボルを設定した後に最初に実行すべきコマンドは !analyze です。 このコマンドは、バグチェックコード、バグチェックの理由、障害コンポーネントを示すスタックトレースを特定します。 このコマンドの詳細については、「!analyze 拡張機能の使用」 を参照してください。
テスト プロセスのスタック トレースを検査する
Device Fundamentals 信頼性テストのエラーのデバッグは、多くの場合、試験用コンピューター上で Te.ProcessHost.exeまたは Te.exe として実行されます。 システムのバグチェックやテストのハングを調査する際に、これらのテストプロセスのスタックトレースを確認することは有益です。 バグチェックの場合、スタックトレースから、クラッシュ時にテストされていたテストケースを特定することができます。 テストがハングアップした場合、スタックトレースにより、テストの進行を妨げているテストスレッドが特定されます。
テスト・コンピュータで実行中のすべてのプロセスをリストするために、!process 0 0 拡張機能を使用して、テスト プロセス EPROCESS ブロック アドレスを見つけることができます。
その後、!process /p /r 拡張機能を使用して、テストプロセスから完全なスタックトレースを取得することができます。
!process 拡張機能 の詳細については、「 !process および .process (Set Process Context) 」を参照してください。
!process の出力には、プロセスで実行している各スレッドのティックカウントが含まれることに注意してください。 テストのハングを調査する際、スタック上に WDTF コンポーネントを含む ティック数が多いスレッド(つまり、スタック上に 「WDTF」で始まるモジュール名)を慎重に検討すべきです。これらのスレッドは、タイムアウトにより、テストが恒久的にハングし最終的に失敗する原因になることがあるからです。
例:
この例では、!process 0 0、!process /p /r、 および !processで、テストスレッドのティック数が非常に多く、テストの進行が妨げられていることを特定しています。
!process 0 0 Te.ProcessHost.exe
PROCESS fffffa80093c6340
SessionId: 1 Cid: 1320 Peb: 7f6595b3000 ParentCid: 12a0
DirBase: 21eee000 ObjectTable: fffff8a0035b0a00 HandleCount: 327.
Image: TE. ProcessHost.exe
.process /p /r fffffa80093c6340
!process fffffa80093c6340
THREAD fffffa800b2be8c0 Cid 0964.0eac Teb: 000007f601ba6000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable
fffffa800b2a11d0 SynchronizationEvent
fffffa800b300640 SynchronizationEvent
Not impersonating
DeviceMap fffff8a0014b9c80
Owning Process fffffa800b302940 Image: TE.exe
Attached Process N/A Image: N/A
Wait Start TickCount 210995 Ticks: 405945 (0:01:45:32.782)
Context Switch Count 51 IdealProcessor: 2
UserTime 00:00:00.015
KernelTime 00:00:00.015
Win32 Start Address WDTFInterfaces!TsSingleWorkerThread (0x000007fe3a567f28)
Stack Init fffff8800eb5edd0 Current fffff8800eb5dee0
Base fffff8800eb5f000 Limit fffff8800eb59000 Call 0
Priority 9 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
Kernel stack not resident.
Child-SP RetAddr Call Site
fffff880`0eb5df20 fffff803`78b27f7c nt!KiSwapContext+0x76
(Inline Function) --------`-------- nt!KiSwapThread+0xf4 (Inline Function @ fffff803`78b27f7c)
fffff880`0eb5e060 fffff803`78aaf4ab nt!KiCommitThreadWait+0x23c
fffff880`0eb5e120 fffff803`78b257a0 nt!KiWaitForAllObjects+0x3bb
fffff880`0eb5e3c0 fffff803`78ecb3dc nt!KeWaitForMultipleObjects+0x4ae
fffff880`0eb5e470 fffff803`78ecb853 nt!ObWaitForMultipleObjects+0x29c
fffff880`0eb5e980 fffff803`78aff053 nt!NtWaitForMultipleObjects+0xe3
fffff880`0eb5ebd0 000007fe`45d2315b nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ fffff880`0eb5ec40)
00000083`7cdef148 000007fe`430912c6 ntdll!ZwWaitForMultipleObjects+0xa
00000083`7cdef150 000007fe`368641b5 KERNELBASE!WaitForMultipleObjectsEx+0xe5
00000083`7cdef430 000007fe`3a566793 WDTFAudioSimpleIoAction!CAudioImpl::RunIO+0x3d1
00000083`7cdef520 000007fe`3a566ea0 WDTFInterfaces!CSimpleIOEx::PerformIO+0x10f
00000083`7cdef5b0 000007fe`3a56706b WDTFInterfaces!CSimpleIOExWrap::PerformIO+0x28
00000083`7cdef5e0 000007fe`3a553fe5 WDTFInterfaces!CMTest_Receiver::Run+0x77
00000083`7cdefe20 000007fe`3a5578ac WDTFInterfaces!CSimpleIO_MTestEx::ActionThread+0x105
00000083`7cdefeb0 000007fe`3a567f3e WDTFInterfaces!CMTEXThread::ThreadWorker+0xc
00000083`7cdefee0 000007fe`4319167e WDTFInterfaces!TsSingleWorkerThread+0x16
00000083`7cdeff20 000007fe`45d3c3f1 KERNEL32!BaseThreadInitThunk+0x1a
00000083`7cdeff50 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
スレッドとフレームにコンテキストを切り替えてローカルを表示する
スタックフレームからローカル変数を表示するには、次の操作を行う必要があります。
..thread (レジスタ コンテキストの設定)コマンドを使用して}、コンテキストをスレッドに切り替えます。
kn コマンドを使用して、スタックをフレーム番号とともにダンプします(スタックとダンプのログを参照のこと)。
.frame (ローカル コンテキストの設定) コマンドを使用して、フレームコンテキストに切り替えます。
dv (ローカル変数の表示) コマンドでローカルを表示します。
Note
ローカル変数のダンプには、プライベートシンボルを使用する必要があります。
例:
この例では、.thread、kn、.frame、およびdv コマンドを使用して、スタックフレームからローカル変数をダンプしています。
3: kd> .thread fffffa8009da7b00
Implicit thread is now fffffa80`09da7b00
3: kd> kn
*** Stack trace for last set context - .thread/.cxr resets it
# Child-SP RetAddr Call Site
00 fffff880`054a03a0 fffff801`05caaf7c nt!KiSwapContext+0x76
01 fffff880`054a04e0 fffff801`05ca8d9f nt!KiCommitThreadWait+0x23c
02 fffff880`054a05a0 fffff801`05f98841 nt!KeWaitForSingleObject+0x1cf
03 fffff880`054a0630 fffff801`061f253d nt!IopCancelAlertedRequest+0x71
04 fffff880`054a0670 fffff801`0604fc5d nt! ?? ::NNGAKEGL::`string'+0x1caaf
05 fffff880`054a0860 fffff801`060552b8 nt!ObpLookupObjectName+0x7a1
06 fffff880`054a0990 fffff801`06066ebe nt!ObOpenObjectByName+0x258
07 fffff880`054a0a60 fffff801`06067609 nt!IopCreateFile+0x37c
08 fffff880`054a0b00 fffff801`05c82053 nt!NtCreateFile+0x79
09 fffff880`054a0b90 000007fa`1a4930fa nt!KiSystemServiceCopyEnd+0x13
0a 00000038`d21bb478 000007fa`0677feef ntdll!NtCreateFile+0xa
0b 00000038`d21bb480 000007fa`0678e9a2 WDTFFuzzTestAction!DPETryOpenDevice+0x2b3
0c 00000038`d21bcde0 000007fa`0678e892 WDTFFuzzTestAction!CWDTFFuzz_MTestImpl::AttemptToOpenSurface+0x66
0d 00000038`d21bce50 000007fa`0678b84c WDTFFuzzTestAction!CWDTFFuzz_MTestImpl::FindAttackSurfaces+0x16e
0e 00000038`d21bf6c0 000007fa`0678a4d9 WDTFFuzzTestAction!CWDTFFuzz_MTestImpl::ActionThread+0x200
0f 00000038`d21bf760 000007fa`1a17167e WDTFFuzzTestAction!ActionThreadStart+0x9
10 00000038`d21bf790 000007fa`1a4ac3f1 KERNEL32!BaseThreadInitThunk+0x1a
11 00000038`d21bf7c0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
3: kd> .frame b
0b 00000038`d21bb480 000007fa`0678e9a2 WDTFFuzzTestAction!DPETryOpenDevice+0x2b3
3: kd> dv
szName = 0x00000038`d21bce90
bSync = 0n0
ppdevice = 0x00000038`d21bce10
messageBuffer = wchar_t [2048] "Attempting to open device : \DosDevices\root#multiportserial#0000#{05caff94-7b1e-420c-8c70-d8361bc4ee0a}"
oa = struct _OBJECT_ATTRIBUTES
!pnptriage
Device Fundamentals 信頼性テストのハングをデバッグする場合、!pnptriage コマンドを使用すると、アクティブな PNP スレッドを一覧表示することができます。 !pnptriage の出力には、システムで動作している各 PNP スレッドのティックカウントが含まれることに注意してください。 テストのハングを調査する場合、ティック数が多いスレッドを慎重に調査する必要があります。これらのスレッドは、テストが永久にハングし、最終的にはタイムアウトにより失敗する可能性があります。
ドライバーデバッグ拡張機能
以下のカーネルデバッガー拡張機能は、Device Fundamentals 信頼性テストの実行時に発生する可能性のあるドライバーの問題をデバッグできます。 !drvobj、!devnode、!devobj、!devstack、および !irp これらの拡張機能の詳細については、「カーネルモード拡張機能」を参照してください。
デバッガー拡張機能
Windows 用デバッグ ツールには、以下の種類のドライバーに対してテストを実行したときに発生する可能性のあるエラーのトラブルシューティングに役立つ、追加のデバッガー拡張機能が付属しています: USB、Storage、NDIS, Graphics、Kernel-Mode Driver Framework (KMDF)、 および User-Mode Driver Framework (UMDF) これらの拡張機能の詳細については、「特殊な拡張機能」を参照してください。 Windows用のデバッグツールの詳細については、「Windows用デバッグツールのダウンロードとインストール」を参照してください。