KMDF 및 UMDF 2 드라이버에서 IFR(Inflight Trace Recorder) 사용

Windows 10부터 KMDF 또는 UMDF 드라이버를 빌드하여 Windows 소프트웨어 추적 전처리를 통해 추가 드라이버 디버깅 정보를 얻을 수 있습니다. IFR(Inflight Trace Recorder)이라고 하는 이 기능은 KMDF 버전 1.15 및 UMDF 버전 2.15부터 사용할 수 있습니다.

Inflight Trace Recorder는 WPP 소프트웨어 추적확장입니다. WPP 추적과 달리 Inflight 추적 레코더는 연결된 추적 소비자 없이 계속 작동합니다. 프레임워크는 메시지를 순환 버퍼에 쓰고 드라이버는 자체 메시지를 추가할 수도 있습니다. 각 드라이버에는 자체 로그가 있으므로 드라이버와 연결된 여러 디바이스가 단일 로그를 공유합니다.

드라이버 이진 파일에서 IFR을 켜면 IFR이 존재하고 드라이버의 수명 동안 실행됩니다. 명시적 추적 컬렉션 세션을 시작할 필요가 없습니다.

로그는 페이징할 수 없는 메모리에 저장되므로 시스템 충돌 후 복구할 수 있습니다. 또한 Inflight 추적 레코더 로그는 책임 있는 드라이버가 결정되지 않은 경우 또는 충돌이 호스트 시간 제한인 경우를 제외하고 미니덤프 파일에 포함됩니다.

Inflight 추적 레코더를 사용하도록 설정하고 드라이버에서 메시지를 보내는 방법

  1. Microsoft Visual Studio에서 다음 단계를 수행합니다.

    • 드라이버 프로젝트의 속성 페이지를 엽니다. 솔루션 탐색기 드라이버 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다. 드라이버의 속성 페이지에서 구성 속성을 선택한 다음 Wpp 추적을 선택합니다. 일반 메뉴에서 WPP 추적 실행을 예설정합니다.

    • Properties-Wpp> 추적 함수> 및 매크로 옵션으로 이동하고 WPP 레코더 사용을 선택합니다.

    • 동일한 메뉴에서 추적 정보를 포함하는 파일(예: Trace.h)으로 검색 구성 데이터를 설정합니다.

  2. WPP 매크로를 호출하는 각 소스 파일에서 TMH(추적 메시지 헤더) 파일을 식별하는 #include 지시문을 추가합니다. 파일 이름은 driver-source-file-name.tmh> 형식<이어야 합니다.

    예를 들어 드라이버가 MyDriver1.c와 MyDriver2.c라는 두 소스 파일로 구성된 경우 MyDriver1.c에는 다음이 포함되어야 합니다.

    #include "MyDriver1.tmh"

    MyDriver2.c 에는 다음이 포함되어야 합니다.

    #include "MyDriver2.tmh"

    Visual Studio에서 드라이버를 빌드하면 WPP 전처리기에서 해당 드라이버를 생성합니다.tmh 파일.

  3. 헤더 파일에서 WPP_CONTROL_GUIDS 매크로를 정의합니다. 이 매크로는 드라이버 추적 메시지에 대한 GUID 및 추적 플래그 를 정의합니다.

    Osrusbfx2 드라이버 샘플은 다음 예제와 같이 Trace.h 헤더 파일에서 단일 컨트롤 GUID 및 7개의 추적 플래그를 정의합니다.

    #define WPP_CONTROL_GUIDS \
    WPP_DEFINE_CONTROL_GUID(OsrUsbFxTraceGuid, \
      (d23a0c5a,d307,4f0e,ae8e,E2A355AD5DAB), \
      WPP_DEFINE_BIT(DBG_INIT)          /* bit  0 = 0x00000001 */ \
      WPP_DEFINE_BIT(DBG_PNP)           /* bit  1 = 0x00000002 */ \
      WPP_DEFINE_BIT(DBG_POWER)         /* bit  2 = 0x00000004 */ \
      WPP_DEFINE_BIT(DBG_WMI)           /* bit  3 = 0x00000008 */ \
      WPP_DEFINE_BIT(DBG_CREATE_CLOSE)  /* bit  4 = 0x00000010 */ \
      WPP_DEFINE_BIT(DBG_IOCTL)         /* bit  5 = 0x00000020 */ \
      WPP_DEFINE_BIT(DBG_WRITE)         /* bit  6 = 0x00000040 */ \
      WPP_DEFINE_BIT(DBG_READ)          /* bit  7 = 0x00000080 */ \
    )
    

    이 예에서는 다음이 적용됩니다.

    • OsrUsbFxTraceGuid 는 {d23a0c5a-d307-4f0e-ae8e-E2A355AD5DAB} GUID의 이름입니다.
    • 추적 플래그는 드라이버가 다양한 유형의 I/O 요청을 처리할 때 생성되는 추적 메시지를 구분하는 데 사용됩니다.
  4. 드라이버(KMDF 및 UMDF 2 모두)는 드라이버 개체 및 레지스트리 경로(일반적으로 DriverEntry에서)를 사용하여 커널 모드 드라이버대한 WPP_INIT_TRACING 호출해야 합니다.

    WPP_INIT_TRACING( DriverObject, RegistryPath );
    

    추적을 비활성화하기 위해 KMDF 및 UMDF 2 드라이버는 모두 EvtCleanupCallback 또는 EvtDriverUnload 커널 모드 드라이버에 대한 WPP_CLEANUP 호출합니다.

    WPP_CLEANUP( WdfDriverWdmGetDriverObject( Driver ));
    

    WPP_CLEANUP 매크로는 PDRIVER_OBJECT 형식의 매개 변수를 사용합니다. 따라서 드라이버의 DriverEntry가 실패하는 경우 WdfDriverWdmGetDriverObject 호출을 건너뛰고 대신 WDM 드라이버 개체에 대한 포인터를 사용하여 WPP_CLEANUP 호출할 수 있습니다.

    UMDF 드라이버는 추적을 초기화하고 정리하기 위해 이러한 매크로의 커널 모드 서명을 사용하므로 KMDF 및 UMDF에 대해 호출이 동일하게 표시됩니다.

  5. 드라이버에서 DoTraceMessage 매크로 또는 사용자 지정된 버전의 매크로를 사용하여 추적 메시지를 만듭니다.

    다음 예제에서는 Osrusbfx2 드라이버가 읽기 요청을 처리하는 데 전념하는 코드의 일부에서 TraceEvents 함수를 사용하는 방법을 보여 줍니다.

    if (Length > TEST_BOARD_TRANSFER_BUFFER_SIZE) {
        TraceEvents(TRACE_LEVEL_ERROR,
                    DBG_READ,
                    "Transfer exceeds %d\n",
                    TEST_BOARD_TRANSFER_BUFFER_SIZE);
    
        status = STATUS_INVALID_PARAMETER;
    }
    

    추적 컨트롤러에서 TRACE_LEVEL_ERROR 수준 및 DBG_READ 추적 플래그를 사용하도록 설정하면 TraceEvents 대한 호출이 추적 메시지를 생성합니다. 메시지에는 드라이버 정의 상수 TEST_BOARD_TRANSFER_BUFFER_SIZE 값이 포함됩니다.

  6. 드라이버 로그에서 사용하는 순환 버퍼의 크기를 변경하려면 다음 레지스트리 위치에서 LogPages 레지스트리 값을 수정합니다.

    UMDF의 경우:

    SOFTWARE\Microsoft\Windows NT\CurrentVersion\WUDF\Services\<YourDriver>\Parameters\Wdf

    KMDF의 경우:

    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\<YourDriver>\Parameters\Wdf

    이는 할당된 로그 버퍼의 크기(페이지)를 포함하는 REG_DWORD 형식의 값입니다. 유효한 값은 0x1 0x10 사이에 있습니다.

