WDK を使った Device Fundamental テストのトラブルシューティング

このトピックでは、WDK を使って Device Fundamental テストを実行したときに発生する可能性のある問題の解決策について説明します。 テストとテストの実施方法について詳しくは、「Device Fundamental テストを選んで構成する方法」、「Visual Studio を使って実行時にドライバーをテストする方法」、「コマンド プロンプトから実行時にドライバーをテストする方法」をご覧ください。

  HCK を使った Device.Fundamentals テストのトラブルシューティングについて詳しくは、Windows HCK を使った Device Fundamental の信頼性テストのトラブルシューティングに関するページをご覧ください。

 

  • Device Fundamental テストに失敗する (全般)
  • ドライバーの検証ツールが有効になっていない
  • テストが応答しない、または実行されない
  • デバイスの突然の削除 PnP テストに失敗する
問題: Device Fundamental テストに失敗する (全般)

 

エラー状況:

テストに失敗しているか、テストを実行できません。デバイスの 種類によっては、Device Fundamental テストを実行するための特定の要件がある場合があります。これらの要件は、Windows ハードウェア認定キット (HCK) を使うときに従う必要がある要件と同じです。

次の Device Fundamental テストを実行する前に、特定のデバイスの種類について説明された要件に従って、テスト コンピューターのデバイスを構成する必要があります。

  • PCI ルート ポートの突然の削除テスト (PCI デバイスのみ)
  • Device Path Exerciser テスト (認定)
  • 前後の I/O を伴うスリープと PNP (無効化/有効化) (認定)
  • プラグ アンド プレイ ドライバー テスト (認定)
  • CHAOS (Concurrent Hardware And Operating System) テスト (認定)
  • 再インストールと前後の I/O テスト (認定)
  • ファイル システムの一貫性に関するデバイス インストール チェック (認定)
  • その他のデバイスの安定性に関するデバイス インストール チェック (認定)

解決策:

テストの実施に関する特定のデバイスの要件については、「提供されている WDTF シンプル I/O プラグイン」をご覧ください。 Device Fundamental テストでは、テストの効果を高めるために、提供されている WDTF シンプル I/O プラグインを使ってデバイス固有の I/O 操作を実行します。 プラグインで実行される I/O の種類と、特別なデバイス要件の有無については、次のリンクを使ってください。テストの失敗をデバッグ、トリアージするために従うことができる特定のトリアージ手順がある場合は、デバイスの種類に対応したそれらの手順も表示されます。

問題: ドライバーの検証ツールが有効になっていない

 

エラー メッセージ:

"テスト中のデバイスのすべてのドライバー (上位/下位フィルター ドライバーを含む) で、少なくとも標準の設定でドライバーの検証ツールが有効になっていません。少なくとも標準の設定でドライバーの検証ツールを有効にして、テストを再実行する必要があります。"

解決策:

実行中の Device Fundamental テストでは、テスト対象のデバイスに関連付けられたドライバーをドライバーの検証ツールが監視する必要があります。次のような 2 つのオプションがあります。

  • Enable Driver Verifier (ドライバーの検証ツールの有効化) テストをテスト グループに追加して、実行中の Device Fundamental テストで指定したのと同じ DQ パラメーターを指定します。
  • ドライバーの検証ツール (Verifier.exe) を手動で使って、テスト中のデバイスの個々のドライバーすべてで、ドライバーの検証ツールを有効にします。ドライバーの検証ツールの標準設定を使う必要があります。 どのドライバーでドライバーの検証ツールが必要になるかを判別するには、テスト コンピューターでデバイス マネージャー (Devmgmt.msc) を開きます。デバイス マネージャーで、テスト中のデバイスを右クリックして、[プロパティ] をクリックします。[ドライバー] タブをクリックし、[ドライバーの詳細] をクリックして、ドライバーの名前を特定します。ネットワーク クラス デバイスでは、ドライバーの検証ツールも Ndis.sys で有効になっている必要があります。
問題: テストが応答しない、または実行されない

 

エラー状況:

