Драйверы отладки — пошаговые лаборатории (режим ядра Sysvad)

Эта лаборатория предоставляет практические упражнения, демонстрирующие отладку драйвера устройства в режиме ядра Sysvad.

Отладчик Microsoft Windows (WinDbg) — это мощное средство отладки на основе Windows, которое можно использовать для выполнения отладки в пользовательском режиме и режиме ядра. WinDbg предоставляет отладку на уровне источника для ядра Windows, драйверов в режиме ядра и системных служб, а также приложений и драйверов в пользовательском режиме.

WinDbg может выполнять шаги по исходному коду, задавать точки останова, просматривать переменные (включая объекты C++), трассировки стека и память. Его командное окно отладчика позволяет пользователю выполнять различные команды.

Настройка лаборатории

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

  • Ноутбук или настольный компьютер под управлением Windows 10
  • Ноутбук или настольный компьютер под управлением Windows 10
  • Сетевой концентратор или маршрутизатор и сетевые кабели для подключения двух компьютеров
  • Доступ к Интернету для скачивания файлов символов

Для выполнения лаборатории вам потребуется следующее программное обеспечение.

  • Microsoft Visual Studio 2017
  • Пакет средств разработки программного обеспечения Windows (SDK) для Windows 10
  • Комплект драйверов Windows (WDK) для Windows 10
  • Пример звукового драйвера Sysvad для Windows 10

Сведения о скачивании и установке WDK см. в разделе "Скачать комплект драйверов Windows (WDK)".

Пошаговое руководство по отладке sysvad

В этой лаборатории описан процесс отладки драйвера в режиме ядра. В упражнениях используется пример виртуального звукового драйвера Syvad. Так как звуковой драйвер Syvad не взаимодействует с фактическим звуковым оборудованием, его можно использовать на большинстве устройств. Лаборатория охватывает следующие задачи:

Лаборатория эхо-драйвера

Драйвер Echo — это более простой драйвер, чем звуковой драйвер Sysvad. Если вы не знакомы с WinDbg, вам может потребоваться сначала завершить отладку универсальных драйверов — пошаговые лаборатории (режим ядра Echo). Эта лаборатория повторно использует инструкции по настройке из этой лаборатории, поэтому если вы завершили эту лабораторию, вы можете пропустить разделы 1 и 2 здесь.

Раздел 1. Подключение сеанс WinDbg в режиме ядра

В разделе 1 вы настроите отладку сети на узле и целевой системе.

Компьютеры в этой лаборатории должны быть настроены для использования сетевого подключения Ethernet для отладки ядра.

В этой лаборатории используются два компьютера. WinDbg выполняется в системе узла, а драйвер Sysvad выполняется в целевой системе.

Используйте сетевой концентратор или маршрутизатор и сетевые кабели для подключения двух компьютеров.

Схема с двумя компьютерами, подключенными через сетевой концентратор или маршрутизатор.

Чтобы работать с приложениями в режиме ядра и использовать WinDbg, рекомендуется использовать KDNET через транспорт Ethernet. Сведения об использовании транспортного протокола Ethernet см. в статье "Начало работы с WinDbg" (режим ядра). Дополнительные сведения о настройке целевого компьютера см. в статье "Подготовка компьютера для автоматического развертывания драйвера вручную" и настройка отладки сетевого ядра KDNET.

Настройка отладки в режиме ядра с помощью Ethernet

Чтобы включить отладку в режиме ядра в целевой системе, выполните следующие действия.

<— в хост-системе

  1. Откройте командную строку в системе узла и введите ipconfig /all , чтобы определить его IP-адрес.
C:\>ipconfig /all
Windows IP Configuration

 Host Name . . . . . . . . . . . . : TARGETPC
...

Ethernet adapter Ethernet:
   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::c8b6:db13:d1e8:b13b3
   Autoconfiguration IPv4 Address. . : 169.182.1.1
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   Default Gateway . . . . . . . . . :
  1. Запишите IP-адрес хост-системы: ______________________________________

  2. Запишите имя узла системы узла: ______________________________________

—> в целевой системе

  1. Откройте командную строку в целевой системе и используйте команду ping для подтверждения сетевого подключения между двумя системами. Используйте фактический IP-адрес хост-системы, записанной вместо 169.182.1.1, показанной в примере выходных данных.
C:\> ping 169.182.1.1

Pinging 169.182.1.1 with 32 bytes of data:
Reply from 169.182.1.1: bytes=32 time=1ms TTL=255
Reply from 169.182.1.1: bytes=32 time<1ms TTL=255
Reply from 169.182.1.1: bytes=32 time<1ms TTL=255
Reply from 169.182.1.1: bytes=32 time<1ms TTL=255

Ping statistics for 169.182.1.1:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 1ms, Average = 0ms

Чтобы использовать служебную программу KDNET для включения отладки в режиме ядра в целевой системе, выполните следующие действия.

  1. На узле найдите каталог KDNET WDK. По умолчанию он расположен здесь.

    C:\Program Files (x86)\Windows Kits\10\Debuggers\x64

В этой лаборатории предполагается, что оба компьютера работают под управлением 64-разрядной версии Windowson как целевого, так и узла. Если это не так, лучший подход заключается в том, чтобы запустить ту же "битность" средств на узле, что и целевой объект. Например, если целевой объект работает под управлением 32-разрядной версии Windows, запустите 32-разрядную версию отладчика на узле. Дополнительные сведения см. в разделе "Выбор 32-разрядных или 64-разрядных средств отладки".

  1. Найдите эти два файла и скопируйте их в сетевую общую папку или диск с большими пальцами, чтобы они были доступны на целевом компьютере.

    kdnet.exe

    VerifiedNICList.xml

  2. На целевом компьютере откройте окно командной строки как Администратор istrator. Введите эту команду, чтобы убедиться, что сетевой адаптер на целевом компьютере выполняется при отправке.

C:\KDNET>kdnet

Network debugging is supported on the following NICs:
busparams=0.25.0, Intel(R) 82579LM Gigabit Network Connection, KDNET is running on this NIC.kdnet.exe
  1. Введите эту команду, чтобы задать IP-адрес хост-системы. Используйте фактический IP-адрес хост-системы, записанной вместо 169.182.1.1, показанной в примере выходных данных. Выберите уникальный адрес порта для каждой пары целевых или узлов, с которыми вы работаете, например 50010.
C:\>kdnet 169.182.1.1 50010

Enabling network debugging on Intel(R) 82577LM Gigabit Network Connection.
Key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p

Внимание

Прежде чем использовать BCDEdit для изменения сведений о загрузке, может потребоваться временно приостановить функции безопасности Windows, такие как BitLocker и безопасная загрузка на тестовом компьютере. Повторно включите эти функции безопасности при завершении тестирования и соответствующим образом управлять тестируемым компьютером при отключении функций безопасности. Безопасная загрузка обычно отключена в UEFI. Чтобы получить доступ к параметру UEFI, воспользуйтесь системой, восстановлением, расширенным запуском. При перезапуске выберите "Устранение неполадок", "Дополнительные параметры" и "Встроенное ПО UEFI". Используйте осторожность, так как неправильно задать параметры UEFI или отключить BitLocker, может сделать систему неработоспособной.

  1. Введите эту команду, чтобы убедиться, что dbgsettings заданы правильно.
C:\> bcdedit /dbgsettings
busparams               0.25.0
key                     2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
debugtype               NET
hostip                  169.182.1.1
port                    50010
dhcp                    Yes
The operation completed successfully.

Скопируйте автоматически созданный уникальный ключ в текстовый файл, чтобы избежать необходимости вводить его на хост-компьютере. Скопируйте текстовый файл с ключом на хост-систему.

Примечаниебрандмауэров и отладчиков

Если появится всплывающее сообщение из брандмауэра, и вы хотите использовать отладчик, проверка все три поля.

Снимок экрана: оповещение Безопасность Windows, указывающее, что брандмауэр Windows блокирует некоторые функции приложения.

<— в хост-системе

  1. На хост-компьютере откройте окно командной строки как Администратор istrator. Перейдите в каталог WinDbg.exe. Мы будем использовать x64version WinDbg.exe из комплекта драйверов Windows (WDK), который был установлен в составе установки пакета Windows.
C:\> Cd C:\Program Files (x86)\Windows Kits\10\Debuggers\x64 
  1. Запустите WinDbg с отладкой удаленного пользователя с помощью следующей команды. Значение ключа и порта соответствует заданному ранее значению BCDEdit в целевом объекте.
C:\> WinDbg –k net:port=50010,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p

->В целевой системе

Перезагрузите целевую систему.

<-В системе узла

В минуту или два выходные данные отладки должны отображаться в хост-системе.

Снимок экрана: отладчик Windows, отображающий выходные данные командного окна из динамического подключения к ядру.

Командное окно отладчика — это основное окно сведений об отладке в WinDbg. Вы можете ввести команды отладчика и просмотреть выходные данные команды в этом окне.

Окно команды отладчика разделено на две области. В нижней части окна введите команды в меньшей области (область входа команд) и просмотрите выходные данные команды в более крупной области в верхней части окна.

В области ввода команд используйте клавиши со стрелками вверх и вниз, чтобы прокрутить журнал команд. Когда появится команда, ее можно изменить или нажать клавишу ВВОД , чтобы выполнить команду.

Раздел 2. Команды и методы отладки в режиме ядра

В разделе 2 вы будете использовать команды отладки для отображения сведений о целевой системе.

<— в хост-системе

Включение языка разметки отладчика (DML) с .prefer_dml

Некоторые команды отладки отображают текст с помощью языка разметки отладчика, который можно быстро собрать дополнительные сведения.

  1. Используйте ctrl+Break (Scroll Lock) в WinDBg, чтобы разбить код, выполняемый в целевой системе. Для реагирования целевой системы может потребоваться немного времени.
  2. Введите следующую команду, чтобы включить DML в окне команды отладчика.
0: kd> .prefer_dml 1
DML versions of commands on by default

Использование HH для получения справки

С помощью команды HH можно получить доступ к справочной команде.

  1. Введите следующую команду, чтобы просмотреть справку по ссылке на команду для .prefer_dml.
    0: kd> .hh .prefer_dml
    

Файл справки отладчика отобразит справку по команде .prefer_dml .

Снимок экрана: приложение справки отладчика, отображающее справку по команде .prefer-dml.

Отображение версии Windows в целевой системе

  1. Отображение подробных сведений о версии целевой системы, введя команду vertarget (Показать целевую версию компьютера) в окне WinDbg.
