Отладка драйверов Windows пошаговые лаборатории (режим эхо-ядра)

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

Цели лаборатории

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

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

  • Использование команд отладчика Windows
  • Используйте стандартные команды (стеки вызовов, переменные, потоки, IRQL)
  • Использование команд отладки расширенного драйвера (!commands)
  • Использование символов
  • Настройка точек останова в динамической отладке
  • Просмотр стеков вызовов
  • Отображение дерева устройств самонастраивающийся
  • Работа с контекстом потока и процесса

Отладка режима пользователя и ядра

При работе с отладчиком Windows можно выполнить два типа отладки:

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

Режим ядра — операционная система и привилегированные программы выполняются в режиме ядра. Код в режиме ядра имеет разрешение на доступ к любой части системы. Он не ограничен, как код пользовательского режима. Он может получить доступ к любой части любого другого процесса, выполняемого в пользовательском режиме или в режиме ядра. Большая часть основных функций ОС и многие драйверы аппаратных устройств выполняются в режиме ядра.

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

Организация занятия

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

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

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

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

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

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

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

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

В этой лаборатории используются два компьютера. Отладчик Windows выполняется в системе узла и драйвере эхо-драйвера режима ядра (KMDF) выполняется в целевой системе.

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

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

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

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

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

  1. В системе узла откройте окно командной строки и введите ipconfig , чтобы определить его IP-адрес.

    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 . . . . . . . . . :
    
  2. Запишите IP-адрес хост-системы: ______________________________________

  3. В целевой системе откройте окно командной строки и используйте 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, может сделать систему неработоспособной.

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

    bcdedit /set {default} DEBUG YES
    
  2. Введите следующую команду, чтобы включить подписывание тестов:

    bcdedit /set TESTSIGNING ON 
    
  3. Введите эту команду, чтобы задать IP-адрес хост-системы. Используйте IP-адрес хост-системы, записанной ранее, а не отображаемую.

    bcdedit /dbgsettings net hostip:192.168.1.1 port:50000 key:2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    

    Предупреждение

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

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

    bcdedit /dbgsettings
    
    key                     2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    debugtype               NET
    hostip                  169.168.1.1
    port                    50000
    dhcp                    Yes
    The operation completed successfully.
    

    Примечание.

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

    Снимок экрана: диалоговое окно

  5. На хост-компьютере откройте окно командной строки как Администратор istrator. В этой лаборатории используется версия x64 WinDbg.exe из комплекта драйверов Windows (WDK), которая была установлена в процессе установки пакета Windows. Перейдите к каталогу WinDbg по умолчанию, расположение по умолчанию показано ниже.

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

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

  6. Откройте WinDbg с отладкой удаленного пользователя с помощью следующей команды. Значения ключа и порта соответствуют значениям, заданным ранее с помощью BCDEdit на целевом компьютере.

    WinDbg –k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    
  7. Перезапустите целевую систему.

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

    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), который можно быстро собрать дополнительные сведения.

  1. В системе узла используйте ctrl+Scroll Lock в WinDBg, чтобы разорвать код, запущенный в целевой системе. Для реагирования целевой системы может потребоваться некоторое время.

    Главный экран в отладчике с выходными данными командного окна из динамического подключения к ядру.

  2. Введите следующую команду, чтобы включить DML в окне команды отладчика:

    0: kd> .prefer_dml 1
    DML versions of commands on by default
    
  3. С помощью команды можно получить доступ к справочной команде .hh . Введите следующую команду, чтобы просмотреть справку по ссылке на команду:.prefer_dml

    0: kd> .hh .prefer_dml
    

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

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

  4. Чтобы отобразить подробные сведения о версии целевой системы, введите команду 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
    
  5. Чтобы убедиться, что вы работаете с правильным процессом в режиме ядра, введите команду 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
    ...
    

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

  6. Чтобы запросить подробные сведения о конкретном модуле, используйте 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, выполните следующие действия.

  1. Скачайте и извлеките пример эхо KMDF из GitHub.

    Пример "Эхо KMDF" находится в общей папке.

    Снимок экрана: страница GitHub windows-driver-samples, в котором выделена общая папка и кнопка скачивания ZIP.

    1. Скачайте примеры драйверов в одном ZIP-файле: примеры драйверов

    2. Скачайте ZIP-файл на локальный жесткий диск.

    3. Выберите и удерживайте или щелкните правой кнопкой мыши ZIP-файл и выберите "Извлечь все". Укажите новую папку или перейдите к существующей, чтобы сохранить извлеченные файлы. Например, можно указать C:\DriverSamples\ в качестве новой папки, в которую необходимо извлечь файлы.

    4. После извлечения файлов перейдите в следующую вложенную папку: C:\DriverSamples\general\echo\kmdf

  2. В Microsoft Visual Studio выберите >файл Open>Project/Solution... и перейдите в папку, содержащую извлеченные файлы, например C:\DriverSamples\general\echo\kmdf. Дважды щелкните файл решения kmdfecho , чтобы открыть его.

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

    Снимок экрана: Visual Studio, отображающий файл device.c, загруженный из проекта kmdfecho.

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

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

  5. Задайте библиотеку среды выполнения. Откройте страницу свойств эхо-драйвера и найдите создание кода C/C++>. Измените библиотеку среды выполнения на многопоточную отладку (/MTd). Дополнительные сведения о параметрах сборки см. в разделе /MD, /MT, /LD (использование библиотеки времени выполнения).

    Снимок экрана: страница свойства эхо в Visual Studio, в котором выделен параметр библиотеки среды выполнения.

  6. В свойствах драйвера убедитесь, что для режима подписи>драйвера заданозначение Test Sign.

    Снимок экрана: страница свойств эхо в Visual Studio, в котором выделен параметр режима подписи.

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

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