テストは応答しません (テスト コマンド ウィンドウで明らかな進展が見られない) が、システムは応答します。

解決策:

カーネル デバッガーに接続されたテスト システムでテストを実行します。テストの進行が停止しているように見えるときにデバッガーに割り込みます。Te.ProcessHost.exe プロセスで実行されているスタック上で "ティック数" (ティック) が多く、"WDTF" があるスレッドを確認します。Te.ProcessHost.exe プロセスが存在しない場合、Te.exe プロセスで実行されているスレッドを確認します。

!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

Te.ProcessHost.exe で実行されているすべてのスレッドを表示し、スタック上の WDTF* を使ったスレッドを探すには

!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

応答しなくなった PnP テストと電源管理テストをデバッグする場合、テストの進行を妨げている可能性があるアクティブな PnP スレッドと電源スレッドを特定するのに役立つ、次の 2 つのカーネル デバッガー コマンドを使うことができます。

!pnptriage

!poaction
問題: デバイスの突然の削除 PnP テストに失敗する

 

エラー メッセージ:"Failed to receive IRP_MN_REMOVE_DEVICE after receiving IRP_MN_SURPRISE_REMOVAL (IRP_MN_SURPRISE_REMOVAL を受け取った後に IRP_MN_REMOVE_DEVICE を受け取れませんでした)"

解決策:

PnP マネージャーが突然の削除 IRP を送った後、削除 IRP をテスト デバイス スタックに送らない場合、デバイスの突然の削除 PnP テスト (「PnP テスト (Device Fundamental)」をご覧ください) は失敗し、次のエラー メッセージが表示されることがあります。

"Failed to receive IRP_MN_REMOVE_DEVICE after receiving IRP_MN_SURPRISE_REMOVAL. Ensure that there are no open handles or references to the test device (in user mode or in kernel mode) preventing IRP_MN_REMOVE_DEVICE from being sent. You may need to terminate any processes or services that may have open user mode handles to this device."

PnP マネージャーは、デバイスに対するすべての未処理のファイル ハンドルが閉じられるまで、IRP_MN_REMOVE_DEVICE 要求を送りません。つまり、PnP マネージャーは、PDO の参照カウントがゼロになるまで、IRP_MN_REMOVE_DEVICE 要求を送りません。IRP_MN_SURPRISE_REMOVAL 要求の適切な処理方法について詳しくは、「IRP_MN_SURPRISE_REMOVAL 要求の処理」をご覧ください。