0: kd> vertarget
Windows 10 Kernel Version 9926 MP (4 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 9926.0.amd64fre.fbl_awesome1501.150119-1648
Machine Name: ""
Kernel base = 0xfffff801`8d283000 PsLoadedModuleList = 0xfffff801`8d58aef0
Debug session time: Fri Feb 20 10:15:17.807 2015 (UTC - 8:00)
System Uptime: 0 days 01:31:58.931

Вывод списка загруженных модулей

  1. Вы можете убедиться, что вы работаете с правильным процессом в режиме ядра, отображая загруженные модули, введя команду lm (список загруженных модулей) в окне WinDbg.
0: Kd> lm
start             end                 module name
fffff801`09200000 fffff801`0925f000   volmgrx    (no symbols)           
fffff801`09261000 fffff801`092de000   mcupdate_GenuineIntel   (no symbols)           
fffff801`092de000 fffff801`092ec000   werkernel   (export symbols)       werkernel.sys
fffff801`092ec000 fffff801`0934d000   CLFS       (export symbols)       CLFS.SYS
fffff801`0934d000 fffff801`0936f000   tm         (export symbols)       tm.sys
fffff801`0936f000 fffff801`09384000   PSHED      (export symbols)       PSHED.dll
fffff801`09384000 fffff801`0938e000   BOOTVID    (export symbols)       BOOTVID.dll
fffff801`0938e000 fffff801`093f7000   spaceport   (no symbols)           
fffff801`09400000 fffff801`094cf000   Wdf01000   (no symbols)           
fffff801`094d9000 fffff801`09561000   CI         (export symbols)       CI.dll
...

Обратите внимание , что выходные данные, которые были опущены, указываются с "... " в этой лаборатории.

Так как у нас еще нет пути к символам и загруженным символам, в отладчике доступна ограниченная информация.

Раздел 3. Скачивание и сборка звукового драйвера Sysvad

В разделе 3 вы скачайте и создадите звуковой драйвер Sysvad.

Как правило, вы будете работать с собственным кодом драйвера при использовании WinDbg. Чтобы ознакомиться с отладкой звуковых драйверов, используется драйвер виртуального звука Sysvad. Этот пример используется для иллюстрации того, как можно выполнить один шаг через собственный код в режиме ядра. Этот метод может быть очень ценным для отладки сложных проблем с кодом в режиме ядра.

Чтобы скачать и создать образец звукового драйвера Sysvad, выполните следующие действия.

  1. Скачайте и извлеките образец звука Sysvad из GitHub

    Вы можете использовать браузер для просмотра примера Sysvad и Readme.md файла:

    https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad

    Снимок экрана: репозиторий GitHub, отображающий общую папку и кнопку

    В этой лаборатории показано, как скачать универсальные примеры драйверов в один ZIP-файл.

    a. Скачайте файл master.zip на локальный жесткий диск.

    https://github.com/Microsoft/Windows-driver-samples/archive/master.zip

    b. Выберите и удерживайте (или щелкните правой кнопкой мыши) Windows-driver-samples-master.zip и выберите команду "Извлечь все". Укажите новую папку или перейдите к существующей папке, в которую будут храниться извлеченные файлы. Например, можно указать C:\WDK_Samples\ в качестве новой папки, в которую извлекаются файлы.

    c. После извлечения файлов перейдите к следующей вложенной папке.

    C:\WDK_Samples\Sysvad

  2. Открытие решения драйвера в Visual Studio

    В Visual Studio выберите "Открыть>проект или решение">и перейдите в папку, содержащую извлеченные файлы (например, C:\WDK_Samples\Sysvad). Дважды щелкните файл решения Syvad .

    В Visual Studio найдите Обозреватель решений. (Если это еще не открыто, выберите Обозреватель решений в меню "Вид".) В Обозреватель решений можно увидеть одно решение с рядом проектов.

    Снимок экрана: Visual Studio с файлом adapter.cpp, загруженным из проекта Sysvad.

  3. Установка конфигурации и платформы примера

    В Обозреватель решений выберите и удерживайте (или щелкните правой кнопкой мыши) решение sysvad (7 из 7 проектов) и выберите Configuration Manager. Убедитесь, что параметры конфигурации и платформы одинаковы для четырех проектов. По умолчанию для конфигурации задано значение Win10 Debug, а платформа имеет значение Win64 для всех проектов. При внесении изменений конфигурации и (или) платформы для одного проекта необходимо внести те же изменения для оставшихся трех проектов.

    Примечание. В этой лаборатории предполагается, что используется 64-разрядная версия Windows. Если вы используете 32-разрядную версию Windows, создайте драйвер для 32-разрядной версии.

  4. Проверка подписи драйвера

    Найдите ПланшетAudioSample. Откройте страницу свойств драйвера Sysvad и убедитесь, что для режима подписи>драйвера задано значение Test Sign.

  5. Примеры драйверов необходимо изменить для использования значений, которые не перекрываются с существующими драйверами. Ознакомьтесь с примерами кода к рабочему драйверу. Что нужно изменить в примерах , чтобы создать уникальный пример драйвера, который будет сосуществовать с существующими реальными драйверами, установленными в Windows.

  6. Создание примера с помощью Visual Studio

    В Visual Studio выберите "Сборка решения сборки>".

    Окна сборки должны отображать сообщение о том, что сборка для всех шести проектов выполнена успешно.

Совет

При возникновении сообщения об ошибке сборки используйте номер ошибки сборки для определения исправления. Например, ошибка MSBuild MSB8040 описывает, как работать с библиотеками с устранением рисков.

  1. Поиск встроенных файлов драйверов

    В проводник перейдите в папку, содержащую извлеченные файлы для примера. Например, вы перейдете в папку C:\WDK_Samples\Sysvad, если это указанная ранее папка. В этой папке расположение скомпилированных файлов драйверов зависит от параметров конфигурации и платформы, выбранных в Configuration Manager. Например, если вы оставили параметры по умолчанию без изменений, файлы скомпилированного драйвера будут сохранены в папке с именем \x64\Debug для 64-разрядной сборки отладки.

    Перейдите к папке, содержащей встроенные файлы для драйвера TabletAudioSample:

    C:\WDK_Samples\Sysvad\TabletAudioSample\x64\Debug. Папка будет содержать драйвер tabletAudioSample .SYS, файл pdp символов и inf-файл. Вам также потребуется найти библиотеки dll и файлы символов DelayAPO, KWSApo и KeywordDetectorContosoAdapter.

    Чтобы установить драйвер, вам потребуются следующие файлы.

    Имя файла Description
    TabletAudioSample.sys Файл драйвера.
    TabletAudioSample.pdb Файл символов драйвера.
    tabletaudiosample.inf Файл сведений (INF), содержащий сведения, необходимые для установки драйвера.
    KeywordDetectorContosoAdapter.dll Пример детектора ключевое слово.
    KeywordDetectorContosoAdapter.pdb Пример файла символов детектора ключевое слово.
    DelayAPO.dll Пример задержки APO.
    DelayAPO.pdb Файл символа задержки APO.
    KWSApo.dll Пример ключевое слово точечный объект APO.
    KWSApo.pdb Файл символов ключевое слово точечных знаков.
    TabletAudioSample.cer Файл сертификата TabletAudioSample.
  2. Найдите USB-диск или настройте сетевую папку для копирования встроенных файлов драйверов из узла в целевую систему.

В следующем разделе вы скопируете код в целевую систему и установите и протестируете драйвер.

Раздел 4. Установка примера звукового драйвера Sysvad в целевой системе

В разделе 4 вы будете использовать devcon для установки звукового драйвера Sysvad.

—> в целевой системе

Компьютер, на котором устанавливается драйвер, называется целевым компьютером или тест-компьютером. Как правило, это отдельный компьютер от компьютера, на котором вы разрабатываете и создаете пакет драйвера. Компьютер, на котором вы разрабатываете и создаете драйвер, называется узлом.

Процесс перемещения пакета драйвера на целевой компьютер и установка драйвера вызывается развертыванием драйвера.

Перед развертыванием драйвера необходимо подготовить целевой компьютер, включив подписывание тестов. После этого вы будете готовы запустить созданный пример драйвера в целевой системе.

Чтобы установить драйвер в целевой системе, выполните следующие действия.

  1. Включение тестовых подписанных драйверов

    Чтобы включить возможность запуска тестового подписанного драйвера, выполните следующие действия.

    1. Откройте Windows Параметры.

    2. В разделе "Обновление и безопасность" выберите "Восстановление".

    3. В разделе "Дополнительное запуск" выберите "Перезапустить сейчас".

    4. Когда компьютер перезагрузится, выберите "Устранение неполадок".

    5. Затем выберите дополнительные параметры, запуск Параметры и нажмите кнопку "Перезапустить".

    6. Выберите "Отключить принудительное применение подписи драйвера", нажав клавишу F7 .

    7. Компьютер начнется с новых значений.

  2. —> в целевой системе

    Установка драйвера

    В следующих инструкциях показано, как установить и проверить пример драйвера.

    INF-файл, необходимый для установки этого драйвера, — TabletAudioSample.inf. На целевом компьютере откройте окно командной строки как Администратор istrator. Перейдите в папку пакета драйвера, щелкните правой кнопкой мыши файл TabletAudioSample.inf и нажмите кнопку "Установить".

    Откроется диалоговое окно с указанием того, что тестовый драйвер является драйвером без знака. Выберите " Установить этот драйвер", чтобы продолжить работу.

    Снимок экрана: предупреждение Безопасность Windows о том, что Windows не может проверить издателя.

    Совет

     Если у вас возникли проблемы с установкой, проверка приведенный ниже файл для получения дополнительных сведений. %windir%\inf\setupapi.dev.log

    Дополнительные инструкции см. в разделе "Настройка компьютера для развертывания, тестирования и отладки драйверов".

    INF-файл содержит идентификатор оборудования для установки tabletaudiosample.sys. Для примера Syvad идентификатор оборудования: root\sysvad_TabletAudioSample

  3. Изучение драйвера в диспетчер устройств

    На целевом компьютере в окне командной строки введите devmgmt, чтобы открыть диспетчер устройств. В диспетчер устройств в меню "Вид" выберите "Устройства" по типу.

    В дереве устройств найдите виртуальные аудиоустройства (WDM) — пример планшета в узле аудиоустройства. Обычно это находится под узлом звуковых, видео и игровых контроллеров . Убедитесь, что он установлен и активен.

    Выделите драйвер для фактического оборудования на компьютере в диспетчер устройств. Затем выберите и удерживайте (или щелкните правой кнопкой мыши) драйвер и выберите отключить, чтобы отключить драйвер.

    Убедитесь, что в диспетчер устройств, что звуковой драйвер оборудования отображает стрелку вниз, указывающую, что она отключена.

    Снимок экрана: дерево диспетчер устройств с выделенным примером планшета виртуального звукового устройства.

    После успешной установки примера драйвера теперь можно протестировать его.

Тестирование звукового драйвера Sysvad

  1. На целевом компьютере в окне командной строки введите devmgmt, чтобы открыть диспетчер устройств. В диспетчер устройств в меню "Вид" выберите "Устройства" по типу. В дереве устройств найдите образец виртуального звукового устройства (WDM).

  2. Откройте панель управления и перейдите к аудиоустройствам и управлению звуком>. В диалоговом окне "Звук" выберите значок говорящего, помеченный как виртуальный звуковой устройство (WDM) — пример планшета, а затем нажмите кнопку "Задать значение по умолчанию", но не нажимайте кнопку "ОК". Откроется диалоговое окно "Звук".

  3. Найдите MP3 или другой звуковой файл на целевом компьютере и дважды щелкните его, чтобы воспроизвести его. Затем в диалоговом окне "Звук" убедитесь, что в индикаторе уровня громкости, связанном с драйвером уровня тома ( WDM) — пример драйвера планшета.

Раздел 5. Использование WinDbg для отображения сведений о драйвере

В разделе 5 вы настроите путь к символам и используйте команды отладчика ядра для отображения сведений о примере драйвера Sysvad.

Символы позволяют WinDbg отображать дополнительные сведения, такие как имена переменных, которые могут быть бесценными при отладке. WinDbg использует форматы отладочных символов Microsoft Visual Studio для отладки на уровне источника. Он может получить доступ к любому символу или переменной из модуля с файлами символов PDB.

Чтобы загрузить отладчик, выполните следующие действия.

<-В системе узла

  1. Если вы закрыли отладчик, снова откройте его с помощью следующей команды в окне командной строки администратора. Замените ключ и порт ранее настроенным.

    C:\> WinDbg –k net:port=50010,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    
  2. Используйте клавиши CTRL+Break (Scroll Lock) для разрыва кода, выполняемого в целевой системе.

Задать путь к символам

  1. Чтобы задать путь символов к серверу символов Майкрософт в среде WinDbg, используйте команду Symfix .

    0: kd> .symfix
    
  2. Чтобы добавить расположение локального символа для использования локальных символов, добавьте путь с помощью Sympath+ и перезагрузите /f.

    0: kd> .sympath+ C:\WDK_Samples\Sysvad
    0: kd> .reload /f
    

    Обратите внимание, что команда reload с параметром /f force удаляет все сведения о символах для указанного модуля и перезагружает символы. В некоторых случаях эта команда также перезагрузит или выгрузит сам модуль.

Обратите внимание , что необходимо загрузить соответствующие символы для использования расширенных функций, которые предоставляет WinDbg. Если у вас нет правильно настроенных символов, вы получите сообщения, указывающие, что символы недоступны при попытке использовать функции, зависящие от символов.

0:000> dv
Unable to enumerate locals, HRESULT 0x80004005
Private symbols (symbols.pri) are required for locals.
Type “.hh dbgerr005” for details.

Серверы символов заметок

Существует ряд подходов, которые можно использовать для работы с символами. Во многих ситуациях компьютер можно настроить для доступа к символам с сервера символов, который корпорация Майкрософт предоставляет при необходимости. В этом пошаговом руководстве предполагается, что этот подход будет использоваться. Если символы в вашей среде находятся в другом расположении, измените шаги, чтобы использовать это расположение. Дополнительные сведения см. в разделе "Путь к символам" для отладчика Windows.

Примечание. Общие сведенияо требованиях к символам исходного кода

Чтобы выполнить отладку источника, необходимо создать проверка (отладочную) версию двоичных файлов. Компилятор создаст файлы символов (PDB-файлы). Эти файлы символов показывают отладчику, как двоичные инструкции соответствуют исходным строкам. Фактические исходные файлы также должны быть доступны отладчику.

Файлы символов не содержат текст исходного кода. Для отладки лучше всего, если компоновщик не оптимизирует код. Отладка и доступ к локальным переменным сложнее, а иногда и почти невозможно, если код оптимизирован. Если у вас возникли проблемы с просмотром локальных переменных или исходных строк, задайте следующие параметры сборки.

set COMPILE_DEBUG=1

set ENABLE_OPTIMIZER=0

  1. Введите следующую команду в области команд отладчика, чтобы отобразить сведения о драйвере Sysvad.

    0: kd> lm m tabletaudiosample v
    Browse full module list
    start             end                 module name
    fffff801`14b40000 fffff801`14b86000   tabletaudiosample   (private pdb symbols)  C:\Debuggers\sym\TabletAudioSample.pdb\E992C4803EBE48C7B23DC1596495CE181\TabletAudioSample.pdb
        Loaded symbol image file: tabletaudiosample.sys
        Image path: \SystemRoot\system32\drivers\tabletaudiosample.sys
        Image name: tabletaudiosample.sys
        Browse all global symbols  functions  data
        Timestamp:        Thu Dec 10 12:20:26 2015 (5669DE8A)
        CheckSum:         0004891E
    ...  
    

    Дополнительные сведения см. в разделе lm.

  2. Выберите ссылку "Обзор всех глобальных символов" в выходных данных отладки, чтобы отобразить сведения о символах элементов, начинающихся с буквы a.

  3. Так как DML включен, некоторые элементы выходных данных являются горячими ссылками, которые можно выбрать. Выберите ссылку на данные в выходных данных отладки, чтобы отобразить сведения о символах элементов, начинающихся с буквы a.

    0: kd> x /D /f tabletaudiosample!a*
     A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    
    fffff806`9adb1000 tabletaudiosample!AddDevice (struct _DRIVER_OBJECT *, struct _DEVICE_OBJECT *)
    

    Дополнительные сведения см. в разделе x (Проверка символов).

  4. Расширение !lmi отображает подробные сведения о модуле. Тип !lmi tabletaudiosample. Выходные данные должны быть похожи на текст, показанный ниже.

    0: kd> !lmi tabletaudiosample
    Loaded Module Info: [tabletaudiosample] 
             Module: tabletaudiosample
       Base Address: fffff8069ad90000
         Image Name: tabletaudiosample.sys
       Machine Type: 34404 (X64)
         Time Stamp: 58ebe848 Mon Apr 10 13:17:12 2017
               Size: 48000
           CheckSum: 42df7
    Characteristics: 22  
    Debug Data Dirs: Type  Size     VA  Pointer
                 CODEVIEW    a7,  e5f4,    d1f4 RSDS - GUID: {5395F0C5-AE50-4C56-AD31-DD5473BD318F}
                   Age: 1, Pdb: C:\Windows-driver-samples-master\audio\sysvad\TabletAudioSample\x64\Debug\TabletAudioSample.pdb
                       ??   250,  e69c,    d29c [Data not mapped]
         Image Type: MEMORY   - Image read successfully from loaded memory.
        Symbol Type: PDB      - Symbols loaded successfully from image header.
                     C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\sym\TabletAudioSample.pdb\5395F0C5AE504C56AD31DD5473BD318F1\TabletAudioSample.pdb
           Compiler: Resource - front end [0.0 bld 0] - back end [14.0 bld 24210]
        Load Report: private symbols & lines, not source indexed 
                     C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\sym\TabletAudioSample.pdb\5395F0C5AE504C56AD31DD5473BD318F1\TabletAudioSample.pdb
    
  5. Используйте расширение !dh для отображения сведений о заголовке, как показано ниже.

    0: kd> !dh tabletaudiosample 
    
    File Type: EXECUTABLE IMAGE
    FILE HEADER VALUES
        8664 machine (X64)
           9 number of sections
    5669DE8A time date stamp Thu Dec 10 12:20:26 2015
    
           0 file pointer to symbol table
           0 number of symbols
          F0 size of optional header
          22 characteristics
                Executable
                App can handle >2gb addresses
    ...
    

Раздел 6. Отображение сведений о дереве устройств самонастраивающийся

В разделе 6 вы увидите сведения о примере драйвера устройства Sysvad и о том, где он находится в дереве устройств самонастраивающийся.

Сведения об драйвере устройства в дереве устройств самонастраивающийся могут быть полезны для устранения неполадок. Например, если драйвер устройства не находится в дереве устройств, может возникнуть проблема с установкой драйвера устройства.

Дополнительные сведения о расширении отладки узла устройства см. в разделе !devnode.

<-В системе узла

  1. Чтобы просмотреть все узлы устройств в дереве устройств самонастраивающийся, введите команду !devnode 0 1. Эта команда может занять минуту или два. В течение этого времени "*Занят" будет отображаться в области состояния WinDbg.

    0: kd> !devnode 0 1
    Dumping IopRootDeviceNode (= 0xffffe0005a3a8d30)
    DevNode 0xffffe0005a3a8d30 for PDO 0xffffe0005a3a9e50
      InstancePath is "HTREE\ROOT\0"
      State = DeviceNodeStarted (0x308)
      Previous State = DeviceNodeEnumerateCompletion (0x30d)
      DevNode 0xffffe0005a3a3d30 for PDO 0xffffe0005a3a4e50
        InstancePath is "ROOT\volmgr\0000"
        ServiceName is "volmgr"
        State = DeviceNodeStarted (0x308)
        Previous State = DeviceNodeEnumerateCompletion (0x30d)
        DevNode 0xffffe0005a324560 for PDO 0xffffe0005bd95ca0…
    ...
    
  2. Используйте CTRL+F для поиска в выходных данных, созданных для поиска имени драйвера устройства, sysvad.

    Диалоговое окно поиска с термином sysvad, введенным в поле поиска.

    Запись узла устройства с именем sysvad_TabletAudioSample будет присутствовать в выходных данных !devnode для Syvad.

      DevNode 0xffffe00086e68190 for PDO 0xffffe00089c575a0
        InstancePath is "ROOT\sysvad_TabletAudioSample\0000"
        ServiceName is "sysvad_tabletaudiosample"
        State = DeviceNodeStarted (0x308)
    ...
    

    Обратите внимание, что отображается адрес PDO и адрес DevNode.

  3. Используйте команду для отображения самонастраивающийся сведений, связанных с драйвером !devnode 0 1 sysvad_TabletAudioSample устройства Sysvad.

    0: kd> !devnode 0 1 sysvad_TabletAudioSample
    Dumping IopRootDeviceNode (= 0xffffe00082df8d30)
    DevNode 0xffffe00086e68190 for PDO 0xffffe00089c575a0
      InstancePath is "ROOT\sysvad_TabletAudioSample\0000"
      ServiceName is "sysvad_tabletaudiosample"
      State = DeviceNodeStarted (0x308)
      Previous State = DeviceNodeEnumerateCompletion (0x30d)
      DevNode 0xffffe000897fb650 for PDO 0xffffe00089927e30
        InstancePath is "SWD\MMDEVAPI\{0.0.0.00000000}.{64097438-cdc0-4007-a19e-62e789062e20}"
        State = DeviceNodeStarted (0x308)
        Previous State = DeviceNodeStartPostWork (0x307)
      DevNode 0xffffe00086d2f5f0 for PDO 0xffffe00089939ae0
        InstancePath is "SWD\MMDEVAPI\{0.0.0.00000000}.{78880f4e-9571-44a4-a9df-960bde446487}"
        State = DeviceNodeStarted (0x308)
        Previous State = DeviceNodeStartPostWork (0x307)
      DevNode 0xffffe00089759bb0 for PDO 0xffffe000875aa060
        InstancePath is "SWD\MMDEVAPI\{0.0.0.00000000}.{7cad07f2-d0a0-4b9b-8100-8dc735e9c447}"
        State = DeviceNodeStarted (0x308)
        Previous State = DeviceNodeStartPostWork (0x307)
      DevNode 0xffffe00087735010 for PDO 0xffffe000872068c0
        InstancePath is "SWD\MMDEVAPI\{0.0.0.00000000}.{fc38551b-e69f-4b86-9661-ae6da78bc3c6}"
        State = DeviceNodeStarted (0x308)
        Previous State = DeviceNodeStartPostWork (0x307)
      DevNode 0xffffe00088457670 for PDO 0xffffe0008562b830
        InstancePath is "SWD\MMDEVAPI\{0.0.1.00000000}.{0894b831-c9fe-4c56-86a6-092380fc5628}"
        State = DeviceNodeStarted (0x308)
        Previous State = DeviceNodeStartPostWork (0x307)
      DevNode 0xffffe000893dbb70 for PDO 0xffffe00089d68060
        InstancePath is "SWD\MMDEVAPI\{0.0.1.00000000}.{15eb6b5c-aa54-47b8-959a-0cff2c1500db}"
        State = DeviceNodeStarted (0x308)
        Previous State = DeviceNodeStartPostWork (0x307)
      DevNode 0xffffe00088e6f250 for PDO 0xffffe00089f6e990
        InstancePath is "SWD\MMDEVAPI\{0.0.1.00000000}.{778c07f0-af9f-43f2-8b8d-490024f87239}"
        State = DeviceNodeStarted (0x308)
        Previous State = DeviceNodeStartPostWork (0x307)
      DevNode 0xffffe000862eb4b0 for PDO 0xffffe000884443a0
        InstancePath is "SWD\MMDEVAPI\{0.0.1.00000000}.{e4b72c7c-be50-45df-94f5-0f2922b85983}"
        State = DeviceNodeStarted (0x308)
        Previous State = DeviceNodeStartPostWork (0x307)
    
  4. Выходные данные, отображаемые в предыдущей команде, включают PDO, связанный с запущенным экземпляром драйвера, в этом примере это 0xffffe00089c575a0. Введите команду адреса> PDO !devobj<, чтобы отобразить самонастраивающийся сведения, связанные с драйвером устройства Sysvad. Используйте адрес PDO, отображаемый на компьютере !devnode , а не тот, который показан здесь.

    0: kd> !devobj 0xffffe00089c575a0
    Device object (ffffe00089c575a0) is for:
    0000004e \Driver\PnpManager DriverObject ffffe00082d47e60
    Current Irp 00000000 RefCount 65 Type 0000001d Flags 00001040
    SecurityDescriptor ffffc102b0f6d171 DevExt 00000000 DevObjExt ffffe00089c576f0 DevNode ffffe00086e68190 
    ExtensionFlags (0000000000)  
    Characteristics (0x00000180)  FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN
    AttachedDevice (Upper) ffffe00088386a50 \Driver\sysvad_tabletaudiosample
    Device queue is not busy.
    
  5. Выходные данные, отображаемые в команде !devobj , включают имя подключенного устройства: \Driver\sysvad_tabletaudiosample. Используйте команду !drvobj с битовой маской 2, чтобы отобразить сведения, связанные с подключенным устройством.

    0: kd> !drvobj \Driver\sysvad_tabletaudiosample 2
    Driver object (ffffe0008834f670) is for:
    \Driver\sysvad_tabletaudiosample
    DriverEntry:   fffff80114b45310  tabletaudiosample!FxDriverEntry
    DriverStartIo: 00000000 
    DriverUnload:  fffff80114b5fea0                tabletaudiosample!DriverUnload
    AddDevice:     fffff80114b5f000  tabletaudiosample!AddDevice
    
    Dispatch routines:
    [00] IRP_MJ_CREATE                      fffff80117b49a20             portcls!DispatchCreate
    [01] IRP_MJ_CREATE_NAMED_PIPE           fffff8015a949a00          nt!IopInvalidDeviceRequest
    [02] IRP_MJ_CLOSE                       fffff80115e26f90                ks!DispatchCleanup
    [03] IRP_MJ_READ                        fffff80115e32710                ks!DispatchRead
    [04] IRP_MJ_WRITE                       fffff80115e327e0              ks!DispatchWrite
    [05] IRP_MJ_QUERY_INFORMATION           fffff8015a949a00         nt!IopInvalidDeviceRequest
    [06] IRP_MJ_SET_INFORMATION             fffff8015a949a00              nt!IopInvalidDeviceRequest
    [07] IRP_MJ_QUERY_EA                    fffff8015a949a00         nt!IopInvalidDeviceRequest
    [08] IRP_MJ_SET_EA                      fffff8015a949a00              nt!IopInvalidDeviceRequest
    [09] IRP_MJ_FLUSH_BUFFERS               fffff80115e32640  ks!DispatchFlush
    [0a] IRP_MJ_QUERY_VOLUME_INFORMATION    fffff8015a949a00           nt!IopInvalidDeviceRequest
    [0b] IRP_MJ_SET_VOLUME_INFORMATION      fffff8015a949a00               nt!IopInvalidDeviceRequest
    [0c] IRP_MJ_DIRECTORY_CONTROL           fffff8015a949a00           nt!IopInvalidDeviceRequest
    [0d] IRP_MJ_FILE_SYSTEM_CONTROL         fffff8015a949a00         nt!IopInvalidDeviceRequest
    [0e] IRP_MJ_DEVICE_CONTROL              fffff80115e27480               ks!DispatchDeviceIoControl
    [0f] IRP_MJ_INTERNAL_DEVICE_CONTROL     fffff8015a949a00   nt!IopInvalidDeviceRequest
    [10] IRP_MJ_SHUTDOWN                    fffff8015a949a00      nt!IopInvalidDeviceRequest
    [11] IRP_MJ_LOCK_CONTROL                fffff8015a949a00  nt!IopInvalidDeviceRequest
    [12] IRP_MJ_CLEANUP                     fffff8015a949a00           nt!IopInvalidDeviceRequest
    [13] IRP_MJ_CREATE_MAILSLOT             fffff8015a949a00               nt!IopInvalidDeviceRequest
    [14] IRP_MJ_QUERY_SECURITY              fffff80115e326a0 ks!DispatchQuerySecurity
    [15] IRP_MJ_SET_SECURITY                fffff80115e32770      ks!DispatchSetSecurity
    [16] IRP_MJ_POWER                       fffff80117b3dce0            portcls!DispatchPower
    [17] IRP_MJ_SYSTEM_CONTROL              fffff80117b13d30              portcls!PcWmiSystemControl
    [18] IRP_MJ_DEVICE_CHANGE               fffff8015a949a00 nt!IopInvalidDeviceRequest
    [19] IRP_MJ_QUERY_QUOTA                 fffff8015a949a00  nt!IopInvalidDeviceRequest
    [1a] IRP_MJ_SET_QUOTA                   fffff8015a949a00       nt!IopInvalidDeviceRequest
    [1b] IRP_MJ_PNP                         fffff80114b5f7d0 tabletaudiosample!PnpHandler
    
  6. Введите команду адресного адреса> !devstack<PDO, чтобы отобразить самонастраивающийся сведения, связанные с драйвером устройства. Выходные данные, отображаемые в команде !devnode 0 1 , включают адрес PDO, связанный с запущенным экземпляром нашего драйвера. В этом примере 0xffffe00089c575a0. Используйте адрес PDO, отображаемый на компьютере !devnode , а не указанный ниже.

    0: kd> !devstack 0xffffe00089c575a0
      !DevObj           !DrvObj            !DevExt           ObjectName
      ffffe00088d212e0  \Driver\ksthunk    ffffe00088d21430  0000007b
      ffffe00088386a50  \Driver\sysvad_tabletaudiosampleffffe00088386ba0  0000007a
    > ffffe00089c575a0  \Driver\PnpManager 00000000  0000004e
    !DevNode ffffe00086e68190 :
      DeviceInst is "ROOT\sysvad_TabletAudioSample\0000"
      ServiceName is "sysvad_tabletaudiosample"
    

В выходных данных показано, что у нас есть очень простой стек драйверов устройств. Драйвер sysvad_TabletAudioSample является дочерним элементом узла PnPManager. PnPManager является корневым узлом.

На этой схеме показано более сложное дерево узлов устройства.

Схема дерева узла устройства, состоящего примерно из 20 узлов.

Дополнительные сведения о более сложных стеках драйверов см. в стекахдрайверов и узлах устройств и стеках устройств.

Раздел 7. Работа с точками останова

В разделе 7 вы будете работать с точками останова, чтобы остановить выполнение кода в определенных точках.

Настройка точек останова с помощью команд

Точки останова используются для остановки выполнения кода в определенной строке кода. Затем можно выполнить шаг вперед в коде с этого момента, чтобы отладить этот конкретный раздел кода.

Чтобы задать точку останова с помощью команды отладки, используйте одну из следующих команд b .

bp

Задает точку останова, которая будет активной до тех пор, пока модуль не будет выгружен.

Bu

Задает точку останова, которая неразрешенная при выгрузке модуля и повторно включается при перезагрузке модуля.

Bm

Задает точку останова для символа. Эта команда будет использовать bu или bp соответствующим образом и позволяет использовать дикие карта * для задания точек останова для всех символов, которые соответствуют (как и все методы в классе).

  1. Используйте пользовательский интерфейс WinDbg, чтобы убедиться, что режим источника отладки>включен в текущем сеансе WinDbg.

  2. Добавьте расположение локального кода в исходный путь, введя следующую команду.

    .sympath+ C:\WDK_Samples\Sysvad
    
  3. Добавьте расположение локального символа в путь к символу, введя следующую команду.

    .sympath+ C:\WDK_Samples\Sysvad
    
  4. Настройка маски отладки

    Так как вы работаете с драйвером, это может быть удобно, чтобы просмотреть все сообщения, которые он может отобразить. Введите следующую команду, чтобы изменить маску битовой отладки по умолчанию, чтобы все отладочные сообщения из целевой системы отображались в отладчике.

    0: kd> ed nt!Kd_DEFAULT_MASK 0xFFFFFFFF
    
  5. Задайте точку останова с помощью команды bm с именем драйвера, а затем именем функции (AddDevice), где нужно задать точку останова, разделенную восклицательным знаком.

    0: kd> bm tabletaudiosample!AddDevice
    breakpoint 1 redefined
      1: fffff801`14b5f000 @!"tabletaudiosample!AddDevice"
    

    Вы можете использовать другой синтаксис в сочетании с параметрами переменных, таких как <модуль>!<символ>, класс>::<method>,<'<file.cpp>:<line number>', или пропустить несколько раз <условие><#>. Для получения дополнительной информации см. Using Breakpoints.

  6. Перечислите текущие точки останова, чтобы убедиться, что точка останова была задана, введя команду BL .

    0: kd> bl
    1 e fffff801`14b5f000     0001 (0001) tabletaudiosample!AddDevice
    
  7. Перезапустите выполнение кода в целевой системе, введя команду go g.

  8. ->В целевой системе

    В Windows откройте диспетчер устройств с помощью значка или введите mmc devmgmt.msc. В диспетчер устройств разверните узел "Звук", "Видео" и "Игровые контроллеры". Выберите и удерживайте (или щелкните правой кнопкой мыши) запись виртуального звукового драйвера и выберите "Отключить " в меню.

  9. Выберите и удерживайте (или щелкните правой кнопкой мыши) запись виртуального звукового драйвера и выберите " Включить " в меню.

  10. <— в хост-системе

    Это должно привести к перезагрузу драйвера Windows, который вызывает AddDevice. Это приведет к остановке точки останова отладки AddDevice, а выполнение кода драйвера в целевой системе должно остановиться.

    Breakpoint 1 hit
    tabletaudiosample!AddDevice:
    fffff801`14baf000 4889542410      mov     qword ptr [rsp+10h],rdx
    

    Если исходный путь задан правильно, следует остановиться в подпрограмме AddDevice в adapter.cpp

    {
        PAGED_CODE();
    
        NTSTATUS        ntStatus;
        ULONG           maxObjects;
    
        DPF(D_TERSE, ("[AddDevice]"));
    
        maxObjects = g_MaxMiniports;
    
        #ifdef SYSVAD_BTH_BYPASS
        // 
        // Allow three (3) Bluetooth hands-free profile devices.
        //
        maxObjects += g_MaxBthHfpMiniports * 3; 
        #endif // SYSVAD_BTH_BYPASS
    
        // Tell the class driver to add the device.
        //
        ntStatus = 
            PcAddAdapterDevice
            ( 
                DriverObject,
                PhysicalDeviceObject,
                PCPFNSTARTDEVICE(StartDevice),
                maxObjects,
                0
            );
        return ntStatus;
    } // AddDevice
    
  11. Пошаговые строки по коду, введя команду p или нажав клавишу F10. Вы можете выйти из кода sysvad AddDevice в PpvUtilCall, PnpCallAddDevice, а затем в код Windows PipCallDriverAddDevice. Вы можете указать номер для команды p , чтобы выполнить шаг вперед нескольких строк, например p 5.

  12. Завершив пошаговое выполнение кода, используйте команду go g , чтобы перезапустить выполнение в целевой системе.

Настройка точек останова доступа к памяти

Вы также можете задать точки останова, которые запускаются при доступе к расположению памяти. Используйте команду ba (break on access) со следующим синтаксисом.

ba <access> <size> <address> {options}
Вариант Описание

e

выполнение (при получении инструкции из адреса ЦП)

r

чтение и запись (при чтении или записи ЦП в адрес)

w

запись (когда ЦП записывает в адрес)

Обратите внимание, что вы можете задать только четыре точки останова данных в любой момент времени, и вам нужно убедиться, что вы правильно выравниваете данные или не активируете точку останова (слова должны заканчиваться адресами, делимыми на 2, dwords должны быть делимыми на 4, а квадры на 0 или 8)

Например, чтобы задать точку останова чтения и записи для определенного адреса памяти, используйте следующую команду.

ba r 4 fffff800`7bc9eff0

Изменение состояния точки останова

Существующие точки останова можно изменить с помощью следующих команд.

bl

Выводит список точек останова.

Bc

Очищает точку останова из списка. Используйте bc * для очистки всех точек останова.

bd

Отключает точку останова. Используйте bd * для отключения всех точек останова.

be

Включает точку останова. Используйте значение * для включения всех точек останова.

Кроме того, можно изменить точки останова, выбрав пункты останова>. Обратите внимание, что диалоговое окно точки останова работает только с существующими точками останова. Новые точки останова должны быть заданы из командной строки.

Установка точки останова в MixerVolume

Различные части кода звукового драйвера вызываются для реагирования на различные события после загрузки драйвера устройства. В следующем разделе мы устанавливаем точку останова, которая будет запускаться при настройке пользователем элемента управления громкости для виртуального звукового драйвера.

Чтобы задать точку останова в MixerVolume, выполните следующие действия.

  1. <— в хост-системе

    Чтобы найти метод, который изменяет том, используйте команду x для перечисления символов в CAdapterCommon, содержащих строковый том.

    kd> x tabletaudiosample!CAdapterCommon::*
    ...
    fffff800`7bce26a0 tabletaudiosample!CAdapterCommon::MixerVolumeWrite (unsigned long, unsigned long, long)
    …
    

    Используйте CTRL+F для поиска вверх в выходных данных для тома и найдите метод MixerVolumeWrite.

  2. Снимите предыдущие точки останова с помощью bc *.

  3. Задайте точку останова символа в подпрограмме CAdapterCommon::MixerVolumeWrite с помощью следующей команды.

    kd> bm tabletaudiosample!CAdapterCommon::MixerVolumeWrite
      1: fffff801`177b26a0 @!"tabletaudiosample!CAdapterCommon::MixerVolumeWrite"
    
  4. Выведите список точек останова, чтобы убедиться, что точка останова задана правильно.

    kd> bl
    1 e fffff801`177b26a0 [c:\WDK_Samples\audio\sysvad\common.cpp @ 1668]    0001 (0001) tabletaudiosample!CAdapterCommon::MixerVolumeWrite
    
  5. Перезапустите выполнение кода в целевой системе, введя команду go g.

  6. В панель управления выберите оборудование и звук>. Выберите и удерживайте (или щелкните правой кнопкой мыши) Пример описания приемника и выберите свойства. Перейдите на вкладку "Уровни ". Настройте том ползунка.

  7. Это должно привести к остановке точки останова отладки SetMixerVolume и выполнению кода драйвера в целевой системе.

    kd> g
    Breakpoint 1 hit
    tabletaudiosample!CAdapterCommon::MixerVolumeWrite:
    fffff801`177b26a0 44894c2420      mov     dword ptr [rsp+20h],r9d
    

    Вы должны остановиться на этой строке в common.cpp

    {
        if (m_pHW)
        {
            m_pHW->SetMixerVolume(Index, Channel, Value);
        }
    } // MixerVolumeWrite
    
  8. Используйте команду dv для отображения текущих переменных и их значений. Дополнительные сведения о переменных приведены в следующем разделе этой лаборатории.

    2: kd> dv
               this = 0x00000000`00000010
             ulNode = 0x344
          ulChannel = 0x210a45f8
            lVolume = 0n24
    
  9. Нажмите клавишу F10 , чтобы выполнить один шаг по коду.

  10. Нажмите клавишу F5 , чтобы завершить выполнение кода MixerVolumeWrite.

Сводка. Пошаговое выполнение кода из командного окна отладчика

Ниже приведены команды, которые можно использовать для пошагового выполнения кода (с соответствующими короткими сокращениями клавиатуры, показанными в скобках).

  • Разрыв (CTRL+Break) — эта команда прерывает работу системы до тех пор, пока система запущена и находится в связи с WinDbg (последовательность в отладчике ядра — CTRL+C).

  • Шаг над (F10) — эта команда приводит к выполнению кода для выполнения одной инструкции или одной инструкции за раз. При обнаружении вызова выполнение кода передает вызов без ввода вызываемой подпрограммы. (Если язык программирования — C или C++ и WinDbg находится в исходном режиме, исходный режим можно включить или отключить с помощью Режим источника отладки>).

  • Шаг (F11) — эта команда похожа на пошаговое выполнение, за исключением того, что выполнение вызова переходит в вызываемую подпрограмму.

  • Шаг выхода (SHIFT+F11) — эта команда приводит к выполнению и выходу из текущей подпрограммы (текущее место в стеке вызовов). Это полезно, если вы видели достаточно подпрограммы.

  • Запустите на курсор (F7 или CTRL+F10) — поместите курсор в исходное или дизассемблированное окно, в котором нужно разбить выполнение, а затем нажмите клавишу F7; Выполнение кода будет выполняться до этой точки. Обратите внимание, что если поток выполнения кода не достигает точки, указанной курсором (например, оператор IF не выполняется), WinDbg не будет разрываться, так как выполнение кода не достигло указанной точки.

  • Запуск (F5) — запуск до тех пор, пока не будет обнаружена точка останова или событие, например ошибка проверка.

Дополнительные параметры

  • Задайте инструкцию текущей строке (CTRL+SHIFT+I) — в окне источника вы можете поместить курсор в строку, ввести это сочетание клавиш, а выполнение кода начнется с этого момента, как только вы позволите ему продолжить (например, с помощью F5 или F10). Это удобно, если вы хотите повторить последовательность, но это требует некоторого ухода. Например, регистры и переменные не задаются в том, что они будут иметь, если выполнение кода достигло этой строки естественным образом.

  • Прямое задание регистра eip . Вы можете поместить значение в регистр eip, и как только вы нажимаете клавишу F5 (или F10, F11 и т. д.), выполнение начинается с этого адреса. Это аналогично настройке инструкции для текущей строки, назначенной курсором, за исключением того, что вы указываете адрес инструкции сборки.

Это может быть проще для пошагового выполнения пользовательского интерфейса, а не из командной строки, поэтому этот метод рекомендуется. При необходимости можно использовать следующие команды для пошагового выполнения исходного файла в командной строке:

  • .line — включение сведений о исходной строке.

  • bp main — задайте начальную точку останова в начале модуля.

  • l+t — пошаговое выполнение будет выполнено по исходной строке.

  • Выберите режим источника отладки>, чтобы ввести исходный режим. Команда L+t недостаточно.

  • l+s — исходные строки будут отображаться по запросу.

  • g — запуск программы до ввода "main".

  • p — выполнение одной исходной строки.

Дополнительные сведения см. в статье "Отладка исходного кода" в WinDbg (классическая версия) в справочной документации по отладке.

Установка точек останова в коде

Вы можете задать точку останова в коде, добавив DebugBreak() инструкцию и перестроив проект и повторно установив драйвер. Эта точка останова будет запускаться каждый раз, когда драйвер включен, поэтому это методы, которые будут использоваться на ранних этапах разработки, а не в рабочем коде. Этот метод не так гибкий, как динамическое задание точек останова с помощью команд точек останова.

Совет. Вы можете сохранить копию драйвера Sysvad, добавив точку останова для дальнейшей работы лаборатории.

  1. Задайте разрыв для каждого выполнения метода AddDevice путем добавления DebugBreak() инструкции в пример кода.

    ...
        // Insert the DebugBreak() statment before the  PcAddAdapterDevice is called.
        //
    
        DebugBreak()
    
        // Tell the class driver to add the device.
        //
        ntStatus = 
            PcAddAdapterDevice
            ( 
                DriverObject,
                PhysicalDeviceObject,
                PCPFNSTARTDEVICE(StartDevice),
                maxObjects,
                0
            );
    
        return ntStatus;
    } // AddDevice
    
  2. Выполните все описанные ранее действия, чтобы перестроить драйвер в Microsoft Visual Studio и повторно установить его на целевой компьютер. Перед установкой обновленного драйвера обязательно удалите существующий драйвер.

  3. Снимите все предыдущие точки останова и убедитесь, что отладчик подключен к целевому компьютеру.

  4. Когда код запускается и достигает инструкции DebugBreak , выполнение будет остановлено, и появится сообщение.

    KERNELBASE!DebugBreak:
    77b3b770 defe     __debugbreak
    