KMDF 드라이버의 경우

  1. 디버거에 .load rcdrkd.dll 입력하여 RCDRKD 명령을 로드합니다.
  2. !wdfkd.wdfldr 확장을 사용하여 현재 WDF(Windows 드라이버 프레임워크)에 동적으로 바인딩된 드라이버에 대한 정보를 표시합니다.
  3. !rcdrkd.rcdrlogdump!rcdrkd.rcdrcrashdump를 사용하여 드라이버가 제공하는 메시지를 봅니다.
  4. !wdfkd.wdflogdump 또는 !wdfkd.wdfcrashdump를 사용하여 프레임워크에서 제공하는 메시지를 확인합니다.

UMDF 드라이버의 라이브 디버깅

  1. !wdfkd.wdfldr 확장을 사용하여 현재 WDF에 동적으로 바인딩된 드라이버에 대한 정보를 표시합니다. 사용자 모드 드라이버를 찾습니다. 연결된 호스트 프로세스를 입력합니다.

  2. 플래그가 있는<> !wdfkd.wdflogdump< YourDriverName.dll><플래그>를 입력합니다.

    • 0x1 – 병합된 프레임워크 및 드라이버 로그
    • 0x2 – 드라이버 로그
    • 0x3 – 프레임워크 로그

    지정된 드라이버에 대한 드라이버 로그가 없는 경우 확장은 프레임워크 로그만 표시합니다.

UMDF 드라이버 충돌 후 기내 추적 레코더 로그 보기

  1. WinDbg에서 파일> 열기 크래시 덤프를 선택하고 디버그할 미니덤프 파일을 지정합니다.

  2. 드라이버 호스트<>옵션>의 프로세스 ID를 YourDriverName.dll><!wdfkd.wdfcrashdump<를 입력합니다. 여기서 <Option>은 다음과 같습니다.

    • 0x1 – 병합된 프레임워크 및 드라이버 로그
    • 0x2 – 드라이버 로그
    • 0x3 – 프레임워크 로그

    드라이버를 지정하지 않으면 !wdfcrashdump 는 모든 드라이버에 대한 정보를 표시합니다. 호스트 프로세스를 지정하지 않고 하나만 있는 경우 확장은 단일 호스트 프로세스를 사용합니다. 호스트 프로세스를 지정하지 않고 둘 이상이 있는 경우 확장은 활성 호스트 프로세스를 나열합니다.

    미니덤프에 저장된 로그 정보가 입력한 이름과 일치하지 않으면 미니덤프에 드라이버의 로그가 포함되지 않습니다.

디버거가 연결되어 있지 않은 경우에도 드라이버 및 프레임워크 로그에 액세스할 수 있습니다. 방법을 알아보려면 비디오: 디버거 없이 드라이버 IFR 로그에 액세스하는 방법을 참조하세요.

드라이버에 추적 메시지를 추가하는 방법에 대한 자세한 내용은 드라이버에 WPP 매크로 추가를 참조하세요.

UMDF 드라이버의 디버깅을 사용하도록 설정하는 방법

RCDRKD 확장

프레임워크의 이벤트 로거 사용

UMDF 드라이버에서 WPP 소프트웨어 추적 사용