Совет

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

  1. В проводник перейдите в папку, содержащую извлеченные файлы для примера. Например, перейдите в папку 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.
  2. Найдите USB-диск или настройте сетевую папку для копирования встроенных файлов драйверов и тестового EchoApp из узла в целевую систему.

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

Установка примера эхо-драйвера KMDF в целевой системе

В этом разделе используйте средство DevCon для установки примера эхо-драйвера.

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

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

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

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

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

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

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

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

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

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

  6. Перезапустите целевой компьютер.

В системе узла перейдите в папку 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.

На целевом компьютере откройте окно командной строки как Администратор istrator. Перейдите в папку пакета драйвера и введите следующую команду:

devcon install echo.inf root\ECHO

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

c:\tools\devcon install echo.inf root\ECHO

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

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

Совет

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

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

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

Снимок экрана: дерево диспетчер устройств, в котором выделен пример эхо-драйвера 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.

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

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

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

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

    0: kd> .symfix
    
  4. Чтобы добавить расположение локального символа для использования локальных символов, добавьте путь с помощью .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
  1. Введите следующую команду в области команд отладчика, чтобы отобразить сведения о драйвере эхо:

    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.

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

    0: kd> x /D Echo!a*
    
  3. Пример эхо не содержит символов, начинающихся с буквы "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 (Проверка символов).

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

    0: kd> !lmi echo
    Loaded Module Info: [echo] 
             Module: ECHO
       Base Address: fffff8010bf94000
         Image Name: ECHO.sys
    … 
    
  5. Используйте расширение для отображения сведений !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
    ...
    
  6. Введите следующую команду, чтобы изменить маску битовой отладки по умолчанию, чтобы все отладочные сообщения из целевой системы отображались в отладчике:

    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.

  1. Чтобы просмотреть все узлы устройства в дереве устройств самонастраивающийся, введите !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…
    …
    
  2. Используйте CTRL+F для поиска в выходных данных, созданных для поиска имени драйвера устройства, эхо.

    Снимок экрана: диалоговое окно

  3. Необходимо загрузить драйвер эхо-устройства. !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)
    …
    
  4. Выходные данные, отображаемые в предыдущей команде, включают 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.
    
  5. Выходные данные, отображаемые в команде !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

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

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

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