Раздел 8. Отображение переменных

В разделе 8 вы будете использовать команды отладчика для отображения переменных.

Это может быть полезно для проверки переменных при выполнении кода, чтобы убедиться, что код работает должным образом. В этой лаборатории проверяются переменные, так как звуковой драйвер создает звук.

  1. Используйте команду dv, чтобы проверить переменные языкового стандарта, связанные с планшетом tabletaudiosample! CMiniportWaveRT::New*.

    kd> dv tabletaudiosample!CMiniportWaveRT::New*
    
  2. Очистка предыдущих точек останова

    bc *
    
  3. Задайте точку останова символов в подпрограммах CMiniportWaveCyclicStreamMSVAD с помощью следующей команды.

    0: kd> bm tabletaudiosample!CMiniportWaveRT::NewStream
      1: fffff801`177dffc0 @!"tabletaudiosample!CMiniportWaveRT::NewStream"
    
  4. Перезапустите выполнение кода в целевой системе, введя команду go g.

  5. —> в целевой системе

    Найдите небольшой файл мультимедиа (например, звуковой файл уведомлений Windows с расширением .wav файла) и выберите файл для воспроизведения. Например, можно использовать Ring05.wav, расположенные в каталоге Windows\Media.

  6. <— в хост-системе

    При воспроизведении файла мультимедиа точка останова должна запускаться, а выполнение кода драйвера в целевой системе должно остановиться.

    Breakpoint 1 hit
    tabletaudiosample!CMiniportWaveRT::NewStream:
    fffff801`177dffc0 44894c2420      mov     dword ptr [rsp+20h],r9d
    

    Окно исходного кода должно выделять фигурную скобку на входе в функцию NewStream.

    /*++
    
    Routine Description:
    
      The NewStream function creates a new instance of a logical stream 
      associated with a specified physical channel. Callers of NewStream should 
      run at IRQL PASSIVE_LEVEL.
    
    Arguments:
    
      OutStream -
    
      OuterUnknown -
    
      Pin - 
    
      Capture - 
    
      DataFormat -
    
    Return Value:
    
      NT status code.
    
    --*/
    {
    
    ...
    
  7. Локальные переменные

    Имена и значения всех локальных переменных для заданного кадра можно отобразить, введя команду dv .

    0: kd> dv
                    this = 0xffffe000`4436f8e0
               OutStream = 0xffffe000`49d2f130
            OuterUnknown = 0xffffe000`4436fa30
                     Pin = 0
                 Capture = 0x01 '
              DataFormat = 0xffffe000`44227790
    signalProcessingMode = {487E9220-E000-FFFF-30F1-D24900E0FFFF}
                ntStatus = 0n1055
                  stream = 0x00000000`00000200
    
  8. Использование DML для отображения переменных

    Чтобы использовать DML для изучения переменных, выберите подчеркнутые элементы. Действие выбора создает команду dx (Display NatVis Expression), которая позволяет детализировать вложенные структуры данных.

    0: kd> dx -r1 (*((tabletaudiosample!CMiniportWaveRT *)0xffffe001d10b8380))
    (*((tabletaudiosample!CMiniportWaveRT *)0xffffe001d10b8380)) :  [Type: CMiniportWaveRT]
        [+0x020] m_lRefCount      : 0
        [+0x028] m_pUnknownOuter  : 0xffffe001d1477e50 : [Type: IUnknown *]
        [+0x030] m_ulLoopbackAllocated : 0x2050
        [+0x034] m_ulSystemAllocated : 0x180
        [+0x038] m_ulOffloadAllocated : 0x0
        [+0x03c] m_dwCaptureAllocatedModes : 0x0
    
    0: kd> dx -r1 (*((tabletaudiosample!_GUID *)0xffffd001c8acd348))
    (*((tabletaudiosample!_GUID *)0xffffd001c8acd348)) : {487E9220-E000-FFFF-30F1-D24900E0FFFF} [Type: _GUID]
        [<Raw View>]    
    
    0: kd> dx -r1 -n (*((tabletaudiosample!_GUID *)0xffffd001c8acd348))
    (*((tabletaudiosample!_GUID *)0xffffd001c8acd348)) :  [Type: _GUID]
        [+0x000] Data1            : 0x487e9220
        [+0x004] Data2            : 0xe000
        [+0x006] Data3            : 0xffff
        [+0x008] Data4            :  [Type: unsigned char [8]]
    
    0: kd> dx -r1 -n (*((tabletaudiosample!unsigned char (*)[8])0xffffd001c8acd350))
    (*((tabletaudiosample!unsigned char (*)[8])0xffffd001c8acd350)) :  [Type: unsigned char [8]]
        [0]              : 0x30
        [1]              : 0xf1
        [2]              : 0xd2
        [3]              : 0x49
        [4]              : 0x0
        [5]              : 0xe0
        [6]              : 0xff
        [7]              : 0xff
    
  9. Глобальные переменные

    Расположение памяти глобальной переменной можно найти, введя ? <имя> переменной.

    0: kd> ? signalProcessingMode
    Evaluate expression: -52768896396472 = ffffd001`c8acd348
    
  10. Это возвращает расположение памяти переменной в данном случае ffffd001'c8acd348. Вы можете просмотреть содержимое расположения памяти, дампав значение этого расположения, введя команду dd с помощью расположения памяти, возвращаемого предыдущей командой.

    0: kd> dd ffffd001`c8acd348
    ffffd001`c8acd348  487e9220 ffffe000 49d2f130 ffffe000
    ffffd001`c8acd358  4837c468 ffffe000 18221570 ffffc000
    ffffd001`c8acd368  4436f8e0 ffffe000 487e9220 ffffe000
    ffffd001`c8acd378  18ab145b fffff801 4837c420 ffffe000
    ffffd001`c8acd388  4436f8e0 ffffe000 49d2f130 ffffe000
    ffffd001`c8acd398  4436fa30 ffffe000 00000000 00000000
    ffffd001`c8acd3a8  00000001 00000000 44227790 ffffe000
    ffffd001`c8acd3b8  18adc7f9 fffff801 495972a0 ffffe000
    
  11. Можно также использовать имена переменных с командой dd .

    0: kd> dd signalProcessingMode
    ffffd001`c8acd348  487e9220 ffffe000 49d2f130 ffffe000
    ffffd001`c8acd358  4837c468 ffffe000 18221570 ffffc000
    ffffd001`c8acd368  4436f8e0 ffffe000 487e9220 ffffe000
    ffffd001`c8acd378  18ab145b fffff801 4837c420 ffffe000
    ffffd001`c8acd388  4436f8e0 ffffe000 49d2f130 ffffe000
    ffffd001`c8acd398  4436fa30 ffffe000 00000000 00000000
    ffffd001`c8acd3a8  00000001 00000000 44227790 ffffe000
    ffffd001`c8acd3b8  18adc7f9 fffff801 495972a0 ffffe000
    
  12. Отображение переменных

    Чтобы отобразить локальные переменные, используйте пункт меню "Просмотр>локальных языков". Этот интерфейс также предоставляет эту возможность детализации на более сложных структурах данных.

    Интерфейс WinDbg, отображающий локальные коды и окна команд.

  13. Используйте p или F10, чтобы выполнить шаг вперед около 10 строк в коде, пока не будет выделен ntStatus = IsFormatSupported(Pin, Capture, DataFormat); строка кода.

        PAGED_CODE();
    
        ASSERT(OutStream);
        ASSERT(DataFormat);
    
        DPF_ENTER(("[CMiniportWaveRT::NewStream]"));
    
        NTSTATUS                    ntStatus = STATUS_SUCCESS;
        PCMiniportWaveRTStream      stream = NULL;
        GUID                        signalProcessingMode = AUDIO_SIGNALPROCESSINGMODE_DEFAULT;
    
        *OutStream = NULL;
    
         //
        // If the data format attributes were specified, extract them.
        //
        if ( DataFormat->Flags & KSDATAFORMAT_ATTRIBUTES )
        {
            // The attributes are aligned (QWORD alignment) after the data format
            PKSMULTIPLE_ITEM attributes = (PKSMULTIPLE_ITEM) (((PBYTE)DataFormat) + ((DataFormat->FormatSize + FILE_QUAD_ALIGNMENT) & ~FILE_QUAD_ALIGNMENT));
            ntStatus = GetAttributesFromAttributeList(attributes, attributes->Size, &signalProcessingMode);
        }
    
        // Check if we have enough streams.
        //
        if (NT_SUCCESS(ntStatus))
        {
            ntStatus = ValidateStreamCreate(Pin, Capture, signalProcessingMode);
        }
    
        // Determine if the format is valid.
        //
        if (NT_SUCCESS(ntStatus))
        {
            ntStatus = IsFormatSupported(Pin, Capture, DataFormat);
        }
    
    ...
    
  14. Используйте команду DV для отображения имен и значений всех локальных переменных для заданного кадра. Обратите внимание, что, как ожидалось, значения отличаются от последнего выполнения этой команды, так как дополнительный код был запущен, который изменяет локальные переменные, а некоторые переменные теперь не находятся в текущем кадре или их значения изменились.

    2: kd> dv
                    this = 0xffffe001`d1182000
               OutStream = 0xffffe001`d4776d20
            OuterUnknown = 0xffffe001`d4776bc8
                     Pin = 0
                 Capture = 0x00 '
              DataFormat = 0xffffe001`cd7609b0
    signalProcessingMode = {4780004E-7133-41D8-8C74-660DADD2C0EE}
                ntStatus = 0n0
                  stream = 0x00000000`00000000
    

Раздел 9. Просмотр стеков вызовов

В разделе 9 вы увидите стеки вызовов для проверки кода вызывающего или вызывающего.

Стек вызовов — это цепочка вызовов функций, которые привели к текущему расположению счетчика программы. Верхняя функция в стеке вызовов — текущая функция, а следующая функция — это функция, которая называется текущей функцией и т. д.

Чтобы отобразить стек вызовов, используйте команды k*:

КБ

Отображает стек и первые три параметра.

Кп

Отображает стеки и полный список параметров.

kn

Позволяет увидеть стек с информацией кадра рядом с ним.

Если вы хотите сохранить стек вызовов, можно выбрать стек вызовов представления>, чтобы просмотреть его. Выберите столбцы в верхней части окна, чтобы переключить отображение дополнительных сведений.

Интерфейс WinDbg, отображающий окно стека вызовов.

В этом выходных данных показан стек вызовов при отладке примера кода адаптера в состоянии останова.

0: kd> kb
# RetAddr           : Args to Child                                                           : Call Site
00 fffff800`7a0fa607 : ffffe001`d1182000 ffffe001`d4776d20 ffffe001`d4776bc8 ffffe001`00000000 : tabletaudiosample!CMiniportWaveRT::NewStream+0x1dc [c:\data1\threshold\audio\endpointscommon\minwavert.cpp @ 597]
01 fffff800`7a0fb2c3 : 00000000`00000000 ffffe001`d122bb10 ffffe001`ceb81750 ffffe001`d173f058 : portcls!CPortPinWaveRT::Init+0x2e7
02 fffff800`7a0fc7f9 : ffffe001`d4776bc0 00000000`00000000 ffffe001`d10b8380 ffffe001`d122bb10 : portcls!CPortFilterWaveRT::NewIrpTarget+0x193
03 fffff800`7a180552 : 00000000`00000000 ffffe001`d10b8380 ffffe001`d122bb10 ffffe001`d4565600 : portcls!xDispatchCreate+0xd9
04 fffff800`7a109a9a : ffffe001`d10b84d0 ffffe001`d10b8380 00000000`00000000 ffffe001`00000000 : ks!KsDispatchIrp+0x272
05 fffff800`7bd314b1 : ffffe001`d122bb10 ffffd001`c3098590 ffffe001`d122bd90 ffffe001`ce80da70 : portcls!DispatchCreate+0x7a
06 fffff803`cda1bfa8 : 00000000`00000024 00000000`00000000 00000000`00000000 ffffe001`d122bb10 : ksthunk!CKernelFilterDevice::DispatchIrp+0xf9
07 fffff803`cda7b306 : 00000000`000001f0 ffffe001`d48ce690 ffffe001`d13d6400 ffffe001`d13d64c0 : nt!IopParseDevice+0x7c8
08 fffff803`cda12916 : 00000000`000001f0 ffffd001`c30988d0 ffffe001`d13d6490 fffff803`cda7b250 : nt!IopParseFile+0xb6
09 fffff803`cda1131c : ffffe001`d2ccb001 ffffd001`c30989e0 00ffffe0`00000040 ffffe001`cd127dc0 : nt!ObpLookupObjectName+0x776
0a fffff803`cd9fedb8 : ffffe001`00000001 ffffe001`d48ce690 00000000`00000000 00000000`00000000 : nt!ObOpenObjectByNameEx+0x1ec
0b fffff803`cd9fe919 : 000000ee`6d1fc8d8 000000ee`6d1fc788 000000ee`6d1fc7e0 000000ee`6d1fc7d0 : nt!IopCreateFile+0x3d8
0c fffff803`cd752fa3 : ffffc000`1f296870 fffff803`cd9d9fbd ffffd001`c3098be8 00000000`00000000 : nt!NtCreateFile+0x79
0d 00007fff`69805b74 : 00007fff`487484e6 0000029b`00000003 00000000`0000012e 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x13
0e 00007fff`487484e6 : 0000029b`00000003 00000000`0000012e 00000000`00000000 00000000`00000000 : 0x00007fff`69805b74
0f 0000029b`00000003 : 00000000`0000012e 00000000`00000000 00000000`00000000 00000000`00000000 : 0x00007fff`487484e6
10 00000000`0000012e : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000080 : 0x0000029b`00000003
11 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000080 00000000`00000000 : 0x12e

Для дальнейшего изучения кода можно использовать DML. При выборе первой записи 00 команда .frame (Set Local Context) используется для задания контекста, а затем команда dv (Display Local Variables) отображает локальные переменные.

0: kd> .frame 0n0;dv /t /v
00 ffffd001`c30981d0 fffff800`7a0fa607 tabletaudiosample!CMiniportWaveRT::NewStream+0x1dc [c:\data1\threshold\audio\endpointscommon\minwavert.cpp @ 597]
ffffd001`c30982b0 class CMiniportWaveRT * this = 0xffffe001`d1182000
ffffd001`c30982b8 struct IMiniportWaveRTStream ** OutStream = 0xffffe001`d4776d20
ffffd001`c30982c0 struct IPortWaveRTStream * OuterUnknown = 0xffffe001`d4776bc8
ffffd001`c30982c8 unsigned long Pin = 0
ffffd001`c30982d0 unsigned char Capture = 0x00 '
ffffd001`c30982d8 union KSDATAFORMAT * DataFormat = 0xffffe001`cd7609b0
ffffd001`c3098270 struct _GUID signalProcessingMode = {4780004E-7133-41D8-8C74-660DADD2C0EE}
ffffd001`c3098210 long ntStatus = 0n0
ffffd001`c3098218 class CMiniportWaveRTStream * stream = 0x00000000`00000000

Раздел 10. Отображение процессов и потоков

В разделе 10 вы будете использовать команды отладчика для отображения процессов и потоков.

Обработать

Чтобы изменить текущий контекст процесса, используйте команду процесса .process<>. В следующем примере показано, как определить процесс и переключить контекст на него.

  • !process Используйте команду, чтобы отобразить текущий процесс, участвующий в воспроизведении звука.

    Дополнительные сведения см. в разделе !process

Выходные данные показывают, что процесс связан с audiodg.exe. Если вы все еще находитесь в точке останова, описанной в предыдущем разделе этого раздела, текущий процесс должен быть связан с изображением audiodg.exe.

<— в хост-системе

0: kd> !process
PROCESS ffffe001d147c840
    SessionId: 0  Cid: 10f0    Peb: ee6cf8a000  ParentCid: 0434
    DirBase: d2122000  ObjectTable: ffffc0001f191ac0  HandleCount: <Data Not Accessible>
    Image: audiodg.exe
    VadRoot ffffe001d4222f70 Vads 70 Clone 0 Private 504. Modified 16. Locked 0.
    DeviceMap ffffc00019113080
    Token                             ffffc0001f1d4060
    ElapsedTime                       <Invalid>
    UserTime                          00:00:00.000
    KernelTime                        00:00:00.000
    QuotaPoolUsage[PagedPool]         81632
    QuotaPoolUsage[NonPagedPool]      9704
    Working Set Sizes (now,min,max)  (2154, 1814, 2109) (8616KB, 7256KB, 8436KB)
    PeakWorkingSetSize                2101
    VirtualSize                       2097192 Mb
    PeakVirtualSize                   2097192 Mb
    PageFaultCount                    2336
    MemoryPriority                    BACKGROUND
    BasePriority                      8
    CommitCharge                      1573

        THREAD ffffe001d173e840  Cid 10f0.1dac  Teb: 000000ee6cf8b000 Win32Thread: ffffe001d1118cf0 WAIT: (UserRequest) UserMode Non-Alertable
            ffffe001d16c4dd0  NotificationEvent
            ffffe001d08b0840  ProcessObject

        THREAD ffffe001ceb77080  Cid 10f0.16dc  Teb: 000000ee6cf8d000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
            ffffe001cf2d1840  QueueObject

        THREAD ffffe001d112c840  Cid 10f0.0a4c  Teb: 000000ee6cf8f000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
            ffffe001cf2d1840  QueueObject

        THREAD ffffe001d16c7840  Cid 10f0.13c4  Teb: 000000ee6cf91000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
            ffffe001cf2d1840  QueueObject

        THREAD ffffe001cec67840  Cid 10f0.0dbc  Teb: 000000ee6cf93000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
            ffffe001d173e5c0  QueueObject

        THREAD ffffe001d1117840  Cid 10f0.1d6c  Teb: 000000ee6cf95000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
            ffffe001d173e5c0  QueueObject

        THREAD ffffe001cdeae840  Cid 10f0.0298  Teb: 000000ee6cf97000 Win32Thread: 0000000000000000 RUNNING on processor 2

Обратите внимание, что один из потоков, связанных с этим процессом, находится в состоянии RUNNING. Этот поток поддерживал воспроизведение клипа мультимедиа при попадании точки останова.

Используйте команду !process 0 0, чтобы отобразить сводную информацию для всех процессов. В выходных данных команды используйте CTRL+F, чтобы найти идентификатор процесса для процесса, связанного с изображением audiodg.exe. В приведенном ниже примере идентификатор процесса — ffffe001d147c840.

Запишите идентификатор процесса, связанный с audiodg.exe на компьютере, чтобы использовать его позже в этой лаборатории. ________________________

...

PROCESS ffffe001d147c840
    SessionId: 0  Cid: 10f0    Peb: ee6cf8a000  ParentCid: 0434
    DirBase: d2122000  ObjectTable: ffffc0001f191ac0  HandleCount: <Data Not Accessible>
    Image: audiodg.exe
...

Введите g в отладчик, чтобы запустить код вперед, пока не будет выполнен воспроизведение клипа мультимедиа. Затем войдите в отладчик, нажав клавиши CTRL+ScrLk (CTRL+Break) Используйте команду !process, чтобы убедиться, что теперь выполняется другой процесс.

!process
PROCESS ffffe001cd0ad040
    SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 001aa000  ObjectTable: ffffc00017214000  HandleCount: <Data Not Accessible>
    Image: System
    VadRoot ffffe001d402b820 Vads 438 Clone 0 Private 13417. Modified 87866. Locked 64.
    DeviceMap ffffc0001721a070
    Token                             ffffc00017216a60
    ElapsedTime                       05:04:54.716
    UserTime                          00:00:00.000
    KernelTime                        00:00:20.531
    QuotaPoolUsage[PagedPool]         0
    QuotaPoolUsage[NonPagedPool]      0
    Working Set Sizes (now,min,max)  (1720, 50, 450) (6880KB, 200KB, 1800KB)
    PeakWorkingSetSize                15853
    VirtualSize                       58 Mb
    PeakVirtualSize                   74 Mb
    PageFaultCount                    46128
   MemoryPriority                    BACKGROUND
    BasePriority                      8
    CommitCharge                      66

        THREAD ffffe001cd0295c0  Cid 0004.000c  Teb: 0000000000000000 Win32Thread: 0000000000000000 WAIT: (Executive) KernelMode Non-Alertable
            fffff803cd8e0120  SynchronizationEvent

        THREAD ffffe001cd02a6c0  Cid 0004.0010  Teb: 0000000000000000 Win32Thread: 0000000000000000 WAIT: (Executive) KernelMode Non-Alertable
            fffff803cd8e0ba0  Semaphore Limit 0x7fffffff
...

В выходных данных выше показано, что выполняется другой системный процесс ffffe001cd0ad040 . Имя изображения отображает систему, а не audiodg.exe.

Теперь используйте команду !process для переключения на процесс, связанный с audiodg.exe. В примере идентификатор процесса — ffffe001d147c840. Замените идентификатор процесса в примере идентификатором процесса, записанным ранее.

0: kd> !process  ffffe001d147c840
PROCESS ffffe001d147c840
    SessionId: 0  Cid: 10f0    Peb: ee6cf8a000  ParentCid: 0434
    DirBase: d2122000  ObjectTable: ffffc0001f191ac0  HandleCount: <Data Not Accessible>
    Image: audiodg.exe
    VadRoot ffffe001d4222f70 Vads 60 Clone 0 Private 299. Modified 152. Locked 0.
    DeviceMap ffffc00019113080
    Token                             ffffc0001f1d4060
    ElapsedTime                       1 Day 01:53:14.490
    UserTime                          00:00:00.031
    KernelTime                        00:00:00.031
    QuotaPoolUsage[PagedPool]         81552
    QuotaPoolUsage[NonPagedPool]      8344
    Working Set Sizes (now,min,max)  (1915, 1814, 2109) (7660KB, 7256KB, 8436KB)
    PeakWorkingSetSize                2116
    VirtualSize                       2097189 Mb
    PeakVirtualSize                   2097192 Mb
    PageFaultCount                    2464
    MemoryPriority                    BACKGROUND
    BasePriority                      8
    CommitCharge                      1418

        THREAD ffffe001d173e840  Cid 10f0.1dac  Teb: 000000ee6cf8b000 Win32Thread: ffffe001d1118cf0 WAIT: (UserRequest) UserMode Non-Alertable
            ffffe001d16c4dd0  NotificationEvent
            ffffe001d08b0840  ProcessObject
        Not impersonating
        DeviceMap                 ffffc00019113080
        Owning Process            ffffe001d147c840       Image:         audiodg.exe
        Attached Process          N/A            Image:         N/A
        Wait Start TickCount      338852         Ticks: 197682 (0:00:51:28.781)
        Context Switch Count      36             IdealProcessor: 0             
        UserTime                  00:00:00.015
        KernelTime                00:00:00.000
        Win32 Start Address 0x00007ff7fb928de0
        Stack Init ffffd001c2ec6dd0 Current ffffd001c2ec60c0
        Base ffffd001c2ec7000 Limit ffffd001c2ec1000 Call 0
        Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
        Kernel stack not resident.

        THREAD ffffe001d115c080  Cid 10f0.15b4  Teb: 000000ee6cf9b000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
            ffffe001d0bf0640  QueueObject
        Not impersonating
        DeviceMap                 ffffc00019113080
        Owning Process            ffffe001d147c840       Image:         audiodg.exe
        Attached Process          N/A            Image:         N/A
        Wait Start TickCount      338852         Ticks: 197682 (0:00:51:28.781)
        Context Switch Count      1              IdealProcessor: 0             
        UserTime                  00:00:00.000
        KernelTime                00:00:00.000
        Win32 Start Address 0x00007fff6978b350
        Stack Init ffffd001c3143dd0 Current ffffd001c3143520
        Base ffffd001c3144000 Limit ffffd001c313e000 Call 0
        Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
        Kernel stack not resident.

        THREAD ffffe001d3a27040  Cid 10f0.17f4  Teb: 000000ee6cf9d000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
            ffffe001d173e5c0  QueueObject
        Not impersonating
        DeviceMap                 ffffc00019113080
        Owning Process            ffffe001d147c840       Image:         audiodg.exe
        Attached Process          N/A            Image:         N/A
        Wait Start TickCount      518918         Ticks: 17616 (0:00:04:35.250)
        Context Switch Count      9              IdealProcessor: 1             
        UserTime                  00:00:00.000
        KernelTime                00:00:00.000
        Win32 Start Address 0x00007fff6978b350
        Stack Init ffffd001c70c6dd0 Current ffffd001c70c6520
        Base ffffd001c70c7000 Limit ffffd001c70c1000 Call 0
        Priority 9 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
        Kernel stack not resident.

Так как этот код не активен, все потоки находятся в состоянии WAIT, как ожидалось.

Потоки

Команды для просмотра и задания потоков очень похожи на те процессы. Используйте команду !thread для просмотра потоков. Используйте поток .thread для задания текущих потоков.

Чтобы изучить потоки, связанные с проигрывателем мультимедиа, снова воспроизвести клип мультимедиа. Если точка останова, описанная в предыдущем разделе, по-прежнему находится на месте, вы остановитесь в контексте audiodg.exe.

Используйте поток !thread -1 0, чтобы отобразить краткие сведения для текущего потока. Здесь показаны адрес потока, идентификаторы потоков и процессов, адрес блока среды потока (TEB), адрес функции Win32 (если таковой) создан для выполнения, а также состояние планирования потока.

0: kd> !thread -1 0
THREAD ffffe001d3a27040  Cid 10f0.17f4  Teb: 000000ee6cf9d000 Win32Thread: 0000000000000000 RUNNING on processor 0

Чтобы просмотреть дополнительные сведения о выполняемом потоке, введите !thread. Должны отображаться сведения, аналогичные приведенным ниже.

0: kd> !thread
THREAD ffffe001d3a27040  Cid 10f0.17f4  Teb: 000000ee6cf9d000 Win32Thread: 0000000000000000 RUNNING on processor 0
IRP List:
    ffffe001d429e580: (0006,02c8) Flags: 000008b4  Mdl: 00000000
Not impersonating
DeviceMap                 ffffc00019113080
Owning Process            ffffe001d147c840       Image:         audiodg.exe
Attached Process          N/A            Image:         N/A
Wait Start TickCount      537630         Ticks: 0
Context Switch Count      63             IdealProcessor: 1             
UserTime                  00:00:00.000
KernelTime                00:00:00.015
Win32 Start Address 0x00007fff6978b350
Stack Init ffffd001c70c6dd0 Current ffffd001c70c6520
Base ffffd001c70c7000 Limit ffffd001c70c1000 Call 0
Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
Child-SP          RetAddr           : Args to Child                                                           : Call Site
ffffd001`c70c62a8 fffff800`7a0fa607 : ffffe001`d4aec5c0 ffffe001`cdefd3d8 ffffe001`d4aec5c0 ffffe001`cdefd390 : tabletaudiosample!CMiniportWaveRT::NewStream [c:\data1\threshold\audio\endpointscommon\minwavert.cpp @ 562]
ffffd001`c70c62b0 fffff800`7a0fb2c3 : 00000000`00000000 ffffe001`d429e580 ffffe001`d4ea47b0 ffffe001`cdefd3d8 : portcls!CPortPinWaveRT::Init+0x2e7
ffffd001`c70c6340 fffff800`7a0fc7f9 : ffffe001`d4aec430 00000000`00000000 ffffe001`d10b8380 ffffe001`d429e580 : portcls!CPortFilterWaveRT::NewIrpTarget+0x193
ffffd001`c70c63c0 fffff800`7a180552 : 00000000`00000000 ffffe001`d10b8380 ffffe001`d429e580 ffffe001`d4565600 : portcls!xDispatchCreate+0xd9
ffffd001`c70c6450 fffff800`7a109a9a : ffffe001`d10b84d0 ffffe001`d10b8380 00000000`00000000 ffffe001`00000000 : ks!KsDispatchIrp+0x272
ffffd001`c70c6510 fffff800`7bd314b1 : ffffe001`d429e580 ffffd001`c70c6590 ffffe001`d429e800 ffffe001`ce80da70 : portcls!DispatchCreate+0x7a
ffffd001`c70c6540 fffff803`cda1bfa8 : 00000000`00000025 00000000`00000000 00000000`00000000 ffffe001`d429e580 : ksthunk!CKernelFilterDevice::DispatchIrp+0xf9
ffffd001`c70c65a0 fffff803`cda7b306 : 00000000`000002fc ffffe001`d5e0d510 00000000`00000000 ffffe001`d3341bd0 : nt!IopParseDevice+0x7c8
ffffd001`c70c6770 fffff803`cda12916 : 00000000`000002fc ffffd001`c70c68d0 ffffe001`d3341ba0 fffff803`cda7b250 : nt!IopParseFile+0xb6
ffffd001`c70c67d0 fffff803`cda1131c : ffffe001`ceb6c601 ffffd001`c70c69e0 00000000`00000040 ffffe001`cd127dc0 : nt!ObpLookupObjectName+0x776
ffffd001`c70c6970 fffff803`cd9fedb8 : ffff8ab8`00000001 ffffe001`d5e0d510 00000000`00000000 00000000`00000000 : nt!ObOpenObjectByNameEx+0x1ec
ffffd001`c70c6a90 fffff803`cd9fe919 : 000000ee`6d37c6e8 00000004`6d37c500 000000ee`6d37c5f0 000000ee`6d37c5e0 : nt!IopCreateFile+0x3d8
ffffd001`c70c6b40 fffff803`cd752fa3 : fffff6fb`7da05360 fffff6fb`40a6c0a8 fffff681`4d815760 ffff8ab8`92895e23 : nt!NtCreateFile+0x79
ffffd001`c70c6bd0 00007fff`69805b74 : 00007fff`487484e6 0000029b`00000003 00000000`0000012e 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ ffffd001`c70c6c40)
000000ee`6d37c568 00007fff`487484e6 : 0000029b`00000003 00000000`0000012e 00000000`00000000 00000000`00000000 : 0x00007fff`69805b74
000000ee`6d37c570 0000029b`00000003 : 00000000`0000012e 00000000`00000000 00000000`00000000 00000000`00000000 : 0x00007fff`487484e6
000000ee`6d37c578 00000000`0000012e : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000080 : 0x0000029b`00000003
000000ee`6d37c580 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000080 00000000`00000000 : 0x12e

Используйте команду k для просмотра стека вызовов, связанного с потоком.

0: kd> k
# Child-SP          RetAddr           Call Site
00 ffffd001`c70c62a8 fffff800`7a0fa607 tabletaudiosample!CMiniportWaveRT::NewStream [c:\data1\threshold\audio\endpointscommon\minwavert.cpp @ 562]
01 ffffd001`c70c62b0 fffff800`7a0fb2c3 portcls!CPortPinWaveRT::Init+0x2e7
02 ffffd001`c70c6340 fffff800`7a0fc7f9 portcls!CPortFilterWaveRT::NewIrpTarget+0x193
03 ffffd001`c70c63c0 fffff800`7a180552 portcls!xDispatchCreate+0xd9
04 ffffd001`c70c6450 fffff800`7a109a9a ks!KsDispatchIrp+0x272
05 ffffd001`c70c6510 fffff800`7bd314b1 portcls!DispatchCreate+0x7a
06 ffffd001`c70c6540 fffff803`cda1bfa8 ksthunk!CKernelFilterDevice::DispatchIrp+0xf9
07 ffffd001`c70c65a0 fffff803`cda7b306 nt!IopParseDevice+0x7c8
08 ffffd001`c70c6770 fffff803`cda12916 nt!IopParseFile+0xb6
09 ffffd001`c70c67d0 fffff803`cda1131c nt!ObpLookupObjectName+0x776
0a ffffd001`c70c6970 fffff803`cd9fedb8 nt!ObOpenObjectByNameEx+0x1ec
0b ffffd001`c70c6a90 fffff803`cd9fe919 nt!IopCreateFile+0x3d8
0c ffffd001`c70c6b40 fffff803`cd752fa3 nt!NtCreateFile+0x79
0d ffffd001`c70c6bd0 00007fff`69805b74 nt!KiSystemServiceCopyEnd+0x13
0e 000000ee`6d37c568 00007fff`487484e6 0x00007fff`69805b74
0f 000000ee`6d37c570 0000029b`00000003 0x00007fff`487484e6
10 000000ee`6d37c578 00000000`0000012e 0x0000029b`00000003
11 000000ee`6d37c580 00000000`00000000 0x12e

