Udostępnij przez


Debugowanie przecieków odniesienia zasilania w WDF

Gdy sterownik Windows Driver Frameworks (WDF) wywołuje WdfDeviceStopIdle, framework zwiększa liczbę odwołań do zasilania urządzenia. Każde pomyślne wywołanie WdfDeviceStopIdle musi być sparowane z wywołaniem metody WdfDeviceResumeIdle w celu zmniejszenia liczby odwołań do zasilania.

Począwszy od Kernel-Mode Driver Framework (KMDF) 1.15 i User-Mode Driver Framework (UMDF) 2.15, można monitorować użycie odwołań do zasilania przy użyciu !wdfkd.wdfdevice i !wdfkd.wdftagtracker rozszerzenia debugera. Ta funkcja jest domyślnie wyłączona ze względu na wydajność, dlatego należy ją włączyć za pomocą aplikacji WdfVerifier lub ręcznie edytując klucz usługi sterownika.

WdfVerifier

Otwórz listę ustawień sterownika i kliknij prawym przyciskiem myszy ustawienie TrackPower. Wybierz opcję odpowiednią dla danego scenariusza.

Porada Unikaj przechwytywania śladów stosu w ścieżkach kodu o krytycznym znaczeniu dla wydajności.

Zrzut ekranu przedstawiający ustawianie parametrów zasilania w programie WdfVerifier.

Edytowanie rejestru

Możesz również włączyć obsługę Weryfikatora oraz monitorowanie odniesień do zasilania, edytując klucz serwisowy sterownika.

W przypadku sterownika KMDF:

HKLM\SYSTEM\ControlSet001\Services\<nazwa usługi sterownika>\Parameters\Wdf

W przypadku sterownika UMDF:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WUDF\Services\<Nazwa usługi sterownika>\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)

Kod sterownika

Sterowniki wywołają WdfDeviceStopIdle i WdfDeviceResumeIdle w celu zarządzania stanem zasilania urządzenia w następujący sposób:

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

Debugowanie za pomocą usługi WdfKd

Aby wyświetlić pobór mocy urządzenia oraz śledzik tagów, który pokazuje historię odniesień, użyj !wdfkd.wdfdevice z rozbudowanymi flagami:

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

Wywołanie !wdfkd.wdftagtracker pokazuje historię odwołania do zasilania urządzenia:

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

Określanie tagu

Opcjonalnie podaj nazwę tagu, aby ułatwić identyfikację konkretnych odniesień energetycznych. W tym celu użyj WdfDeviceStopIdleWithTag i WdfDeviceResumeIdleWithTag:

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

Odpowiadające !wdftagtracker przykładowe dane wyjściowe:

(--) 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