Работа с точками останова и исходным кодом

В этом разделе задайте точки останова и одношаговый исходный код в режиме ядра.

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

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

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

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

Дополнительные сведения см. в статье отладка исходного кода в WinDbg.

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

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

    .srcpath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
    
  3. Введите следующую команду, чтобы добавить расположение локального символа в путь к символу:

    .sympath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
    
  4. x Используйте команду для проверки символов, связанных с драйвером эхо, чтобы определить имя функции, используемое для точки останова. Для поиска DeviceAdd имени функции можно использовать wild карта или 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

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

  5. Задайте точку останова с bm помощью команды, используя имя драйвера, за которым следует имя функции, например AddDevice, где нужно задать точку останова, разделенную восклицательным знаком. Эта лаборатория используется AddDevice для просмотра загрузки драйвера.

    0: kd> bm ECHO!EchoEvtDeviceAdd
      1: fffff801`0bf9b1c0 @!"ECHO!EchoEvtDeviceAdd"
    

    Вы можете использовать другой синтаксис в сочетании с параметрами переменных, например <module>!<symbol>, <class>::<method>'<file.cpp>:<line number>'или пропустить несколько раз<condition> <#>. Дополнительные сведения см. в разделе "Условные точки останова" в WinDbg и других отладчиках Windows.

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

    0: kd> bl
    1 e fffff801`0bf9b1c0     0001 (0001) ECHO!EchoEvtDeviceAdd
    

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

  7. Перезапустите выполнение кода в целевой системе, введя g команду (go).

  8. В целевой системе в Windows откройте диспетчер устройств с помощью значка или ввода mmc devmgmt.msc. В диспетчер устройств разверните узел Samples.

  9. Выберите и удерживайте или щелкните правой кнопкой мыши запись эхо-драйвера KMDF и выберите "Отключить " в меню.

  10. Выберите и удерживайте или удерживайте правой кнопкой мыши запись эхо-драйвера KMDF и выберите "Включить " в меню.

  11. В системе узла, когда драйвер включен, точка останова отладки AddDevice должна запускаться. Выполнение кода драйвера в целевой системе должно быть остановлено. При нажатии точки останова выполнение должно быть остановлено в начале подпрограммы AddDevice . Отображается вывод команды отладки Breakpoint 1 hit.

    Снимок экрана: WinDbg с примерами локальных и командных окон кода.

  12. Шаг по строке кода, введя p команду или нажав клавишу F10, пока не достигнет следующего конца подпрограммы AddDevice . Символ фигурной скобки (}) выделен, как показано ниже.

    Снимок экрана: окно кода с символом фигурной скобки, выделенным в начале подпрограммы 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 с помощью описанного выше процесса. Чтобы просмотреть выходные данные, показанные здесь, повторите описанные ранее действия при необходимости.

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

Снимок экрана: WinDbg, отображающий окно локальных переменных.

Чтобы найти расположение глобальной переменной, введите ? <variable name>.

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

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

Раздел 8. Просмотр переменных и стеков вызовов

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

В этой лаборатории предполагается, что вы остановлены в подпрограмме AddDevice с помощью описанного выше процесса. Чтобы просмотреть выходные данные, повторите описанные ранее действия при необходимости.

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

Отображение переменных

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

Снимок экрана: WinDbg, отображающий окно локальных переменных.

Глобальные переменные

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

Локальные переменные

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

0: kd> dv
         Driver = 0x00001fff`7ff9c838
     DeviceInit = 0xffffd001`51978190
         status = 0n0

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

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