このテストの失敗をデバッグできるように、物理デバイス オブジェクト (PDO) の参照カウントが変更されるしくみを確認する必要があります。つまり、参照カウントを変更しているプロセスを特定し、参照カウントが変更されるとコール スタックがどのようになるかを調べる必要があります。この失敗をデバッグするには、次の手順を実行できます。

  1. まだデバッグしていない場合は、テスト コンピューターにカーネル デバッガーを接続します。 「ドライバーの展開およびテストのためのコンピューターのプロビジョニング (WDK 8.1)」をご覧ください。

  2. テスト デバイスの PDO の参照カウントが保存される場所に ba (Break on Access) breakpoint を設定します。 アクセス ブレークポイントについて詳しくは、「プロセッサ ブレークポイント (ba ブレークポイント)」をご覧ください。次の例では、!devnode カーネル デバッガー コマンドを使って、USBvideo ドライバーの devnode に関する情報を取得します。この devnode の PDO のアドレスは 0x849e9648 です。

    0: kd> !devnode 0 1 usbvideo
    Dumping IopRootDeviceNode (= 0x848fadd8)
    DevNode 0x849e9448 for PDO 0x849e9648
      InstancePath is "USB\VID_045E&PID_076D&MI_00\7&1243e0b7&0&0000"
      ServiceName is "usbvideo"
      State = DeviceNodeStarted (0x308)
      Previous State = DeviceNodeEnumerateCompletion (0x30d)
    
  3. PDO 上で !devobj コマンドを使って、PDO の参照カウント (RefCount) に関する情報を表示します。

    0: kd> !devobj 0x849e9648
    Device object (849e9648) is for:
     0000004e \Driver\usbccgp DriverObject 8727e120
    Current Irp 00000000 RefCount 0 Type 00000022 Flags 00003040
    Dacl 82910320 DevExt 849e9700 DevObjExt 849e99e0 DevNode 849e9448 
    ExtensionFlags (0x00000800)  DOE_DEFAULT_SD_PRESENT
    Characteristics (0x00000180)  FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN
    AttachedDevice (Upper) 88310588 \Driver\usbvideo
    Device queue is not busy
    
  4. dt (Display Type) カーネル デバッガー コマンドを使って、PDO デバイス オブジェクトを調べます。 ReferenceCount は、デバイス オブジェクトに関連付けられているデバイスに対して開いているハンドルの数を示します。

    0: kd> dt nt!_DEVICE_OBJECT 849e9648  
    …
       +0x002 Size             : 0x398
       +0x004 ReferenceCount   : 0n0
       +0x008 DriverObject     : 0x8727e120 _DRIVER_OBJECT
    ..
    …
    
  5. テストを開始する前に、参照カウントがゼロより大きい場合は、次の操作を行います。

    • PDO が作成される場所にブレークポイントを設定します。
    • PDO が作成されたら、アクセス時中断 (ba) ブレークポイントの PDO の参照カウントが保存される場所にブレークを設定します。

    たとえば、次のコマンドでは、ba (Break on Access) ブレークポイントをデバイス オブジェクト (0x849e9648) に設定します。ブレークポイントは、サイズが 4 バイト (ReferenceCount のサイズ) の ReferenceCount (+4 オフセット) への書き込みアクセスに設定されます。

    0: kd> ba w 4 849e9648+4 
    
    • テストの開始前に PDO の参照カウントが 0 である場合、テストを実行すると、デバイスの突然の削除が実行されるときに、PDO の参照カウントがゼロより大きくなる可能性があります。通常、これは、ハンドルのリークが発生していることを示します。コマンド プロンプト ウィンドウまたは Visual Studio からデバイスの突然の削除 PNP テストを実行し、失敗を再現して、問題のトラブルシューティングに必要な情報を収集します。Visual Studio からデバイスの突然の削除 PNP テストを実行する方法については、「PnP テスト (Device Fundamental)」と「Device Fundamental テストを選んで構成する方法」をご覧ください。

      DoConcurrentIO パラメーターを "TRUE" に設定すると、テストでは、PDO に対するファイル ハンドルが多数開かれます。このテストの失敗をデバッグするために、このパラメーターを "False" に設定した状態で失敗を再現することをお勧めします。

     

  6. アクセス時中断 (ba) ブレークポイントに到達したら、!thread カーネル デバッガー コマンドと k (Display Stack Backtrace) カーネル デバッガー コマンドを使って失敗をデバッグできます。テストの実行中に参照カウントが何度も変更される可能性があるため、オプションとして、ba (Break on Access) デバッガー コマンドの commandString パラメーターを使って、参照カウントが変更されるたびに必要な情報を取得し、テストを続けることができます。

    たとえば、次のアクセス時中断コマンドでは、commandString は、参照カウント変更の原因となるプロセスを識別する !thread コマンド、コール スタックを識別する .reload ; k 100 コマンド、変更のたびに参照カウントを出力するための !devobj コマンド、ブレークポイントの後も続けるための g コマンドで構成されています。

    0: kd> ba w 4 849e9648+4 "!thread; .thread /p /r; .reload; k 100; !devobj 849e9648; g" 
    

次の例では、cscript.exe で実行されているスレッドからの CreateFile function の呼び出しによって、参照カウントが増加しています。コール スタック全体を表示することもできます。テストの実行中に参照カウントが変更されるインスタンスをすべてキャプチャし、それらのコール スタックを分析することで、ハンドルのリークを特定しやすくなります。

