다음을 통해 공유


WDF에서 전원 참조 누수 디버깅

WDF(Windows 드라이버 프레임워크) 드라이버가 WdfDeviceStopIdle을 호출하면 프레임워크는 디바이스의 전원 참조 수를 증가합니다. WdfDeviceStopIdle에 대한 모든 성공적인 호출은 WdfDeviceResumeIdle 호출과 일치하여 전원 참조 수를 감소시켜야 합니다.

KMDF(Kernel-Mode Driver Framework) 1.15 및 UMDF(User-Mode Driver Framework) 2.15부터 !wdfkd.wdfdevice!wdfkd.wdftagtracker 디버거 확장을 사용하여 전원 참조 사용량을 모니터링할 수 있습니다. 이 기능은 성능상의 이유로 기본적으로 사용하지 않도록 설정되므로 WdfVerifier 애플리케이션을 사용하거나 드라이버의 서비스 키를 수동으로 편집하여 켜야 합니다.

WdfVerifier

드라이버의 설정 목록을 열고 TrackPower 설정을 마우스 오른쪽 단추로 클릭합니다. 시나리오에 적합한 옵션을 선택합니다.

성능에 중요한 코드 경로에서 스택 추적을 캡처하지 마세요.

WdfVerifier에서 전원 참조 추적을 설정하는 스크린샷

레지스트리 편집

드라이버의 서비스 키를 편집하여 검증 도구 지원 및 전원 참조 추적을 켤 수도 있습니다.

KMDF 드라이버의 경우:

HKLM\SYSTEM\ControlSet001\Services\<Driver Service Name>\Parameters\Wdf

UMDF 드라이버의 경우:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WUDF\Services\<Driver Service Name>\Parameters\Wdf

(REG_DWORD) VerifierOn = 0x1
(REG_DWORD) TrackPower = 0x0 (disabled)
                       = 0x1 (capture tick count, file name, line number)
                       = 0x2 (capture tick count, file name, line number, and stack traces)

드라이버 코드

드라이버는 다음과 같이 WdfDeviceStopIdleWdfDeviceResumeIdle 을 호출하여 디바이스의 작동 전원 상태를 관리합니다.

//
// Take power reference
//
status = WdfDeviceStopIdle(device, FALSE);
if (NT_SUCCESS(status)) {
    //
    // Release power reference
    //
    WdfDeviceResumeIdle(device);
}

WdfKd를 사용하여 디버깅

디바이스에서 가져온 전원 참조와 참조 기록을 표시하는 태그 추적기를 표시하려면 자세한 플래그와 함께 !wdfkd.wdfdevice 를 사용합니다.

kd> !wdfkd.wdfdevice 0x6d939790 ff
Power references: 0 !wdftagtracker 0x9ea030a8

!wdfkd.wdftagtracker를 호출하면 디바이스의 전원 참조 기록이 표시됩니다.

kd> !wdftagtracker 0x9ea030a8
Reference and Release History:
# (showing most recent first; refcount is approximate in multi-threaded scenarios)

## 3 entries, history depth is 25

(--) 0 ref: Tag '....' at Time 0x1331e ticks
##      path\to\your\driver\code.c @ 374

(++) 1 refs: Tag '....' at Time 0x1331e ticks
##      path\to\your\driver\code.c @ 372

(++) Initial Tag '....' at Time 0x12c9a ticks

태그 지정

필요에 따라 특정 전원 참조를 쉽게 식별할 수 있도록 태그 이름을 지정합니다. 이렇게 하려면 WdfDeviceStopIdleWithTagWdfDeviceResumeIdleWithTag를 사용합니다.

status = WdfDeviceStopIdleWithTag(device, FALSE, (PVOID)'oyeH');
if (NT_SUCCESS(status)) {
    WdfDeviceResumeIdleWithTag(device, (PVOID)'oyeH');
}

해당 !wdftagtracker 샘플 출력:

(--) 0 ref: Tag 'Heyo' at Time 0x24e40 ticks
##      path\to\your\driver\code.c @ 374

(++) 1 refs: Tag 'Heyo' at Time 0x24e40 ticks
##      path\to\your\driver\code.c @ 372

(++) Initial Tag '....' at Time 0x12c9a ticks