Команда Description
kb Отображает стек и первые три параметра.
kp Отображает стеки и полный список параметров.
kn Позволяет увидеть стек с информацией кадра рядом с ним.
  1. В системе узла, если вы хотите сохранить стек вызовов, выберите стек вызовов представления, чтобы просмотреть>его. Выберите столбцы в верхней части окна, чтобы переключить отображение дополнительных сведений.

    Снимок экрана: WinDbg с окном стека вызовов.

  2. 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 . Задайте точку останова для изучения процесса, используемого при воспроизведении звука.

  1. В системе узла введите dv команду для проверки переменных языкового стандарта, связанных с подпрограммой EchoEvtIo :

    0: kd> dv ECHO!EchoEvtIo*
    ECHO!EchoEvtIoQueueContextDestroy
    ECHO!EchoEvtIoWrite
    ECHO!EchoEvtIoRead         
    
  2. Снимите предыдущие точки останова с помощью bc *:

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

    0: kd> bm ECHO!EchoEvtIo*
      2: aade5490          @!”ECHO!EchoEvtIoQueueContextDestroy”
      3: aade55d0          @!”ECHO!EchoEvtIoWrite”
      4: aade54c0          @!”ECHO!EchoEvtIoRead”
    
  4. Выведите список точек останова, чтобы убедиться, что точка останова задана правильно:

    0: kd> bl
    1 e aabf0490 [c:\Samples\kmdf echo sample\c++\driver\autosync\queue.c @ 197]    0001 (0001) ECHO!EchoEvtIoQueueContextDestroy
    ...
    
  5. Введите g для перезапуска выполнения кода:

    0: kd> g
    
  6. В целевой системе запустите тестовую EchoApp.exe программу драйвера в целевой системе.

  7. При запуске тестового приложения в системе узла вызывается подпрограмма ввода-вывода в драйвере. Этот вызов приводит к срабатыванию точки останова и выполнению кода драйвера в целевой системе останавливается.

    Breakpoint 2 hit
    ECHO!EchoEvtIoWrite:
    fffff801`0bf95810 4c89442418      mov     qword ptr [rsp+18h],r8
    
  8. !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.

  9. !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
    
    ...
    
  10. Запишите идентификатор процесса, связанный с echoapp.exe для использования позже в этой лаборатории. Вы также можете скопировать адрес в буфер копирования для последующего использования с помощью CTRL+C.

    адрес процесса _____________________________________________________(echoapp.exe)

  11. Введите g отладчик по мере необходимости, чтобы запустить код вперед, пока echoapp.exe не завершит работу. Он попадает в точку останова в событии чтения и записи много раз. Когда echoapp.exe завершится, войдите в отладчик, нажав клавиши CTRL+ScrLk (CTRL+Break).

  12. !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 выполняется при остановке ОС.

  13. !process Используйте команду, чтобы попытаться просмотреть идентификатор процесса, связанный с echoapp.exe, записанной ранее. Укажите адрес процесса echoapp.exe, записанный ранее, вместо примера адреса процесса, показанного в этом примере.

    0: kd> !process ffffe0007e6a7780
    TYPE mismatch for process object at 82a9acc0
    

    Объект процесса больше недоступен, так как процесс echoapp.exe больше не выполняется.

Потоки

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

  1. В системе узла введите g отладчик, чтобы перезапустить выполнение кода в целевой системе.

  2. В целевой системе запустите тестовую программу EchoApp.exe драйвера.

  3. В системе узла точка останова останавливается, а выполнение кода останавливается.

    Breakpoint 4 hit
    ECHO!EchoEvtIoRead:
    aade54c0 55              push    ebp
    
  4. Чтобы просмотреть выполняемые потоки, введите !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. Это означает, что вы просматриваете поток, связанный с тестируемым приложением.

  5. !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
    
  6. !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.

  7. Используйте команду для перечисления сведений !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
    ...
    
  8. Запишите первый адрес потока, связанный с двумя процессами.

    Cmd.exe:____________________________________________________

    EchoApp.exe: _________________________________________________

  9. !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 и находится в состоянии выполнения.

  10. Используйте команду для отображения сведений о потоке !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 и находится в состоянии ожидания.

  11. Укажите адрес потока ожидания CMD.exe потока, чтобы изменить контекст на этот поток ожидания.

    0: kd> .Thread ffffe0007cf34880
    Implicit thread is now ffffe000`7cf34880
    
  12. 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.

См. также