THREAD 87eb3d40  Cid 1094.1490  Teb: 7f5a8000 Win32Thread: 82da2210 RUNNING on processor 3
Not impersonating
DeviceMap                 a71b3228
Owning Process            88199cc0       Image:         cscript.exe
Attached Process          N/A            Image:         N/A
Wait Start TickCount      1232688        Ticks: 0
Context Switch Count      18             IdealProcessor: 2             
UserTime                  00:00:00.000
KernelTime                00:00:00.000
Win32 Start Address ntdll!TppWorkerThread (0x7710704d)
Stack Init a6ebfde0 Current a6ebfa6c Base a6ec0000 Limit a6ebd000 Call 0
Priority 9 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
ChildEBP RetAddr  Args to Child              
a6ebfa50 814a73fe f81771f8 814a72e5 8281000e nt!IopCheckDeviceAndDriver+0x61 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\w8rtm\minkernel\ntos\io\iomgr\parse.c @ 182]
a6ebfb70 8149fb76 849e9648 848f9200 87164008 nt!IopParseDevice+0x11d (FPO: [Non-Fpo]) (CONV: stdcall) [d:\w8rtm\minkernel\ntos\io\iomgr\parse.c @ 1634]
…
…
0236f874 7710689d ffffffff 77195ae2 00000000 ntdll!__RtlUserThreadStart+0x4a (FPO: [SEH]) (CONV: stdcall) [d:\w8rtm\minkernel\ntdll\rtlstrt.c @ 1021]
0236f884 00000000 7710704d 0031c540 00000000 ntdll!_RtlUserThreadStart+0x1c (FPO: [Non-Fpo]) (CONV: stdcall) [d:\w8rtm\minkernel\ntdll\rtlstrt.c @ 939]

Implicit thread is now 87eb3d40
Connected to Windows 8 9200 x86 compatible target at (Wed Sep 19 21:04:27.601 2012 (UTC - 7:00)), ptr64 FALSE
Loading Kernel Symbols
...............................................................
................................................................
...............
Loading User Symbols
................................................................
...........................
Loading unloaded module list
.....................
ChildEBP RetAddr  
a6ebfa50 814a73fe nt!IopCheckDeviceAndDriver+0x61 [d:\w8rtm\minkernel\ntos\io\iomgr\parse.c @ 182]
a6ebfb70 8149fb76 nt!IopParseDevice+0x11d [d:\w8rtm\minkernel\ntos\io\iomgr\parse.c @ 1634]
…
…
0236f2d4 6970274e KERNELBASE!CreateFileW+0x61 [d:\w8rtm\minkernel\kernelbase\fileopcr.c @ 1194]
0236f31c 6b6ce0e1 deviceaccess!CDeviceBroker::OpenDeviceFromInterfacePath+0x178 [d:\w8rtm\base\devices\broker\dll\broker.cpp @ 177]
0236f34c 6b6cc5c0 MFCORE!CDevProxy::CreateKsFilter+0x46 [d:\w8rtm\avcore\mf\core\transforms\devproxy\devproxy.cpp @ 2263]
…
…
0236f874 7710689d ntdll!__RtlUserThreadStart+0x4a [d:\w8rtm\minkernel\ntdll\rtlstrt.c @ 1021]
0236f884 00000000 ntdll!_RtlUserThreadStart+0x1c [d:\w8rtm\minkernel\ntdll\rtlstrt.c @ 939]

Device object (849e9648) is for:
 0000004e \Driver\usbccgp DriverObject 8727e120
Current Irp 00000000 RefCount 1 Type 00000022 Flags 00003040
Dacl 82910320 DevExt 849e9700 DevObjExt 849e99e0 DevNode 849e9448 
ExtensionFlags (0x00000800)  DOE_DEFAULT_SD_PRESENT
Characteristics (0x00000180)  FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN
AttachedDevice (Upper) 88310588 \Driver\usbvideo
Device queue is not busy.

関連トピック

Device Fundamental のテスト

Visual Studio を使って実行時にドライバーをテストする方法

コマンド プロンプトから実行時にドライバーをテストする方法

Device Fundamental テストを選んで構成する方法

提供されている WDTF シンプル I/O プラグイン

Windows HCK を使った Device Fundamental の信頼性テストのトラブルシューティング