Поделиться через


Отладка утечки power Reference в WDF

Когда драйвер Windows Driver Frameworks (WDF) вызывает WdfDeviceStopIdle, фреймворк увеличивает счётчик ссылок питания устройства. Каждый успешный вызов WdfDeviceStopIdle должен соответствовать вызову WdfDeviceResumeIdle для уменьшения количества ссылок на питание.

Начиная с версии 1.15 Kernel-Mode Driver Framework (KMDF) и версии 2.15 User-Mode Driver Framework (UMDF), вы можете отслеживать использование ссылок на питание с помощью расширений отладчика !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)

Код драйвера

Драйверы вызывают WdfDeviceStopIdle и WdfDeviceResumeIdle для управления состоянием работы устройства следующим образом:

//
// 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

Указание тега

При необходимости укажите имя тега для упрощения идентификации конкретных ссылок на источник питания. Для этого используйте WdfDeviceStopIdleWithTag и WdfDeviceResumeIdleWithTag:

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