WDK를 사용하여 장치 기본 테스트 문제 해결

이 항목에서는 WDK를 사용하여 장치 기본 테스트를 실행할 때 발생할 수 있는 문제 해결을 위한 제안 사항을 소개합니다. 테스트 및 테스트 방법에 대한 자세한 내용은 장치 기본 테스트를 선택하고 구성하는 방법, Visual Studio를 사용하여 런타임에 드라이버를 테스트하는 방법명령 프롬프트에서 런타임에 드라이버를 테스트하는 방법을 참조하세요.

참고  HCK를 사용하여 Device.Fundamentals 테스트 문제를 해결하는 방법에 대한 자세한 내용은 Windows HCK를 사용하여 장치 기본 안정성 테스트 문제 해결을 참조하세요.

 

  • 장치 기본 테스트 실패(일반)
  • 드라이버 검증 도구가 사용하도록 설정되지 않음
  • 테스트가 응답하지 않거나 실행되지 않음
  • 예기치 않은 장치 제거 PNP 테스트
문제: 장치 기본 테스트 실패(일반)

 

오류 조건:

테스트가 실패하거나 실행되지 않습니다. 일부 장치 유형의 경우 장치 기본 테스트 실행에 대한 특정 요구 사항이 있습니다. Windows HCK(하드웨어 인증 키트)를 사용할 경우 이러한 동일한 요구 사항을 따라야 합니다.

다음 장치 기본 테스트를 실행하기 전에 테스트 컴퓨터에서 특정 장치 유형에 대해 설명된 요구 사항에 따라 장치를 구성해야 합니다.

  • PCI Root Port 예기치 않은 장치 제거(PCI 장치 전용)
  • 장치 경로 시험기 테스트(인증)
  • 절전 모드 전후 I/O 테스트 및 PNP(사용 안 함 및 사용) 테스트(인증)
  • 플러그 앤 플레이 드라이버 테스트(인증)
  • CHAOS(Concurrent Hardware And Operating System) 테스트(인증)
  • 다시 설치 전후 I/O 테스트(인증)
  • 파일 시스템 일관성에 대한 장치 설치 확인(인증)
  • 기타 장치 안정성에 대한 장치 설치 확인(인증)

해결 방법:

테스트에 대한 특정 장치 요구 사항 정보는 제공된 WDTF 단순 I/O 플러그 인에 설명되어 있습니다. 장치 기본 테스트에서는 제공된 WDTF 단순 I/O 플러그 인을 사용하여 테스트 효과를 향상시키기 위해 장치별 I/O 작업을 수행합니다. 플러그 인이 수행하는 I/O 유형에 대한 설명과 특수 장치 요구 사항이 있는지 확인하려면 다음 링크를 사용하세요. 테스트 실패를 디버그하고 심사하는 데 도움이 되기 위해 수행할 수 있는 특정 심사 단계가 있는 경우 장치 유형에 대해 해당 단계가 표시됩니다.

문제: 드라이버 검증 도구가 사용하도록 설정되지 않음

 

오류 메시지:

"테스트 시 장치의 모든 드라이버(모든 상위 및 하위 필터 드라이버 포함)에 대한 최소한의 표준 설정으로 장치 검증 도구를 사용할 수 없습니다. 최소한의 표준 설정으로 드라이버 검증 도구를 사용하도록 설정하고 테스트를 다시 실행합니다."

해결 방법:

실행 중인 장치 기본 테스트에서 드라이버 검증 도구가 테스트 중인 장치와 연결된 드라이버를 모니터링하도록 요구합니다. 다음 두 가지 옵션이 있습니다.

  • 드라이버 검증 도구 사용 테스트를 테스트 그룹에 추가하고 실행 중인 장치 기본 테스트에 지정한 것과 동일한 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 및 전원 관리 테스트를 디버그하는 경우 다음 커널 디버거 명령 2개를 사용하면 테스트 진행을 방해하는 활성 PnP 및 전원 스레드를 식별할 수 있습니다.

!pnptriage

!poaction
문제: 예기치 않은 장치 제거 PNP 테스트

 

오류 메시지: "IRP_MN_SURPRISE_REMOVAL을 수신한 후 IRP_MN_REMOVE_DEVICE를 수신하지 못함"

해결 방법:

PnP 관리자가 예기치 않은 제거 IRP를 보낸 후 제거 IRP를 테스트 장치 스택으로 보내지 않는 경우 예기치 않은 장치 제거 PnP 테스트(PnP 테스트(장치 기본) 참조)가 실패하고 다음 오류 메시지가 표시될 수 있습니다.

"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의 참조 수가 0에 도달할 때까지 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. 테스트를 시작하기 전에 참조 수가 0보다 큰 경우:

    • PDO가 생성되는 중단점을 설정합니다.
    • PDO가 생성된 후 PDO의 참조 수가 저장된 위치에 있는 액세스(ba) 중단점에서 중단을 설정합니다.

    예를 들어 다음 명령은 장치 개체에서 ba (Break on Access) 중단점을 설정합니다(0x849e9648). 쓰기 액세스에 대한 중단점이 ReferenceCount(+4 오프셋)로 설정되고 크기는 4바이트(ReferenceCount입니다.

    0: kd> ba w 4 849e9648+4 
    
    • 테스트를 시작하기 전에 PDO의 참조 수가 0과 같을 경우 테스트를 실행하면 테스트에서 예기치 않은 장치 제거를 수행할 때 PDO의 참조 수가 0보다 커질 수 있습니다. 일반적으로 이 상태는 핸들 누수가 있음을 나타냅니다. 명령 프롬프트 창 또는 Visual Studio에서 예기치 않은 장치 제거 PNP 테스트를 실행하여 문제를 해결하는 데 필요한 정보를 캡처하기 위해 실패를 재현합니다. Visual Studio에서 예기치 않은 장치 제거 PNP 테스트를 실행하는 방법은 PnP 테스트(장치 기본)장치 기본 테스트를 선택하고 구성하는 방법을 참조하세요.

    참고  DoConcurrentIO 매개 변수를 "TRUE"로 설정하면 테스트에서 PDO에 대한 수백 개의 파일 핸들을 엽니다. 이 테스트 실패를 디버그하기 위해 이 매개 변수를 "False"로 설정하여 이 실패를 재현하는 것이 좋습니다.

     

  6. 액세스(ba) 중단점에서 중단이 발생하면 !threadk (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.

관련 항목

장치 기본 테스트

Visual Studio를 사용하여 런타임에 드라이버를 테스트하는 방법

명령 프롬프트를 사용하여 런타임에 드라이버를 테스트하는 방법

장치 기본 테스트를 선택하고 구성하는 방법

제공된 WDTF 단순 I/O 플러그 인

Windows HCK를 사용하여 장치 기본 안정성 테스트 문제 해결