Введите g в отладчик, чтобы запустить код вперед, пока не будет выполнен воспроизведение клипа мультимедиа. Затем войдите в отладчик, нажав клавиши CTRL - ScrLk (CTRL-Break) используйте команду !thread, чтобы убедиться, что теперь выполняется другой поток.

0: kd> !thread
THREAD ffffe001ce80b840  Cid 17e4.01ec  Teb: 00000071fa9b9000 Win32Thread: ffffe001d41690d0 RUNNING on processor 0
Not impersonating
DeviceMap                 ffffc0001974e2c0
Owning Process            ffffe001d1760840       Image:         rundll32.exe
Attached Process          N/A            Image:         N/A
Wait Start TickCount      538040         Ticks: 0
Context Switch Count      3181840        IdealProcessor: 0             
UserTime                  00:00:08.250
KernelTime                00:00:10.796
Win32 Start Address 0x00007ff6d2f24270
Stack Init ffffd001cd16afd0 Current ffffd001cd16a730
Base ffffd001cd16b000 Limit ffffd001cd165000 Call 0
Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5

Child-SP          RetAddr           : Args to Child                                                           : Call Site
fffff803`cf373d18 fffff800`7a202852 : fffff803`cf373e60 00000000`00000001 ffffe001`cf4ed330 00000000`0000ffff : nt!DbgBreakPointWithStatus
fffff803`cf373d20 fffff803`cd6742c6 : ffffe001`cf4ed2f0 fffff803`cf373e60 00000000`00000001 00000000`0004e4b8 : kdnic!TXSendCompleteDpc+0x142
fffff803`cf373d60 fffff803`cd74d495 : 00000000`00000000 fffff803`cd923180 fffff803`cde1f4b0 fffff901`40669010 : nt!KiRetireDpcList+0x5f6
fffff803`cf373fb0 fffff803`cd74d2a0 : 00000000`00000090 0000000e`0000006a 00000000`00000092 00000000`00000000 : nt!KxRetireDpcList+0x5 (TrapFrame @ fffff803`cf373e70)
ffffd001`cd16a6c0 fffff803`cd74bd75 : 00000000`00000000 fffff803`cd74a031 00000000`00000000 00000000`00000000 : nt!KiDispatchInterruptContinue
ffffd001`cd16a6f0 fffff803`cd74a031 : 00000000`00000000 00000000`00000000 ffffe001`cff4d2a0 fffff803`cd67738e : nt!KiDpcInterruptBypass+0x25
ffffd001`cd16a700 fffff960`50cdb5a4 : fffff901`400006d0 00000000`00000001 fffff901`40000d60 ffffd001`cd16a9f0 : nt!KiInterruptDispatchNoLockNoEtw+0xb1 (TrapFrame @ ffffd001`cd16a700)
ffffd001`cd16a890 fffff960`50c66b2f : 00000000`00000000 fffff901`40669010 fffff901`42358580 fffff901`40000d60 : win32kfull!Win32FreePoolImpl+0x34
ffffd001`cd16a8c0 fffff960`50c68cd6 : 00000000`00000000 ffffd001`cd16a9f0 fffff901`400006d0 fffff901`400c0460 : win32kfull!EXLATEOBJ::vAltUnlock+0x1f
ffffd001`cd16a8f0 fffff803`cd752fa3 : 00000000`00000000 00000000`00000000 ffffe001`ce80b840 00000000`00000000 : win32kfull!NtGdiAlphaBlend+0x1d16
ffffd001`cd16add0 00007fff`674c1494 : 00007fff`674b1e97 0000a7c6`daee0559 00000000`00000001 0000020b`741f3c50 : nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ ffffd001`cd16ae40)
00000071`fa74c9a8 00007fff`674b1e97 : 0000a7c6`daee0559 00000000`00000001 0000020b`741f3c50 00000000`00ffffff : 0x00007fff`674c1494
00000071`fa74c9b0 0000a7c6`daee0559 : 00000000`00000001 0000020b`741f3c50 00000000`00ffffff 00000000`00000030 : 0x00007fff`674b1e97
00000071`fa74c9b8 00000000`00000001 : 0000020b`741f3c50 00000000`00ffffff 00000000`00000030 00000000`01010bff : 0x0000a7c6`daee0559
00000071`fa74c9c0 0000020b`741f3c50 : 00000000`00ffffff 00000000`00000030 00000000`01010bff 00000000`00000000 : 0x1
00000071`fa74c9c8 00000000`00ffffff : 00000000`00000030 00000000`01010bff 00000000`00000000 00000000`000000c0 : 0x0000020b`741f3c50
00000071`fa74c9d0 00000000`00000030 : 00000000`01010bff 00000000`00000000 00000000`000000c0 00000000`00000030 : 0xffffff
00000071`fa74c9d8 00000000`01010bff : 00000000`00000000 00000000`000000c0 00000000`00000030 00000071`00000030 : 0x30
00000071`fa74c9e0 00000000`00000000 : 00000000`000000c0 00000000`00000030 00000071`00000030 00000071`01ff8000 : 0x1010bff

Имя изображения — это rundll32.exe, что действительно не имя изображения, связанное с воспроизведением клипа мультимедиа.

Примечание. Чтобы задать текущий поток, введите номер> потока .thread<.

Дополнительные сведения о потоках и процессах см. в следующих ссылках:

Потоки и процессы

Изменение контекстов

Раздел 11. IRQL, регистры и дизассембли

Просмотр сохраненного IRQL

В разделе 11 вы увидите IRQL и содержимое regsisters.

<— в хост-системе

Уровень запроса прерывания (IRQL) используется для управления приоритетом обслуживания прерываний. Каждый процессор имеет параметр IRQL, который потоки могут вызывать или уменьшать. Прерывания, которые происходят под параметром IRQL процессора, маскируются и не будут вмешиваться в текущую операцию. Прерывания, возникающие над параметром IRQL процессора, имеют приоритет над текущей операцией. Расширение !irql отображает уровень запроса прерывания (IRQL ) на текущем процессоре целевого компьютера до сбоя отладчика. Когда целевой компьютер прерывается в отладчик, IRQL изменяется, но IRQL, действующий непосредственно перед сохранением отладчика и отображается с помощью !irql.

0: kd> !irql
Debugger saved IRQL for processor 0x0 -- 2 (DISPATCH_LEVEL)

<Просмотр регистров и дизассембли

Просмотр регистров

Отображение содержимого регистров для текущего потока в текущем процессоре с помощью команды r (Registers).

0: kd> r
rax=000000000000c301 rbx=ffffe00173eed880 rcx=0000000000000001
rdx=000000d800000000 rsi=ffffe00173eed8e0 rdi=ffffe00173eed8f0
rip=fffff803bb757020 rsp=ffffd001f01f8988 rbp=ffffe00173f0b620
 r8=000000000000003e  r9=ffffe00167a4a000 r10=000000000000001e
r11=ffffd001f01f88f8 r12=0000000000000000 r13=ffffd001f01efdc0
r14=0000000000000001 r15=0000000000000000
iopl=0         nv up ei pl nz na pe nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
nt!DbgBreakPointWithStatus:
fffff803`bb757020 cc              int     3

