Debugging Kebocoran Referensi Daya di WDF

Ketika driver Windows Driver Frameworks (WDF) memanggil WdfDeviceStopIdle, kerangka kerja akan menaikkan jumlah referensi daya perangkat. Setiap panggilan yang berhasil ke WdfDeviceStopIdle harus dicocokkan dengan panggilan ke WdfDeviceResumeIdle untuk mengurangi jumlah referensi daya.

Mulai dari Kernel-Mode Driver Framework (KMDF) 1.15 dan User-Mode Driver Framework (UMDF) 2.15, Anda dapat memantau penggunaan referensi daya dengan menggunakan ekstensi debugger !wdfkd.wdfdevice dan !wdfkd.wdftagtracker . Fungsionalitas ini dinonaktifkan secara default karena alasan performa, jadi Anda perlu mengaktifkannya dengan aplikasi WdfVerifier atau dengan mengedit kunci layanan driver secara manual.

WdfVerifier

Buka daftar pengaturan untuk driver Anda dan klik kanan pengaturan TrackPower . Pilih opsi yang sesuai untuk skenario Anda.

Tips Hindari menangkap jejak tumpukan di jalur kode kritis performa.

Cuplikan layar pengaturan melacak referensi daya di WdfVerifier.

Mengedit Registri

Anda juga dapat mengaktifkan dukungan Pemverifikasi dan pelacakan referensi daya dengan mengedit kunci layanan driver Anda.

Untuk driver KMDF:

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

Untuk driver 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)

Kode Driver

Driver memanggil WdfDeviceStopIdle dan WdfDeviceResumeIdle untuk mengelola status daya kerja perangkat sebagai berikut:

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

Penelusuran kesalahan dengan WdfKd

Untuk menampilkan referensi daya yang diambil pada perangkat, serta pelacak tag yang menunjukkan riwayat referensi, gunakan !wdfkd.wdfdevice dengan bendera verbose:

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

Memanggil !wdfkd.wdftagtracker menunjukkan riwayat referensi daya perangkat:

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

Menentukan Tag

Secara opsional, tentukan nama tag untuk memfasilitasi identifikasi referensi daya tertentu. Untuk melakukannya, gunakan WdfDeviceStopIdleWithTag dan WdfDeviceResumeIdleWithTag:

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

Output sampel !wdftagtracker yang sesuai:

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