Отладка драйверов Windows пошаговые лаборатории (режим эхо-ядра)
В этой лаборатории представлен отладчик ядра WinDbg. Для отладки кода драйвера в режиме эхо-ядра используется WinDbg.
Цели лаборатории
В этой лаборатории содержатся упражнения, которые представляют средства отладки, обучают распространенные команды отладки, иллюстрируют использование точек останова и показывают, как использовать расширения отладки.
В этой лаборатории вы используете динамическое подключение отладки ядра для изучения следующих действий:
- Использование команд отладчика Windows
- Используйте стандартные команды (стеки вызовов, переменные, потоки, IRQL)
- Использование команд отладки расширенного драйвера (!commands)
- Использование символов
- Настройка точек останова в динамической отладке
- Просмотр стеков вызовов
- Отображение дерева устройств самонастраивающийся
- Работа с контекстом потока и процесса
Отладка режима пользователя и ядра
При работе с отладчиком Windows можно выполнить два типа отладки:
Режим пользователя — приложения и подсистемы выполняются на компьютере в пользовательском режиме. Процессы, выполняемые в пользовательском режиме, делают это в пределах собственных виртуальных адресных пространств. Они ограничены от прямого доступа ко многим частям системы, включая системное оборудование, память, которая не выделяется для их использования, и другие части системы, которые могут компрометировать целостность системы. Поскольку процессы, выполняемые в пользовательском режиме, эффективно изолированы от системных и других процессов пользовательского режима, они не могут влиять на эти ресурсы.
Режим ядра — операционная система и привилегированные программы выполняются в режиме ядра. Код в режиме ядра имеет разрешение на доступ к любой части системы. Он не ограничен, как код пользовательского режима. Он может получить доступ к любой части любого другого процесса, выполняемого в пользовательском режиме или в режиме ядра. Большая часть основных функций ОС и многие драйверы аппаратных устройств выполняются в режиме ядра.
В этом упражнении рассматриваются команды отладки, которые часто используются как в пользовательском режиме, так и в режиме ядра отладки. Упражнение также охватывает расширения отладки, иногда называемые "bang" !commands, которые используются для отладки в режиме ядра.
Организация занятия
Для выполнения лаборатории потребуется следующее оборудование:
- Ноутбук или настольный компьютер под управлением Windows 10
- Второй ноутбук или настольный компьютер под управлением Windows 10
- Сетевой концентратор или маршрутизатор и сетевые кабели для подключения двух компьютеров
- Доступ к Интернету для скачивания файлов символов
Для выполнения лаборатории потребуется следующее программное обеспечение:
- Visual Studio
- Пакет средств разработки программного обеспечения Windows (SDK) для Windows 10
- Комплект драйверов Windows (WDK) для Windows 10
- Пример драйвера эхо для Windows 10
В лаборатории приведены следующие разделы:
- Подключение к сеансу WinDbg в режиме ядра
- Команды и методы отладки в режиме ядра
- Скачивание и сборка драйвера эхо KMDF
- Установка примера эхо-драйвера в целевой системе
- Использование WinDbg для отображения сведений о драйвере
- Отображение сведений о дереве устройств самонастраивающийся
- Работа с точками останова и исходным кодом
- Просмотр переменных и стеков вызовов
- Отображение процессов и потоков
- IRQL, регистрация и завершение сеанса WinDbg
- Ресурсы отладки Windows
Подключение к сеансу WinDbg в режиме ядра
В этом разделе описана настройка отладки сети на узле и целевой системе.
Компьютеры в этой лаборатории должны быть настроены для использования сетевого подключения Ethernet для отладки ядра.
В этой лаборатории используются два компьютера. Отладчик Windows выполняется в системе узла и драйвере эхо-драйвера режима ядра (KMDF) выполняется в целевой системе.
Используйте сетевой концентратор или маршрутизатор и сетевые кабели для подключения двух компьютеров.
Чтобы работать с приложениями в режиме ядра и использовать WinDbg, рекомендуется использовать KDNET через транспорт Ethernet. Сведения об использовании транспортного протокола Ethernet см. в статье "Начало работы с WinDbg" (режим ядра). Дополнительные сведения о настройке целевого компьютера см. в статье "Подготовка компьютера для автоматического развертывания драйвера вручную" и настройка отладки сетевого ядра KDNET.
Настройка отладки в режиме ядра с помощью Ethernet
Чтобы включить отладку в режиме ядра в целевой системе, выполните следующие действия.
В системе узла откройте окно командной строки и введите ipconfig , чтобы определить его IPv4-адрес.
Windows IP Configuration Ethernet adapter Ethernet: Connection-specific DNS Suffix . : Link-local IPv6 Address . . . . . : fe80::c8b6:db13:d1e8:b13b%3 Autoconfiguration IPv4 Address. . : 169.182.1.1 Subnet Mask . . . . . . . . . . . : 255.255.0.0 Default Gateway . . . . . . . . . :
Запишите IP-адрес хост-системы: ______________________________________
В целевой системе откройте окно командной строки и используйте
ping
команду для подтверждения сетевого подключения между двумя системами.ping 169.182.1.1
Используйте фактический IP-адрес хост-системы, записанной вместо 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
Включите отладку в режиме ядра в целевой системе, выполнив следующие действия.
Внимание
Прежде чем использовать BCDEdit для изменения сведений о загрузке, может потребоваться временно приостановить функции безопасности Windows, такие как BitLocker и безопасная загрузка на тестовом компьютере. Повторно включите эти функции безопасности при завершении тестирования. При отключении функций безопасности необходимо управлять тестируемым компьютером. Безопасная загрузка обычно отключена в UEFI. Чтобы получить доступ к параметру UEFI, воспользуйтесь системой, восстановлением, расширенным запуском. При перезапуске выберите "Устранение неполадок", "Дополнительные параметры" и "Встроенное ПО UEFI". Используйте осторожность, так как неправильно задать параметры UEFI или отключить BitLocker, может сделать систему неработоспособной.
На целевом компьютере откройте окно командной строки от имени администратора. Введите следующую команду, чтобы включить отладку:
bcdedit /set {default} DEBUG YES
Введите следующую команду, чтобы включить подписывание тестов:
bcdedit /set TESTSIGNING ON
Введите эту команду, чтобы задать IP-адрес хост-системы. Используйте IP-адрес хост-системы, записанной ранее, а не отображаемую.
bcdedit /dbgsettings net hostip:192.168.1.1 port:50000 key:2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Предупреждение
Чтобы повысить безопасность подключения и уменьшить риск запросов на подключение отладчика клиента, используйте автоматически созданный случайный ключ. Дополнительные сведения см. в разделе "Настройка автоматической отладки сетевого ядра KDNET".
Введите следующую команду, чтобы убедиться, что значения для
dbgsettings
них заданы правильно:bcdedit /dbgsettings
key 2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p debugtype NET hostip 169.168.1.1 port 50000 dhcp Yes The operation completed successfully.
Примечание.
Если вы получаете сообщение из брандмауэра и хотите использовать отладчик, выберите все три поля.
На хост-компьютере откройте окно командной строки от имени администратора. В этой лаборатории используется версия x64 WinDbg.exe из комплекта драйверов Windows (WDK), которая была установлена в процессе установки пакета Windows. Перейдите к каталогу WinDbg по умолчанию, расположение по умолчанию показано ниже.
cd C:\Program Files(x86)\Windows Kits\10\Debuggers\x64
В этой лаборатории предполагается, что оба компьютера выполняют 64-разрядную версию Windows как на целевом, так и на узле. Если это не так, лучший подход заключается в том, чтобы запустить ту же битность инструментов на узле, что и целевой объект. Например, если целевой объект запускает 32-разрядную версию Windows, запустите 32-разрядную версию отладчика на узле. Дополнительные сведения см. в разделе "Выбор средств отладки с 32-разрядной или 64-разрядной версией".
Откройте WinDbg с отладкой удаленного пользователя с помощью следующей команды. Значения ключа и порта соответствуют значениям, заданным ранее с помощью BCDEdit на целевом компьютере.
WinDbg –k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Перезапустите целевую систему.
В минуту или два выходные данные отладки должны отображаться в хост-системе.
Microsoft (R) Windows Debugger Version 10.0.17074.1002 AMD64 Copyright (c) Microsoft Corporation. All rights reserved. Using NET for debugging Opened WinSock 2.0 Waiting to reconnect... Connected to target 169.182.1.1 on port 50005 on local IP 169.182.1.2 You can get the target MAC address by running .kdtargetmac command. Connected to Windows 10 16299 x64 target at (Wed Feb 28 17:16:23.051 2018 (UTC - 8:00)), ptr64 TRUE Kernel Debugger connection established. (Initial Breakpoint requested) Symbol search path is: srv* Executable search path is: Windows 10 Kernel Version 16299 MP (4 procs) Free x64 Product: WinNt, suite: TerminalServer SingleUserTS Built by: 16299.15.amd64fre.rs3_release.170928-1534 Machine Name: Kernel base = 0xfffff800`9540d000 PsLoadedModuleList = 0xfffff800`95774110 Debug session time: Wed Feb 28 17:16:23.816 2018 (UTC - 8:00) System Uptime: 0 days 0:00:20.534
Командное окно отладчика — это основное окно сведений об отладке в WinDbg. Вы можете ввести команды отладчика и просмотреть выходные данные команды в этом окне.
Окно команды отладчика разделено на две области. Введите команды в меньшей области, которая является областью входа команд в нижней части окна и просмотрите выходные данные команды в более крупной области в верхней части окна.
В области ввода команд используйте клавиши СТРЕЛКА ВВЕРХ и СТРЕЛКА ВНИЗ, чтобы прокрутить журнал команд. Когда появится команда, ее можно изменить или нажать клавишу ВВОД, чтобы выполнить команду.
Команды и методы отладки в режиме ядра
В этом разделе используются команды отладки для отображения сведений о целевой системе.
Некоторые команды отладки отображают текст с помощью языка разметки отладчика (DML), который можно быстро собрать дополнительные сведения.
В системе узла используйте ctrl+Scroll Lock в WinDBg, чтобы разорвать код, запущенный в целевой системе. Для реагирования целевой системы может потребоваться некоторое время.
Введите следующую команду, чтобы включить DML в окне команды отладчика:
0: kd> .prefer_dml 1 DML versions of commands on by default
С помощью команды можно получить доступ к справочной команде
.hh
. Введите следующую команду, чтобы просмотреть справку по ссылке на команду:.prefer_dml
0: kd> .hh .prefer_dml
Файл справки отладчика отображает справку по команде
.prefer_dml
.Чтобы отобразить подробные сведения о версии целевой системы, введите команду vertarget (Show Target Computer Version) в окне 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
Чтобы убедиться, что вы работаете с правильным процессом в режиме ядра, введите команду 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 ...
Выходные данные, которые были опущены, указываются с "..." в этой лаборатории.
Чтобы запросить подробные сведения о конкретном модуле, используйте
v
параметр (подробные сведения):0: Kd> lm v m tcpip Browse full module list start end module name fffff801`09eeb000 fffff801`0a157000 tcpip (no symbols) Loaded symbol image file: tcpip.sys Image path: \SystemRoot\System32\drivers\tcpip.sys Image name: tcpip.sys Browse all global symbols functions data Timestamp: Sun Nov 09 18:59:03 2014 (546029F7) CheckSum: 00263DB1 ImageSize: 0026C000 Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4 Unable to enumerate user-mode unloaded modules, Win32 error 0n30
Нет заданного пути к символам и загруженным символам, поэтому ограниченные сведения доступны в отладчике.
Скачивание и сборка драйвера эхо KMDF
В этом разделе скачайте и создайте драйвер эхо KMDF.
Как правило, вы будете работать с собственным кодом драйвера при использовании WinDbg. Чтобы ознакомиться с операцией WinDbg, в этой лаборатории используется пример драйвера шаблона KMDF "Echo". Исходный код доступен для понимания сведений, отображаемых в WinDbg. Этот пример также используется для иллюстрации того, как можно выполнить одношаговый код в собственном режиме ядра. Этот метод может быть ценным для отладки сложных проблем с кодом в режиме ядра.
Чтобы скачать и создать пример звукового драйвера Echo, выполните следующие действия.
Скачайте и извлеките пример эхо KMDF из GitHub.
Просмотрите пример эхо в GitHub.
Ознакомьтесь с примером.
Просмотрите все примеры драйверов Windows.
Пример "Эхо KMDF" находится в общей папке.
Скачайте примеры драйверов в одном ZIP-файле: примеры драйверов
Скачайте ZIP-файл на локальный жесткий диск.
Выберите и удерживайте или щелкните правой кнопкой мыши ZIP-файл и выберите "Извлечь все". Укажите новую папку или перейдите к существующей, чтобы сохранить извлеченные файлы. Например, можно указать C:\DriverSamples\ в качестве новой папки, в которую необходимо извлечь файлы.
После извлечения файлов перейдите в следующую вложенную папку: C:\DriverSamples\general\echo\kmdf
В Microsoft Visual Studio выберите >файл Open>Project/Solution... и перейдите в папку, содержащую извлеченные файлы, например C:\DriverSamples\general\echo\kmdf. Дважды щелкните файл решения kmdfecho , чтобы открыть его.
В Visual Studio найдите Обозреватель решений. Если это окно еще не открыто, выберите Обозреватель решений в меню "Вид". В Обозреватель решений можно увидеть одно решение с тремя проектами.
Задайте конфигурацию и платформу примера. В Обозреватель решений выберите и удерживайте или щелкните правой кнопкой мыши решение kmdfecho (3 проекта) и выберите Configuration Manager. Убедитесь, что параметры конфигурации и платформы одинаковы для трех проектов. По умолчанию для конфигурации задано значение Win10 Debug, а платформа имеет значение Win64 для всех проектов. Если вы вносите изменения конфигурации или платформы для одного проекта, внесите те же изменения для оставшихся трех проектов.
Примеры драйверов необходимо изменить для использования значений, которые не перекрываются с существующими драйверами. Ознакомьтесь с примерами кода к рабочему драйверу. Что нужно изменить в примерах , чтобы создать уникальный пример драйвера, который будет сосуществовать с существующими реальными драйверами, установленными в Windows.
Задайте библиотеку среды выполнения. Откройте страницу свойств эхо-драйвера и найдите создание кода C/C++>. Измените библиотеку среды выполнения на многопоточную отладку (/MTd). Дополнительные сведения о параметрах сборки см. в разделе /MD, /MT, /LD (использование библиотеки времени выполнения).
В свойствах драйвера убедитесь, что для режима подписи>драйвера задано значение Test Sign.
В Visual Studio выберите "Сборка решения сборки>".
Окна сборки должны отображать сообщение о том, что сборка для всех трех проектов выполнена успешно.
Совет
При возникновении сообщения об ошибке сборки используйте номер ошибки сборки для определения исправления. Например, ошибка MSBuild MSB8040 описывает, как работать с библиотеками с устранением рисков.
В проводник перейдите в папку, содержащую извлеченные файлы для примера. Например, перейдите в папку C:\DriverSamples\general\echo\kmdf, если это папка, указанная ранее. В этой папке расположение скомпилированных файлов драйверов зависит от параметров конфигурации и платформы, выбранных в Configuration Manager. Если вы оставили параметры по умолчанию без изменений, то скомпилированные файлы драйверов сохраняются в папке с именем \x64\Debug для 64-разрядной сборки отладки .
Перейдите в папку, содержащую встроенные файлы для драйвера автосинхронной синхронизации: C:\DriverSamples\general\echo\kmdf\driver\AutoSync\x64\Debug.
Папка должна содержать следующие файлы:
Файл Description Echo.sys Файл драйвера. Echo.inf Файл сведений (INF), содержащий сведения, необходимые для установки драйвера. Кроме того, был создан файл echoapp.exe и он должен находиться здесь: C:\DriverSamples\general\echo\kmdf\exe\x64\Debug.
Файл Description EchoApp.exe Исполняемый файл командной строки, который взаимодействует с драйвером echo.sys. Найдите USB-диск или настройте сетевую папку для копирования встроенных файлов драйверов и тестового EchoApp из узла в целевую систему.
В следующем разделе скопируйте код в целевую систему и установите и проверьте драйвер.
Установка примера эхо-драйвера KMDF в целевой системе
В этом разделе используйте средство DevCon для установки примера эхо-драйвера.
Компьютер, на котором устанавливается драйвер, называется целевым компьютером или тест-компьютером. Как правило, этот компьютер отделен от компьютера, на котором вы разрабатываете и создаете пакет драйвера. Компьютер, на котором вы разрабатываете и создаете драйвер, называется узлом.
Процесс перемещения пакета драйвера на целевой компьютер и установка драйвера вызывается развертыванием драйвера.
Перед развертыванием тестового подписанного драйвера подготовьте целевой компьютер, включив подписывание тестов. Кроме того, необходимо найти средство DevCon в установке WDK и скопировать его в целевую систему.
Чтобы установить драйвер в целевой системе, выполните следующие действия.
В целевой системе включите тестовые драйверы со знаком:
Откройте параметры Windows.
В разделе "Обновление и безопасность" выберите "Восстановление".
В разделе "Дополнительное запуск" выберите "Перезапустить сейчас".
Когда компьютер перезагрузится, выберите параметры запуска. В Windows 10 выберите "Устранение неполадок>с дополнительными параметрами> запуска", а затем нажмите кнопку "Перезапустить".
Выберите "Отключить принудительное применение подписи драйвера", нажав клавишу F7.
Перезапустите целевой компьютер.
В системе узла перейдите в папку Tools в установке WDK и найдите средство DevCon. Например, просмотрите следующую папку: C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe.
Создайте папку в целевом объекте для встроенного пакета драйвера, например C:\EchoDriver. Скопируйте devcon.exe в целевую систему. Найдите сертификат .cer в хост-системе. Он находится в той же папке на хост-компьютере в папке, содержащей встроенные файлы драйверов. Скопируйте все файлы из встроенного драйвера, описанного ранее на хост-компьютере, и сохраните их в одну папку, созданную на целевом компьютере.
На целевом компьютере выберите и удерживайте или щелкните правой кнопкой мыши файл сертификата и нажмите кнопку "Установить", а затем следуйте инструкциям по установке тестового сертификата.
Если вам нужны более подробные инструкции по настройке целевого компьютера, см. статью "Подготовка компьютера для развертывания драйверов вручную".
В следующих инструкциях показано, как установить и проверить пример драйвера. Ниже приведен общий синтаксис средства разработки, используемого для установки драйвера:
devcon install <INF file> <hardware ID>
INF-файл, необходимый для установки этого драйвера, — echo.inf. Inf-файл содержит идентификатор оборудования для установки echo.sys. Для примера эхо идентификатор оборудования является корневым\ECHO.
На целевом компьютере откройте окно командной строки от имени администратора. Перейдите в папку пакета драйвера и введите следующую команду:
devcon install echo.inf root\ECHO
Если появится сообщение об ошибке о том, что devcon не распознается, попробуйте добавить путь к средству devcon . Например, если вы скопировали его в папку C:\Tools, попробуйте выполнить следующую команду:
c:\tools\devcon install echo.inf root\ECHO
Откроется диалоговое окно, указывающее, что тестовый драйвер является драйвером без знака. Выберите " Установить этот драйвер", чтобы продолжить работу.
Совет
Если у вас возникли проблемы с установкой, дополнительные сведения см. в следующем файле. %windir%\inf\setupapi.dev.log
После успешной установки примера драйвера можно протестировать его.
На целевом компьютере в окне командной строки введите devmgmt, чтобы открыть диспетчер устройств. В диспетчер устройств в меню "Вид" выберите "Устройства" по типу. В дереве устройства найдите пример драйвера Эхо WDF в узле примера устройства.
Введите echoapp , чтобы запустить тестовое приложение эхо, чтобы убедиться, что драйвер работает.
C:\Samples\KMDF_Echo_Sample> echoapp
DevicePath: \\?\root#sample#0005#{cdc35b6e-0be4-4936-bf5f-5537380a7c1a}
Opened device successfully
512 Pattern Bytes Written successfully
512 Pattern Bytes Read successfully
Pattern Verified successfully
30720 Pattern Bytes Written successfully
30720 Pattern Bytes Read successfully
Pattern Verified successfully
Использование WinDbg для отображения сведений о драйвере
В этом разделе задайте путь к символам и используйте команды отладчика ядра для отображения сведений о примере драйвера эхо KMDF.
Чтобы просмотреть сведения о драйвере, выполните следующие действия.
Если вы закрыли отладчик, откройте его снова с помощью следующей команды в окне командной строки администратора.
WinDbg -k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Используйте клавиши CTRL+Break (Scroll Lock) для разрыва кода, выполняемого в целевой системе.
Чтобы задать путь к символам серверу символов Майкрософт в среде WinDbg, используйте
.symfix
команду.0: kd> .symfix
Чтобы добавить расположение локального символа для использования локальных символов, добавьте путь с помощью
.sympath+
и затем.reload /f
.0: kd> .sympath+ C:\DriverSamples\general\echo\kmdf 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
Введите следующую команду в области команд отладчика, чтобы отобразить сведения о драйвере эхо:
0: kd> lm m echo* v Browse full module list start end module name fffff801`4ae80000 fffff801`4ae89000 ECHO (private pdb symbols) C:\Samples\KMDF_ECHO_SAMPLE\echo.pdb Loaded symbol image file: ECHO.sys Image path: \SystemRoot\system32\DRIVERS\ECHO.sys Image name: ECHO.sys ...
Дополнительные сведения см. в разделе lm.
Так как этот набор
prefer_dml
лаборатории ранее, некоторые элементы выходных данных являются горячими ссылками, которые можно выбрать. Выберите ссылку "Обзор всех глобальных символов" в выходных данных отладки, чтобы отобразить сведения о символах элементов, начинающихся с буквы "a".0: kd> x /D Echo!a*
Пример эхо не содержит символов, начинающихся с буквы "a", поэтому введите
x ECHO!Echo*
сведения обо всех символах, связанных с драйвером эхо, которые начинаются с "Echo".0: kd> x ECHO!Echo* fffff801`0bf95690 ECHO!EchoEvtIoQueueContextDestroy (void *) fffff801`0bf95000 ECHO!EchoEvtDeviceSelfManagedIoStart (struct WDFDEVICE__ *) fffff801`0bf95ac0 ECHO!EchoEvtTimerFunc (struct WDFTIMER__ *) fffff801`0bf9b120 ECHO!EchoEvtDeviceSelfManagedIoSuspend (struct WDFDEVICE__ *) ...
Дополнительные сведения см. в разделе x (Проверка символов).
Расширение отображает подробные
!lmi
сведения о модуле. Введите!lmi echo
. Выходные данные должны совпадать с текстом, показанным в этом примере:0: kd> !lmi echo Loaded Module Info: [echo] Module: ECHO Base Address: fffff8010bf94000 Image Name: ECHO.sys …
Используйте расширение для отображения сведений
!dh
о заголовке, как показано в этом примере:0: kd> !dh echo File Type: EXECUTABLE IMAGE FILE HEADER VALUES 14C machine (i386) 6 number of sections 54AD8A42 time date stamp Wed Jan 07 11:34:26 2015 ...
Введите следующую команду, чтобы изменить маску битовой отладки по умолчанию, чтобы все отладочные сообщения из целевой системы отображались в отладчике:
0: kd> ed nt!Kd_DEFAULT_MASK 0xFFFFFFFF
Некоторые драйверы отображают дополнительные сведения при использовании маски 0xFFFFFFFF. Задайте для маски значение 0x00000000, если вы хотите уменьшить объем отображаемых сведений.
0: kd> ed nt!Kd_DEFAULT_MASK 0x00000000
dd
Используйте команду, чтобы подтвердить, что маска настроена для отображения всех сообщений отладчика.0: kd> dd nt!kd_DEFAULT_MASK fffff802`bb4057c0 ffffffff 00000000 00000000 00000000 fffff802`bb4057d0 00000000 00000000 00000000 00000000 fffff802`bb4057e0 00000001 00000000 00000000 00000000 fffff802`bb4057f0 00000000 00000000 00000000 00000000 fffff802`bb405800 00000000 00000000 00000000 00000000 fffff802`bb405810 00000000 00000000 00000000 00000000 fffff802`bb405820 00000000 00000000 00000000 00000000 fffff802`bb405830 00000000 00000000 00000000 00000000
Отображение сведений о дереве устройств самонастраивающийся
В этом разделе отображаются сведения о драйвере устройства эхо и его расположении в дереве устройств самонастраивающийся.
Сведения об драйвере устройства в дереве устройств самонастраивающийся могут быть полезны для устранения неполадок. Например, если драйвер устройства не является резидентом дерева устройств, может возникнуть проблема с установкой драйвера устройства.
Дополнительные сведения о расширении отладки узла устройства см. в разделе !devnode.
Чтобы просмотреть все узлы устройства в дереве устройств самонастраивающийся, введите
!devnode 0 1
команду.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… …
Используйте CTRL+F для поиска в выходных данных, созданных для поиска имени драйвера устройства, эхо.
Необходимо загрузить драйвер эхо-устройства.
!devnode 0 1 echo
Используйте команду для отображения самонастраивающийся сведений, связанных с драйвером эхо устройства, как показано в этом примере:0: Kd> !devnode 0 1 echo Dumping IopRootDeviceNode (= 0xffffe0007b725d30) DevNode 0xffffe0007b71a630 for PDO 0xffffe0007b71a960 InstancePath is "ROOT\SAMPLE\0000" ServiceName is "ECHO" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) …
Выходные данные, отображаемые в предыдущей команде, включают PDO, связанную с запущенным экземпляром драйвера, в этом примере 0xffffe0007b71a960.
!devobj <PDO address>
Введите команду, чтобы отобразить самонастраивающийся сведения, связанные с драйвером эхо устройства. Используйте адрес PDO,!devnode
отображаемый на компьютере, а не указанный здесь.0: kd> !devobj 0xffffe0007b71a960 Device object (ffffe0007b71a960) is for: 0000000e \Driver\PnpManager DriverObject ffffe0007b727e60 Current Irp 00000000 RefCount 0 Type 00000004 Flags 00001040 Dacl ffffc102c9b36031 DevExt 00000000 DevObjExt ffffe0007b71aab0 DevNode ffffe0007b71a630 ExtensionFlags (0x00000800) DOE_DEFAULT_SD_PRESENT Characteristics (0x00000180) FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN AttachedDevice (Upper) ffffe000801fee20 \Driver\ECHO Device queue is not busy.
Выходные данные, отображаемые в команде
!devnode 0 1
, включают адрес PDO, связанный с запущенным экземпляром драйвера, в этом примере это 0xffffe0007b71a960.!devstack <PDO address>
Введите команду, чтобы отобразить самонастраивающийся сведения, связанные с драйвером устройства. Используйте адрес PDO,!devnode
отображаемый на компьютере, а не тот, который показан в этом примере.0: kd> !devstack 0xffffe0007b71a960 !DevObj !DrvObj !DevExt ObjectName ffffe000801fee20 \Driver\ECHO ffffe0007f72eff0 > ffffe0007b71a960 \Driver\PnpManager 00000000 0000000e !DevNode ffffe0007b71a630 : DeviceInst is "ROOT\SAMPLE\0000" ServiceName is "ECHO"
В выходных данных показано, что у вас есть довольно простой стек драйверов устройств. Драйвер эхо является дочерним элементом узла PnPManager . PnPManager — это корневой узел.
\Driver\ECHO
\Driver\PnpManager
На этой схеме показано более сложное дерево узлов устройства.
Дополнительные сведения о более сложных стеках драйверов см. в стеках драйверов и узлах устройств и стеках устройств.
Работа с точками останова и исходным кодом
В этом разделе задайте точки останова и одношаговый исходный код в режиме ядра.
Чтобы выполнить пошаговое выполнение кода и проверить значения переменных в режиме реального времени, включите точки останова и задайте путь к исходному коду.
Точки останова останавливают выполнение кода в определенной строке кода. Шаг вперед в коде с этого момента, чтобы отлаживать этот конкретный раздел кода.
Чтобы задать точку останова с помощью команды отладки, используйте одну из следующих b
команд.
Команда | Description |
---|---|
bp |
Задает точку останова, активную до выгрузки модуля. |
bu |
Задает точку останова, которая неразрешенная при выгрузке модуля и повторно включается при перезагрузке модуля. |
bm |
Задает точку останова для символа. Эта команда использует или bp соответствующим образом и позволяет использовать bu подстановочные знаки (* ) для задания точек останова для каждого символа, соответствующего всем методам в классе. |
Дополнительные сведения см. в статье отладка исходного кода в WinDbg.
В системе узла используйте пользовательский интерфейс WinDbg, чтобы убедиться, что режим источника отладки>включен в текущем сеансе WinDbg.
Введите следующую команду, чтобы добавить расположение локального кода в исходный путь:
.srcpath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
Введите следующую команду, чтобы добавить расположение локального символа в путь к символу:
.sympath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
x
Используйте команду для проверки символов, связанных с драйвером эхо, чтобы определить имя функции, используемое для точки останова. Для поискаDeviceAdd
имени функции можно использовать подстановочный знак или CTRL+F.0: kd> x ECHO!EchoEvt* 8b4c7490 ECHO!EchoEvtIoQueueContextDestroy (void *) 8b4c7000 ECHO!EchoEvtDeviceSelfManagedIoStart (struct WDFDEVICE__ *) 8b4c7820 ECHO!EchoEvtTimerFunc (struct WDFTIMER__ *) 8b4cb0e0 ECHO!EchoEvtDeviceSelfManagedIoSuspend (struct WDFDEVICE__ *) 8b4c75d0 ECHO!EchoEvtIoWrite (struct WDFQUEUE__ *, struct WDFREQUEST__ *, unsigned int) 8b4cb170 ECHO!EchoEvtDeviceAdd (struct WDFDRIVER__ *, struct …
В выходных данных показано, что
DeviceAdd
метод для драйвера эхо.ECHO!EchoEvtDeviceAdd
Кроме того, просмотрите исходный код, чтобы найти имя функции для точки останова.
Задайте точку останова с
bm
помощью команды, используя имя драйвера, за которым следует имя функции, напримерAddDevice
, где нужно задать точку останова, разделенную восклицательным знаком. Эта лаборатория используетсяAddDevice
для просмотра загрузки драйвера.0: kd> bm ECHO!EchoEvtDeviceAdd 1: fffff801`0bf9b1c0 @!"ECHO!EchoEvtDeviceAdd"
Вы можете использовать другой синтаксис в сочетании с параметрами переменных, например
<module>!<symbol>
,<class>::<method>
'<file.cpp>:<line number>'
или пропустить несколько раз<condition> <#>
. Дополнительные сведения см. в разделе "Условные точки останова" в WinDbg и других отладчиках Windows.Перечислите текущие точки останова, чтобы убедиться, что точка останова была задана,
bl
введя команду:0: kd> bl 1 e fffff801`0bf9b1c0 0001 (0001) ECHO!EchoEvtDeviceAdd
В выходных данных, показанных здесь, указано, что точка останова 1 включена для срабатывания.
Перезапустите выполнение кода в целевой системе, введя
g
команду (go).В целевой системе в Windows откройте диспетчер устройств с помощью значка или ввода mmc devmgmt.msc. В диспетчер устройств разверните узел Samples.
Выберите и удерживайте или щелкните правой кнопкой мыши запись эхо-драйвера KMDF и выберите "Отключить " в меню.
Выберите и удерживайте или удерживайте правой кнопкой мыши запись эхо-драйвера KMDF и выберите "Включить " в меню.
В системе узла, когда драйвер включен, точка останова отладки AddDevice должна запускаться. Выполнение кода драйвера в целевой системе должно быть остановлено. При нажатии точки останова выполнение должно быть остановлено в начале подпрограммы AddDevice . Отображается вывод команды отладки
Breakpoint 1 hit
.Шаг по строке кода, введя
p
команду или нажав клавишу F10, пока не достигнет следующего конца подпрограммы AddDevice . Символ фигурной скобки (}
) выделен, как показано ниже.
В следующем разделе изучите состояние переменных после выполнения кода DeviceAdd.
Существующие точки останова можно изменить с помощью следующих команд:
Команда | Description |
---|---|
bl |
Выводит список точек останова. |
bc |
Очищает точку останова из списка. Используйте bc * для очистки всех точек останова. |
bd |
Отключает точку останова. Используется bd * для отключения всех точек останова. |
be |
Включает точку останова. Используется be * для включения всех точек останова. |
Кроме того, можно изменить точки останова в пользовательском интерфейсе WinDbg.
Вы также можете задать точки останова, которые запускаются при доступе к расположению памяти. ba
Используйте команду (разрыв доступа) со следующим синтаксисом:
ba <access> <size> <address> {options}
Вариант | Описание |
---|---|
e |
выполнение: при получении инструкции из адреса ЦП |
r |
чтение и запись: при чтении или записи ЦП в адрес |
w |
запись: при записи ЦП в адрес |
В любое время можно задать только четыре точки останова данных. Это до вас, чтобы убедиться, что вы правильно выравниваете данные, чтобы активировать точку останова. Слова должны заканчиваться адресами, делимыми на 2, слова должны быть делимыми на 4, а четыре слова на 0 или 8.
Например, чтобы задать точку останова чтения и записи для определенного адреса памяти, можно использовать команду, как в этом примере.
ba r 4 0x0003f7bf0
Для пошагового выполнения кода с соответствующими короткими сокращениями клавиатуры, показанными в скобках, можно использовать следующие команды.
- Разрыв (CTRL+Break). Эта команда прерывает работу системы до тех пор, пока система запущена и находится в обмене данными с WinDbg. Последовательность в отладчике ядра — CTRL+C.
- Запустите на курсор (F7 или CTRL+F10). Поместите курсор в исходное или дизассемблированное окно, где требуется разорвать выполнение, а затем нажмите клавишу F7. Выполнение кода выполняется до этой точки. Если поток выполнения кода не достигает точки, указанной курсором, WinDbg не прерывается. Эта ситуация может произойти, если инструкция IF не выполняется.
- Запуск (F5). Запустите до тех пор, пока не будет обнаружена точка останова или происходит событие, например проверка ошибок.
- Шаг над (F10). Эта команда приводит к выполнению кода для выполнения одной инструкции или одной инструкции за раз. При обнаружении вызова выполнение кода передает вызов без ввода вызываемой подпрограммы. Если язык программирования — C или C++ и WinDbg находится в исходном режиме, исходный режим можно включить или отключить с помощью режима источника отладки>.
- Шаг (F11). Эта команда похожа на пошаговое выполнение, за исключением того, что выполнение вызова переходит в вызываемую подпрограмму.
- Шаг выхода (SHIFT+F11). Эта команда приводит к запуску и выходу из текущей подпрограммы или текущего места в стеке вызовов. Эта команда полезна, если вы видели достаточно подпрограммы.
Дополнительные сведения см. в статье отладка исходного кода в WinDbg.
Просмотр переменных и стеков вызовов
В этом разделе отображаются сведения о переменных и стеках вызовов.
В этой лаборатории предполагается, что вы остановлены в подпрограмме AddDevice с помощью описанного выше процесса. Чтобы просмотреть выходные данные, показанные здесь, повторите описанные ранее действия при необходимости.
Для отображения переменных в системе узла используйте элемент локального меню представления>для отображения локальных переменных.
Чтобы найти расположение глобальной переменной, введите ? <variable name>
.
- Шаг выхода (SHIFT+F11) — эта команда приводит к выполнению и выходу из текущей подпрограммы (текущее место в стеке вызовов). Это полезно, если вы видели достаточно подпрограммы.
Дополнительные сведения см. в статье "Отладка исходного кода" в WinDbg (классическая версия) в справочной документации по отладке.
Раздел 8. Просмотр переменных и стеков вызовов
В разделе 8 вы увидите сведения о переменных и стеках вызовов.
В этой лаборатории предполагается, что вы остановлены в подпрограмме AddDevice с помощью описанного выше процесса. Чтобы просмотреть выходные данные, повторите описанные ранее действия при необходимости.
<— в хост-системе
Отображение переменных
Используйте элемент локального меню представления>для отображения локальных переменных.
Глобальные переменные
Расположение глобальной переменной можно найти, введя ? <имя> переменной.
Локальные переменные
Имена и значения всех локальных переменных для заданного кадра можно отобразить, введя команду dv .
Чтобы отобразить имена и значения всех локальных переменных для определенного кадра, введите dv
команду:
0: kd> dv
Driver = 0x00001fff`7ff9c838
DeviceInit = 0xffffd001`51978190
status = 0n0
Стек вызовов — это цепочка вызовов функций, которые привели к текущему расположению счетчика программы. Верхняя функция в стеке вызовов — текущая функция, а следующая функция — это функция, которая называется текущей функцией и т. д.
Чтобы отобразить стек вызовов, используйте k*
команды.
Команда | Description |
---|---|
kb |
Отображает стек и первые три параметра. |
kp |
Отображает стеки и полный список параметров. |
kn |
Позволяет увидеть стек с информацией кадра рядом с ним. |
В системе узла, если вы хотите сохранить стек вызовов, выберите стек вызовов представления, чтобы просмотреть>его. Выберите столбцы в верхней части окна, чтобы переключить отображение дополнительных сведений.
kn
Используйте команду, чтобы отобразить стек вызовов при отладке примера кода адаптера в состоянии останова.3: kd> kn # Child-SP RetAddr Call Site 00 ffffd001`51978110 fffff801`0942f55b ECHO!EchoEvtDeviceAdd+0x66 [c:\Samples\kmdf echo sample\c++\driver\autosync\driver.c @ 138] 01 (Inline Function) --------`-------- Wdf01000!FxDriverDeviceAdd::Invoke+0x30 [d:\wbrtm\minkernel\wdf\framework\shared\inc\private\common\fxdrivercallbacks.hpp @ 61] 02 ffffd001`51978150 fffff801`eed8097d Wdf01000!FxDriver::AddDevice+0xab [d:\wbrtm\minkernel\wdf\framework\shared\core\km\fxdriverkm.cpp @ 72] 03 ffffd001`51978570 fffff801`ef129423 nt!PpvUtilCallAddDevice+0x35 [d:\9142\minkernel\ntos\io\pnpmgr\verifier.c @ 104] 04 ffffd001`519785b0 fffff801`ef0c4112 nt!PnpCallAddDevice+0x63 [d:\9142\minkernel\ntos\io\pnpmgr\enum.c @ 7397] 05 ffffd001`51978630 fffff801`ef0c344f nt!PipCallDriverAddDevice+0x6e2 [d:\9142\minkernel\ntos\io\pnpmgr\enum.c @ 3390] ...
Стек вызовов показывает, что ядро (nt) вызывается в код самонастраивающийся (PnP), который называется кодом платформы драйверов (WDF), который позже назвал функцию эхо-драйвераDeviceAdd
.
Отображение процессов и потоков
В этом разделе отображаются сведения о процессах и потоках, выполняемых в режиме ядра.
Процессы
Вы можете отобразить или задать сведения о процессе с помощью расширения отладчика !process . Задайте точку останова для изучения процесса, используемого при воспроизведении звука.
В системе узла введите
dv
команду для проверки переменных языкового стандарта, связанных с подпрограммойEchoEvtIo
:0: kd> dv ECHO!EchoEvtIo* ECHO!EchoEvtIoQueueContextDestroy ECHO!EchoEvtIoWrite ECHO!EchoEvtIoRead
Снимите предыдущие точки останова с помощью
bc *
:0: kd> bc *
Задайте точку останова символа в
EchoEvtIo
подпрограммах с помощью следующей команды:0: kd> bm ECHO!EchoEvtIo* 2: aade5490 @!”ECHO!EchoEvtIoQueueContextDestroy” 3: aade55d0 @!”ECHO!EchoEvtIoWrite” 4: aade54c0 @!”ECHO!EchoEvtIoRead”
Выведите список точек останова, чтобы убедиться, что точка останова задана правильно:
0: kd> bl 1 e aabf0490 [c:\Samples\kmdf echo sample\c++\driver\autosync\queue.c @ 197] 0001 (0001) ECHO!EchoEvtIoQueueContextDestroy ...
Введите
g
для перезапуска выполнения кода:0: kd> g
В целевой системе запустите тестовую
EchoApp.exe
программу драйвера в целевой системе.При запуске тестового приложения в системе узла вызывается подпрограмма ввода-вывода в драйвере. Этот вызов приводит к срабатыванию точки останова и выполнению кода драйвера в целевой системе останавливается.
Breakpoint 2 hit ECHO!EchoEvtIoWrite: fffff801`0bf95810 4c89442418 mov qword ptr [rsp+18h],r8
!process
Используйте команду, чтобы отобразить текущий процесс, участвующий в выполнении echoapp.exe:0: kd> !process PROCESS ffffe0007e6a7780 SessionId: 1 Cid: 03c4 Peb: 7ff7cfec4000 ParentCid: 0f34 DirBase: 1efd1b000 ObjectTable: ffffc001d77978c0 HandleCount: 34. Image: echoapp.exe VadRoot ffffe000802c79f0 Vads 30 Clone 0 Private 135. Modified 5. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001cf270050 ElapsedTime 00:00:00.052 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 33824 QuotaPoolUsage[NonPagedPool] 4464 Working Set Sizes (now,min,max) (682, 50, 345) (2728KB, 200KB, 1380KB) PeakWorkingSetSize 652 VirtualSize 16 Mb PeakVirtualSize 16 Mb PageFaultCount 688 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 138 THREAD ffffe00080e32080 Cid 03c4.0ec0 Teb: 00007ff7cfece000 Win32Thread: 0000000000000000 RUNNING on processor 1
В выходных данных показано, что процесс связан с потоком echoapp.exe , который выполнялся при нажатии точки останова на событие записи драйвера. Дополнительные сведения см. в разделе !process.
!process 0 0
Используйте сводную информацию для всех процессов. В выходных данных используйте ctrl+F, чтобы найти тот же адрес процесса для процесса, связанного с изображением echoapp.exe . В примере используетсяffffe0007e6a7780
адрес процесса.... PROCESS ffffe0007e6a7780 SessionId: 1 Cid: 0f68 Peb: 7ff7cfe7a000 ParentCid: 0f34 DirBase: 1f7fb9000 ObjectTable: ffffc001cec82780 HandleCount: 34. Image: echoapp.exe ...
Запишите идентификатор процесса, связанный с echoapp.exe для использования позже в этой лаборатории. Вы также можете скопировать адрес в буфер копирования для последующего использования с помощью CTRL+C.
адрес процесса _____________________________________________________(echoapp.exe)
Введите
g
отладчик по мере необходимости, чтобы запустить код вперед, пока echoapp.exe не завершит работу. Он попадает в точку останова в событии чтения и записи много раз. Когда echoapp.exe завершится, войдите в отладчик, нажав клавиши CTRL+ScrLk (CTRL+Break).!process
Используйте команду, чтобы убедиться, что выполняется другой процесс. В выходных данных, показанных здесь, процесс со значением изображения системы отличается от значения эхо-изображения .1: kd> !process PROCESS ffffe0007b65d900 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 001ab000 ObjectTable: ffffc001c9a03000 HandleCount: 786. Image: System VadRoot ffffe0007ce45930 Vads 14 Clone 0 Private 22. Modified 131605. Locked 64. DeviceMap ffffc001c9a0c220 Token ffffc001c9a05530 ElapsedTime 21:31:02.516 ...
В выходных данных показано, что системный процесс ffffe0007b65d900 выполняется при остановке ОС.
!process
Используйте команду, чтобы попытаться просмотреть идентификатор процесса, связанный с echoapp.exe, записанной ранее. Укажите адрес процесса echoapp.exe, записанный ранее, вместо примера адреса процесса, показанного в этом примере.0: kd> !process ffffe0007e6a7780 TYPE mismatch for process object at 82a9acc0
Объект процесса больше недоступен, так как процесс echoapp.exe больше не выполняется.
Потоки
Команды для просмотра и задания потоков аналогичны командам для процессов. Используйте команду !thread для просмотра потоков. Используйте поток .thread для задания текущих потоков.
В системе узла введите
g
отладчик, чтобы перезапустить выполнение кода в целевой системе.В целевой системе запустите тестовую программу EchoApp.exe драйвера.
В системе узла точка останова останавливается, а выполнение кода останавливается.
Breakpoint 4 hit ECHO!EchoEvtIoRead: aade54c0 55 push ebp
Чтобы просмотреть выполняемые потоки, введите !thread. Должны отображаться сведения, аналогичные следующему примеру:
0: kd> !thread THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0 IRP List: ffffe0007bc5be10: (0006,01f0) Flags: 00060a30 Mdl: 00000000 Not impersonating DeviceMap ffffc001d83c6e80 Owning Process ffffe0008096c900 Image: echoapp.exe ...
Запишите имя изображения echoapp.exe. Это означает, что вы просматриваете поток, связанный с тестируемым приложением.
!process
Используйте команду, чтобы определить, является ли этот поток единственным потоком, выполняемым в процессе, связанном с echoapp.exe. Число потоков выполняемого потока в процессе совпадает с тем потоком, который отображается командой!thread
.0: kd> !process PROCESS ffffe0008096c900 SessionId: 1 Cid: 0b28 Peb: 7ff7d00df000 ParentCid: 0f34 DirBase: 1fb746000 ObjectTable: ffffc001db6b52c0 HandleCount: 34. Image: echoapp.exe VadRoot ffffe000800cf920 Vads 30 Clone 0 Private 135. Modified 8. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001cf5dc050 ElapsedTime 00:00:00.048 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 33824 QuotaPoolUsage[NonPagedPool] 4464 Working Set Sizes (now,min,max) (681, 50, 345) (2724KB, 200KB, 1380KB) PeakWorkingSetSize 651 VirtualSize 16 Mb PeakVirtualSize 16 Mb PageFaultCount 686 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 138 THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0
!process 0 0
Используйте команду, чтобы найти адрес процесса двух связанных процессов и записать этот адрес.Cmd.exe: ____________________________________________________________
EchoApp.exe: _______________________________________________________
0: kd> !process 0 0 … PROCESS ffffe0007bbde900 SessionId: 1 Cid: 0f34 Peb: 7ff72dfa7000 ParentCid: 0c64 DirBase: 19c5fa000 ObjectTable: ffffc001d8c2f300 HandleCount: 31. Image: cmd.exe … PROCESS ffffe0008096c900 SessionId: 1 Cid: 0b28 Peb: 7ff7d00df000 ParentCid: 0f34 DirBase: 1fb746000 ObjectTable: ffffc001db6b52c0 HandleCount: 34. Image: echoapp.exe …
Кроме того, можно использовать
!process 0 17
для отображения подробных сведений о каждом процессе. Выходные данные этой команды могут быть длинными. Выходные данные можно искать с помощью ctrl+F.Используйте команду для перечисления сведений
!process
о процессе для обоих процессов на компьютере. Укажите адрес процесса из!process 0 0
выходных данных, а не адрес, показанный в этом примере.Этот пример выходных данных предназначен для идентификатора процесса cmd.exe , записанного ранее. Имя образа для этого идентификатора процесса cmd.exe.
0: kd> !process ffffe0007bbde900 PROCESS ffffe0007bbde900 SessionId: 1 Cid: 0f34 Peb: 7ff72dfa7000 ParentCid: 0c64 DirBase: 19c5fa000 ObjectTable: ffffc001d8c2f300 HandleCount: 31. Image: cmd.exe VadRoot ffffe0007bb8e7b0 Vads 25 Clone 0 Private 117. Modified 20. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001d8c48050 ElapsedTime 21:33:05.840 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 24656 QuotaPoolUsage[NonPagedPool] 3184 Working Set Sizes (now,min,max) (261, 50, 345) (1044KB, 200KB, 1380KB) PeakWorkingSetSize 616 VirtualSize 2097164 Mb PeakVirtualSize 2097165 Mb PageFaultCount 823 MemoryPriority FOREGROUND BasePriority 8 CommitCharge 381 THREAD ffffe0007cf34880 Cid 0f34.0f1c Teb: 00007ff72dfae000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable ffffe0008096c900 ProcessObject Not impersonating ...
Этот пример выходных данных предназначен для идентификатора процесса echoapp.exe , записанного ранее.
0: kd> !process ffffe0008096c900 PROCESS ffffe0008096c900 SessionId: 1 Cid: 0b28 Peb: 7ff7d00df000 ParentCid: 0f34 DirBase: 1fb746000 ObjectTable: ffffc001db6b52c0 HandleCount: 34. Image: echoapp.exe VadRoot ffffe000800cf920 Vads 30 Clone 0 Private 135. Modified 8. Locked 0. DeviceMap ffffc001d83c6e80 Token ffffc001cf5dc050 ElapsedTime 00:00:00.048 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 33824 QuotaPoolUsage[NonPagedPool] 4464 Working Set Sizes (now,min,max) (681, 50, 345) (2724KB, 200KB, 1380KB) PeakWorkingSetSize 651 VirtualSize 16 Mb PeakVirtualSize 16 Mb PageFaultCount 686 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 138 THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0 IRP List: ffffe0007bc5be10: (0006,01f0) Flags: 00060a30 Mdl: 00000000 Not impersonating ...
Запишите первый адрес потока, связанный с двумя процессами.
Cmd.exe: ____________________________________________________
EchoApp.exe: _________________________________________________
!Thread
Используйте команду для отображения сведений о текущем потоке.0: kd> !Thread THREAD ffffe000809a0880 Cid 0b28.1158 Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0 IRP List: ffffe0007bc5be10: (0006,01f0) Flags: 00060a30 Mdl: 00000000 Not impersonating DeviceMap ffffc001d83c6e80 Owning Process ffffe0008096c900 Image: echoapp.exe Attached Process N/A Image: N/A ...
Как ожидается, текущий поток связан с echoapp.exe и находится в состоянии выполнения.
Используйте команду для отображения сведений о потоке
!Thread
, связанном с процессом cmd.exe . Укажите адрес потока, записанный ранее.0: kd> !Thread ffffe0007cf34880 THREAD ffffe0007cf34880 Cid 0f34.0f1c Teb: 00007ff72dfae000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable ffffe0008096c900 ProcessObject Not impersonating DeviceMap ffffc001d83c6e80 Owning Process ffffe0007bbde900 Image: cmd.exe Attached Process N/A Image: N/A Wait Start TickCount 4134621 Ticks: 0 Context Switch Count 4056 IdealProcessor: 0 UserTime 00:00:00.000 KernelTime 00:00:01.421 Win32 Start Address 0x00007ff72e9d6e20 Stack Init ffffd0015551dc90 Current ffffd0015551d760 Base ffffd0015551e000 Limit ffffd00155518000 Call 0 Priority 14 BasePriority 8 UnusualBoost 3 ForegroundBoost 2 IoPriority 2 PagePriority 5 Child-SP RetAddr : Args to Child : Call Site ffffd001`5551d7a0 fffff801`eed184fe : fffff801`eef81180 ffffe000`7cf34880 00000000`fffffffe 00000000`fffffffe : nt!KiSwapContext+0x76 [d:\9142\minkernel\ntos\ke\amd64\ctxswap.asm @ 109] ffffd001`5551d8e0 fffff801`eed17f79 : ffff03a5`ca56a3c8 000000de`b6a6e990 000000de`b6a6e990 00007ff7`d00df000 : nt!KiSwapThread+0x14e [d:\9142\minkernel\ntos\ke\thredsup.c @ 6347] ffffd001`5551d980 fffff801`eecea340 : ffffd001`5551da18 00000000`00000000 00000000`00000000 00000000`00000388 : nt!KiCommitThreadWait+0x129 [d:\9142\minkernel\ntos\ke\waitsup.c @ 619] ...
Этот поток связан с cmd.exe и находится в состоянии ожидания.
Укажите адрес потока ожидания CMD.exe потока, чтобы изменить контекст на этот поток ожидания.
0: kd> .Thread ffffe0007cf34880 Implicit thread is now ffffe000`7cf34880
k
Используйте команду для просмотра стека вызовов, связанного с потоком ожидания.0: kd> k *** Stack trace for last set context - .thread/.cxr resets it # Child-SP RetAddr Call Site 00 ffffd001`5551d7a0 fffff801`eed184fe nt!KiSwapContext+0x76 [d:\9142\minkernel\ntos\ke\amd64\ctxswap.asm @ 109] 01 ffffd001`5551d8e0 fffff801`eed17f79 nt!KiSwapThread+0x14e [d:\9142\minkernel\ntos\ke\thredsup.c @ 6347] 02 ffffd001`5551d980 fffff801`eecea340 nt!KiCommitThreadWait+0x129 [d:\9142\minkernel\ntos\ke\waitsup.c @ 619] 03 ffffd001`5551da00 fffff801`ef02e642 nt!KeWaitForSingleObject+0x2c0 [d:\9142\minkernel\ntos\ke\wait.c @ 683] ...
Такие элементы стека вызовов, как
KiCommitThreadWait
указание на то, что этот поток не выполняется должным образом.
Дополнительные сведения о потоках и процессах см. в следующих ссылках:
IRQL, регистрация и завершение сеанса WinDbg
В этом разделе отображаются уровни запроса прерывания (IRQL) и содержимое регистров.
Просмотр сохраненного IRQL
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
Кроме того, можно отобразить содержимое регистров, выбрав пункт "Просмотр>регистров". Дополнительные сведения см. в разделе r (Registers).
Просмотр содержимого регистров может оказаться полезным при пошаговом выполнении кода языка сборки и в других сценариях. Дополнительные сведения об дизассембли языка сборки см. в разделе Annotated x86 Disassembly и annotated x64 disassembly.
Сведения о содержимом регистра см. в разделе архитектуры x86 и архитектуры x64.
Завершение сеанса WinDbg
Если вы хотите оставить отладчик подключенным, но хотите работать с целевым объектом, снимите все точки bc *
останова, чтобы целевой компьютер не попытается подключиться к отладчику хост-компьютера. Затем используйте g
команду, чтобы позволить целевому компьютеру снова запуститься.
Чтобы завершить сеанс отладки, в системе узла войдете в отладчик и введите qd
команду (Выход и отсоединение) или нажмите кнопку "Остановить отладку " в меню.
0: kd> qd
Дополнительные сведения см. в разделе "Завершение сеанса отладки" в WinDbg.
Ресурсы отладки Windows
Дополнительные сведения см. в отладке Windows. Некоторые из этих книг используют более ранние версии Windows, такие как Windows Vista в своих примерах, но описанные понятия применимы к большинству версий Windows.
Книги
- Расширенная отладка Windows Марио Hewardt и Даниэль Прават
- В отладке Windows: практическое руководство по отладке и трассировке стратегий в Windows® от Tarik Soulami
- Windows Internals Павел Yosifovich, Алекс Ионеску, Марк Руссинович и Дэвид Соломон
Видео
Поставщики обучения