Кроме того, можно отобразить содержимое регистров, выбрав пункт "Просмотр>регистров".

Снимок экрана: окно регистрации WinDbg, отображающее примерно 12 регистров.

Просмотр содержимого регистров может оказаться полезным при пошаговом выполнении кода языка сборки и в других сценариях. Дополнительные сведения см. в разделе r (Registers).

Сведения о содержимом регистра см. в разделе архитектуры x86 и архитектуры x64.

Разборка

Вы можете разобрать код, который находится под выполнением, чтобы просмотреть код языка сборки, который выполняется, выбрав "Просмотреть>дизассембли".

Снимок экрана: окно дизассемблирования WinDbg с кодом языка сборки.

Дополнительные сведения об дизассембли языка сборки см. в разделе Annotated x86 Disassembly и Annotated x64 Disassembly.

Раздел 12. Работа с памятью

В разделе 12 вы будете использовать команды отладчика для отображения содержимого памяти.

Просмотр памяти

Может потребоваться проверить память, чтобы определить проблему или проверить переменные, указатели и т. д. Вы можете отобразить память, введя одну из следующих команд адресов> d*<.

db

Отображает данные в значениях байтов и символах ASCII.

dd

Отображает данные как двойные широкие слова (4 байта).

du

Отображает данные в виде символов Юникода.

dw

Отображает данные в виде слов (2 байта) и символов ASCII.

Примечание. Если вы пытаетесь отобразить недопустимый адрес, его содержимое отображается как вопросительные знаки (?).

Кроме того, можно просмотреть память, выбрав пункт "Просмотреть>память". Используйте вытягивание формата отображения, чтобы изменить способ отображения памяти.

Снимок экрана: окно памяти WinDbg с различными параметрами формата отображения.

  1. Чтобы просмотреть данные, связанные с элементом управления томом, задайте точку останова для запуска подпрограммы PropertyHandlerAudioEngineVolumeLevel с помощью команды bm. Прежде чем задать новую точку останова, мы очистим все предыдущие точки останова с помощью bc *.

    kd> bc *
    
  2. Задайте точку останова для запуска подпрограммы PropertyHandlerAudioEngineVolumeLevel с помощью команды bm.

    kd> bm tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume
      1: fffff80f`02c3a4b0 @!"tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume"
    
  3. Выведите список точек останова, чтобы убедиться, что точка останова задана правильно.

    kd> bl
      1: fffff80f`02c3a4b0 @!"tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume"
    
  4. Используйте команду g для перезапуска выполнения кода.

    В целевой системе настройте том в области системы. Это приведет к возникновению точки останова.

    Breakpoint 1 hit
    tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume:
    fffff80f`02c3a4b0 44894c2420      mov     dword ptr [rsp+20h],r9d
    
  5. Чтобы отобразить локальные переменные, используйте элемент меню представления>"Локальный". Обратите внимание на текущее значение переменной IVolume.

  6. Тип данных и текущее значение переменной IVolume можно отобразить в примере кода, введя команду dt и имя переменной.

    kd> dt lVolume
    Local var @ 0xa011ea50 Type long
    0n-6291456
    
  7. Точка останова достигается при вводе SetDeviceChannelVolume.

    STDMETHODIMP_(NTSTATUS) CMiniportWaveRT::SetDeviceChannelVolume(_In_  ULONG _ulNodeId, _In_ UINT32 _uiChannel, _In_  LONG  _Volume)
    {
        NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
    
        PAGED_CODE ();
    
        DPF_ENTER(("[CMiniportWaveRT::SetEndpointChannelVolume]"));
        IF_TRUE_ACTION_JUMP(_ulNodeId != KSNODE_WAVE_AUDIO_ENGINE, ntStatus = STATUS_INVALID_DEVICE_REQUEST, Exit);
    
        // Snap the volume level to our range of steppings.
        LONG lVolume = VOLUME_NORMALIZE_IN_RANGE(_Volume); 
    
        ntStatus = SetChannelVolume(_uiChannel, lVolume);
    Exit:
        return ntStatus;
    }
    
  8. Попытайтесь отобразить значение в расположении памяти IVolume с помощью команды dt (тип отображения).

    kd> dt dt lVolume
    Local var @ 0xffffb780b7eee664 Type long
    0n0
    

    Так как переменная еще не определена, она не содержит сведений.

  9. Нажмите клавишу F10, чтобы выполнить переадресацию к последней строке кода в SetDeviceChannelVolume.

        return ntStatus;
    
  10. Отображение значения в расположении памяти IVolume с помощью команды dt (тип отображения).

    kd> dt lVolume
    Local var @ 0xffffb780b7eee664 Type long
    0n-6291456
    

    Теперь, когда переменная активна, в этом примере отображается значение 6291456.

  11. Вы также можете отобразить расположение памяти IVolume с помощью функции ? (Вычислять выражение) Команды.

    kd> ? lVolume
    Evaluate expression: -79711507126684 = ffffb780`b7eee664
    
  12. Показанный адрес ffffb780'b7eee664 — это адрес переменной lVolume. Используйте команду dd, чтобы отобразить содержимое памяти в этом расположении.

    kd>  dd ffffb780`b7eee664
    ffffb780`b7eee664  ffa00000 00000018 00000000 c52d7008
    ffffb780`b7eee674  ffffc98e e0495756 fffff80e c52d7008
    ffffb780`b7eee684  ffffc98e 00000000 fffff80e 00000000
    ffffb780`b7eee694  ffffc98e ffa00000 ffffb780 b7eee710
    ffffb780`b7eee6a4  ffffb780 00000000 00000000 c7477260
    ffffb780`b7eee6b4  ffffc98e b7eee7a0 ffffb780 b7eee6f0
    ffffb780`b7eee6c4  ffffb780 e04959ca fffff80e 00000000
    ffffb780`b7eee6d4  00000000 00000028 00000000 00000002
    
  13. Вы можете отобразить первые четыре байта адреса, указав параметр диапазона L4.

    kd> dd ffffb780`b7eee664 l4
    ffffb780`b7eee664  ffa00000 00000018 00000000 c52d7008
    
  14. Чтобы просмотреть отображаемые выходные данные памяти различных типов, введите команды du, da и db .

    kd> du ffffb780`b7eee664 
    ffffb780`b7eee664  ""
    
    kd> a ffffb780`b7eee664 
    ffffb780`b7eee664  ""
    
    kd> db 0xffffae015ff97664 
    ffffae01`5ff97664  00 80 bc ff 18 00 00 00-00 00 00 00 08 50 e0 51  .............P.Q
    ffffae01`5ff97674  00 c0 ff ff 56 57 da 56-0e f8 ff ff 08 50 e0 51  ....VW.V.....P.Q
    ffffae01`5ff97684  00 c0 ff ff 00 00 00 00-0e f8 ff ff 00 00 00 00  ................
    ffffae01`5ff97694  00 c0 ff ff aa 80 bc ff-01 ae ff ff 10 77 f9 5f  .............w._
    ffffae01`5ff976a4  01 ae ff ff 40 00 00 00-00 e6 ff ff 10 dc 30 55  ....@.........0U
    ffffae01`5ff976b4  00 c0 ff ff a0 77 f9 5f-01 ae ff ff f0 76 f9 5f  .....w._.....v._
    ffffae01`5ff976c4  01 ae ff ff ca 59 da 56-0e f8 ff ff 00 00 00 00  .....Y.V........
    ffffae01`5ff976d4  00 00 00 00 28 00 00 00-00 00 00 00 02 00 00 00  ....(...........
    

    Используйте параметр с плавающей запятой df для отображения данных в виде чисел с плавающей запятой с одной точностью (4 байта).

    df ffffb780`b7eee664 
    ffffb780`b7eee664          -1.#QNAN   3.3631163e-044                0        -2775.002
    ffffb780`b7eee674          -1.#QNAN  -5.8032637e+019         -1.#QNAN        -2775.002
    ffffb780`b7eee684          -1.#QNAN                0         -1.#QNAN                0
    ffffb780`b7eee694          -1.#QNAN         -1.#QNAN         -1.#QNAN  -2.8479408e-005
    

Запись в память

Как и команды, используемые для чтения памяти, можно использовать команды e* для изменения содержимого памяти.

Команда Description

шт.

Строка ASCII (не с завершением NULL)

eu

Строка Юникода (не завершающаяся null)

д

Значения Word (2 байта)

Eza

Строка ASCII с завершением NULL

ezu

Строка Юникода с завершением NULL

Eb

Значения байтов

ed

Значения двойного слова (4 байта)

В следующем примере показано, как перезаписать память.

  1. Сначала найдите адрес lVolume, используемый в примере кода.

    kd> ? lVolume
    Evaluate expression: -79711507126684 = ffffb780`b7eee664
    
  2. Перезапись адреса памяти новыми символами с помощью команды EB .

    kd> eb 0xffffb780`b7eee664 11 11 11 11 11
    
  3. Отображение расположения памяти, чтобы убедиться, что символы были перезаписаны, введя команду db .

    kd> db 0xffffb780`b7eee664
    ffffb780`b7eee664  11 11 11 11 11 00 00 00-00 00 00 00 08 70 2d c5  .............p-.
    ffffb780`b7eee674  8e c9 ff ff 56 57 49 e0-0e f8 ff ff 08 70 2d c5  ....VWI......p-.
    ffffb780`b7eee684  8e c9 ff ff 00 00 00 00-0e f8 ff ff 00 00 00 00  ................
    ffffb780`b7eee694  8e c9 ff ff 00 00 a0 ff-80 b7 ff ff 10 e7 ee b7  ................
    ffffb780`b7eee6a4  80 b7 ff ff 00 00 00 00-00 00 00 00 60 72 47 c7  ............`rG.
    ffffb780`b7eee6b4  8e c9 ff ff a0 e7 ee b7-80 b7 ff ff f0 e6 ee b7  ................
    ffffb780`b7eee6c4  80 b7 ff ff ca 59 49 e0-0e f8 ff ff 00 00 00 00  .....YI.........
    ffffb780`b7eee6d4  00 00 00 00 28 00 00 00-00 00 00 00 02 00 00 00  ....(...........
    

Кроме того, можно изменить содержимое памяти в окне часов или локальных параметров. В окне просмотра могут отображаться переменные, не имеющие контекста текущего кадра. Изменение их не имеет значения, если они не находятся в контексте.

Раздел 13. Завершение сеанса WinDbg

<-В системе узла

Если вы хотите оставить отладчик подключенным, но хотите работать с целевым объектом, снимите все точки bc *останова, чтобы целевой компьютер не попытается подключиться к отладчику хост-компьютера. Затем используйте g команду, чтобы позволить целевому компьютеру снова запуститься.

Чтобы завершить сеанс отладки, в системе узла войдете в отладчик и введите qd команду (Выход и отсоединение) или нажмите кнопку "Остановить отладку " в меню.

0: kd> qd

Дополнительные сведения см. в статье "Завершение сеанса отладки" в WinDbg (классическая версия) в справочной документации по отладке.

Раздел 14. Ресурсы отладки Windows

Дополнительные сведения доступны в отладке Windows. Обратите внимание, что некоторые из этих книг будут использовать более старые версии Windows, такие как Windows Vista в своих примерах, но описанные понятия применимы к большинству версий Windows.

Книги

  • Расширенная отладка Windows Марио Hewardt и Даниэль Прават

  • В отладке Windows: практическое руководство по отладке и трассировке стратегий в Windows® от Tarik Soulami

  • Windows Internals Павел Yosifovich, Алекс Ионеску, Марк Руссинович и Дэвид Соломон

Видео

Средства defrag показывают WinDbg Эпизоды 13-29: </show/defrag-tools/>

Поставщики обучения:

OSR- https://www.osr.com/

См. также

Начало работы с отладкой Windows