Laboratoire de débogage pas à pas des pilotes Windows (écho en mode noyau)
Ce laboratoire présente le débogueur de noyau WinDbg. Vous utilisez WinDbg pour déboguer le code source du pilote d’écho en mode noyau.
Objectifs du labo
Ce laboratoire comprend des exercices qui présentent les outils de débogage, enseignent les commandes de débogage courantes, illustrent l’utilisation des points d’arrêt et montrent comment utiliser les extensions de débogage.
Dans ce laboratoire, vous utilisez une connexion de débogage de noyau en direct pour explorer les actions suivantes :
- Utiliser les commandes du débogueur Windows
- Utiliser des commandes standard (piles d’appels, variables, threads, IRQL)
- Utiliser des commandes de débogage de pilote avancées (!commands)
- Utiliser des symboles
- Définir des points d’arrêt en débogage en direct
- Afficher les piles d’appels
- Afficher l’arbre des périphériques Plug and Play
- Travailler avec le contexte des threads et des processus
Débogage en mode utilisateur et en mode noyau
Lorsque vous travaillez avec le débogueur Windows, vous pouvez effectuer deux types de débogage :
Mode utilisateur : Les applications et sous-systèmes s’exécutent sur l’ordinateur en mode utilisateur. Les processus qui s’exécutent en mode utilisateur le font dans leurs propres espaces d’adresse virtuels. Ils ne peuvent pas accéder directement à de nombreuses parties du système, comme le matériel système, la mémoire qui n’est pas allouée à leur utilisation, et d’autres parties du système qui pourraient compromettre l’intégrité du système. Étant donné que les processus qui s’exécutent en mode utilisateur sont isolés du système et des autres processus en mode utilisateur, ils ne peuvent pas interférer avec ces ressources.
Mode noyau : Le système d’exploitation et les programmes privilégiés s’exécutent en mode noyau. Le code en mode noyau a l’autorisation d’accéder à n’importe quelle partie du système. Il n’est pas restreint comme le code en mode utilisateur. Il peut accéder à n’importe quelle partie de tout autre processus en cours d’exécution en mode utilisateur ou en mode noyau. Une grande partie de la fonctionnalité de base du système d’exploitation et de nombreux pilotes de périphérique s’exécutent en mode noyau.
Cet exercice couvre les commandes de débogage fréquemment utilisées lors du débogage en mode utilisateur et en mode noyau. L’exercice couvre également les extensions de débogage, parfois appelées !commands « bang », qui sont utilisées pour le débogage en mode noyau.
Configuration du laboratoire
Vous avez besoin du matériel suivant pour terminer le laboratoire :
- Un ordinateur portable ou de bureau (hôte) exécutant Windows 10
- Un deuxième ordinateur portable ou de bureau (cible) exécutant Windows 10
- Un hub ou un routeur et des câbles réseau pour connecter les deux ordinateurs
- Un accès à Internet pour télécharger des fichiers de symboles
Vous avez besoin du logiciel suivant pour terminer le laboratoire :
- Visual Studio
- Kit de développement logiciel (SDK) Windows pour Windows 10
- Kit de développement de pilotes Windows (WDK) pour Windows 10
- Le pilote d’écho d’exemple pour Windows 10
Le laboratoire comprend les sections suivantes :
- Connexion à une session de débogage de noyau WinDbg
- Commandes et techniques de débogage en mode noyau
- Télécharger et compiler le pilote d’écho KMDF
- Installer l’exemple de pilote d’écho sur le système cible
- Utiliser WinDbg pour afficher des informations sur le pilote
- Afficher des informations sur l’arbre des périphériques Plug and Play
- Travailler avec des points d’arrêt et du code source
- Afficher des variables et des piles d’appels
- Afficher des processus et des threads
- IRQL, registres et fin de la session WinDbg
- Ressources de débogage Windows
Connexion à une session de débogage de noyau WinDbg
Dans cette section, configurez le débogage réseau sur le système hôte et cible.
Les ordinateurs de ce laboratoire doivent être configurés pour utiliser une connexion réseau Ethernet pour le débogage en mode noyau.
Ce laboratoire utilise deux ordinateurs. Le débogueur Windows s’exécute sur le système hôte et le pilote d’écho Framework du mode noyau (KMDF) s’exécute sur le système cible.
Utilisez un concentrateur réseau ou un routeur et des câbles réseau pour connecter les deux ordinateurs.
Pour travailler avec des applications en mode noyau et utiliser WinDbg, nous vous recommandons d’utiliser le transport KDNET sur Ethernet. Pour plus d’informations sur l’utilisation du protocole de transport Ethernet, veuillez consulter la rubrique Bien démarrer avec WinDbg (mode noyau). Pour plus d’informations sur la configuration de l’ordinateur cible, veuillez consulter la rubrique Préparer un ordinateur pour le déploiement manuel du pilote et Configurer automatiquement le débogage du noyau réseau KDNET.
Configurez le débogage en mode noyau en utilisant l’Ethernet
Pour activer le débogage en mode noyau sur le système cible :
Sur le système hôte, ouvrez une fenêtre d’invite de commandes et saisissez ipconfig pour déterminer son adresse 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 . . . . . . . . . :
Enregistrez l’adresse IP du système hôte : ______________________________________
Sur le système cible, ouvrez une fenêtre d’invite de commandes et utilisez la commande
ping
pour confirmer la connectivité réseau entre les deux systèmes.ping 169.182.1.1
Utilisez l’adresse IP réelle du système hôte que vous avez enregistrée au lieu de 169.182.1.1 qui est affichée dans la sortie d’exemple.
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
Activez le débogage en mode noyau sur le système cible en effectuant les étapes suivantes.
Important
Avant d’utiliser BCDEdit pour modifier les informations de démarrage, vous devrez peut-être suspendre temporairement les fonctionnalités de sécurité de Windows telles que BitLocker et Secure Boot sur l’ordinateur de test. Réactivez ces fonctionnalités de sécurité lorsque le test est terminé. Gérez correctement l’ordinateur de test lorsque les fonctionnalités de sécurité sont désactivées. Le démarrage sécurisé est généralement désactivé dans l’UEFI. Pour accéder aux paramètres de l’UEFI, utilisez Système, Récupération, Démarrage avancé. Au redémarrage, sélectionnez Dépannage, Options avancées, Paramètres du microprogramme UEFI. Faites preuve de prudence, car la définition incorrecte des options de l’UEFI ou la désactivation de BitLocker peuvent rendre le système inopérable.
Sur l’ordinateur cible, ouvrez une fenêtre d’invite de commande en tant qu’administrateur. Saisissez cette commande pour activer le débogage :
bcdedit /set {default} DEBUG YES
Saisissez cette commande pour activer la signature de test :
bcdedit /set TESTSIGNING ON
Saisissez cette commande pour définir l’adresse IP du système hôte. Utilisez l’adresse IP du système hôte que vous avez enregistrée précédemment, pas celle affichée.
bcdedit /dbgsettings net hostip:192.168.1.1 port:50000 key:2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Avertissement
Pour renforcer la sécurité de la connexion et réduire le risque des demandes de connexion au débogueur client aléatoires, utilisez une clé aléatoire générée automatiquement. Pour plus d’informations, consultez la rubrique Configuration automatique du débogage réseau du noyau KDNET.
Saisissez cette commande pour confirmer que les valeurs de
dbgsettings
sont correctement définies :bcdedit /dbgsettings
key 2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p debugtype NET hostip 169.168.1.1 port 50000 dhcp Yes The operation completed successfully.
Remarque
Si vous recevez un message du pare-feu et que vous souhaitez utiliser le débogueur, sélectionnez les trois cases.
Sur l’ordinateur hôte, ouvrez une fenêtre d’invite de commandes en tant qu’administrateur. Ce laboratoire utilise la version x64 de WinDbg.exe du Kit de développement de pilotes Windows (WDK) qui a été installée dans le cadre de l’installation du kit Windows. Rendez-vous dans le répertoire WinDbg par défaut, l’emplacement par défaut est indiqué ci-dessous.
cd C:\Program Files(x86)\Windows Kits\10\Debuggers\x64
Ce laboratoire suppose que les deux ordinateurs exécutent une version 64 bits de Windows à la fois sur la cible et sur l’hôte. Si ce n’est pas le cas, la meilleure approche est d’exécuter la même architecture d’outils sur l’hôte que sur la cible. Par exemple, si la cible exécute Windows 32 bits, exécutez une version 32 bits du débogueur sur l’hôte. Pour plus d’informations, veuillez consulter la rubrique Choisir les outils de débogage 32 bits ou 64 bits.
Ouvrez WinDbg avec le débogage utilisateur à distance en utilisant la commande suivante. Les valeurs de la clé et du port correspondent aux valeurs que vous avez définies précédemment à l’aide de BCDEdit sur l’ordinateur cible.
WinDbg –k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Redémarrez le système cible.
En une minute ou deux, les sorties de débogage devraient s’afficher sur le système hôte.
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
La fenêtre de commande du débogueur est la principale fenêtre d’information de débogage dans WinDbg. Vous pouvez saisir des commandes de débogueur et afficher la sortie de commande dans cette fenêtre.
La fenêtre de commande du débogueur est divisée en deux panneaux. Saisissez les commandes dans le petit panneau, qui est le panneau de saisie de commande en bas de la fenêtre, et affichez la sortie de la commande dans le grand panneau en haut de la fenêtre.
Dans le panneau de saisie de commande, utilisez les touches de flèche Haut et Bas pour faire défiler l’historique des commandes. Lorsqu’une commande apparaît, vous pouvez la modifier ou appuyer sur Entrée pour exécuter la commande.
Commandes et techniques de débogage en mode noyau
Dans cette section, utilisez des commandes de débogage pour afficher des informations sur le système cible.
Certaines commandes de débogage affichent du texte en utilisant le langage de balisage de débogueur (DML) que vous pouvez sélectionner pour rassembler rapidement plus d’informations.
Sur le système hôte, utilisez Ctrl+Verrouillage défil pour interrompre le code en cours d’exécution sur le système cible. Il peut falloir un certain temps pour que le système cible réponde.
Entrez la commande suivante pour activer DML dans la fenêtre de commande du débogueur :
0: kd> .prefer_dml 1 DML versions of commands on by default
Vous pouvez accéder à l’aide des commandes de référence en utilisant la commande
.hh
. Entrez la commande suivante pour afficher l’aide de référence des commandes.prefer_dml
:0: kd> .hh .prefer_dml
Le fichier d’aide du débogueur affiche l’aide de la commande
.prefer_dml
.Pour afficher des informations détaillées sur la version sur le système cible, entrez la commande vertarget (Afficher la version de l’ordinateur cible) dans la fenêtre 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
Pour vérifier que vous travaillez avec le processus en mode noyau correct, entrez la commande lm (Liste des modules chargés) dans la fenêtre WinDbg pour afficher les modules chargés :
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 ...
La sortie qui a été omise est indiquée par « … » dans ce laboratoire.
Pour demander des informations détaillées sur un module spécifique, utilisez l’option
v
(verbose) :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
Il n’y a pas de chemin de symbole défini et de symboles chargés, donc des informations limitées sont disponibles dans le débogueur.
Télécharger et compiler le pilote d’écho KMDF
Dans cette section, téléchargez et créez le pilote d’écho KMDF.
Généralement, vous travailleriez avec votre propre code de pilote lorsque vous utilisez WinDbg. Pour vous familiariser avec le fonctionnement de WinDbg, ce laboratoire utilise le modèle KMDF « Echo » de l’échantillon de pilote. Le code source est disponible pour aider à comprendre les informations affichées dans WinDbg. Cet exemple est également utilisé pour illustrer comment vous pouvez procéder étape par étape à travers le code en mode noyau natif. Cette technique peut être précieuse pour le débogage de problèmes de code en mode noyau complexes.
Pour télécharger et créer le pilote d’écho KMDF :
Téléchargez et extrayez l’échantillon Echo KMDF depuis GitHub.
Consultez l’échantillon echo sur GitHub.
Lisez ce qui concerne l’échantillon.
Parcourez tous les échantillons de pilotes Windows.
L’échantillon Echo KMDF est situé dans le dossier general.
Téléchargez les échantillons de pilotes dans un fichier zip : Échantillons de pilotes
Téléchargez le fichier zip sur votre disque dur local.
Sélectionnez et maintenez ou cliquez avec le bouton droit sur le fichier zip, puis sélectionnez Extraire tout. Spécifiez un nouveau dossier ou accédez à un dossier existant pour stocker les fichiers extraits. Par exemple, vous pourriez spécifier C:\DriverSamples\ comme nouveau dossier dans lequel extraire les fichiers.
Après l’extraction des fichiers, accédez au sous-dossier suivant : C:\DriverSamples\general\echo\kmdf
Dans Microsoft Visual Studio, sélectionnez Fichier>Ouvrir>Projet/Solution... et rendez-vous dans le dossier contenant les fichiers extraits, par exemple, C:\DriverSamples\general\echo\kmdf. Double-cliquez sur le fichier de solution kmdfecho pour l’ouvrir.
Dans Visual Studio, localisez l’Explorateur de solutions. Si cette fenêtre n’est pas déjà ouverte, sélectionnez Explorateur de solutions dans le menu Affichage (View). Dans l’Explorateur de solutions, vous pouvez voir une solution qui contient trois projets.
Configurez la configuration et la plate-forme de l’échantillon. Dans l’Explorateur de solutions, sélectionnez et maintenez ou faites un clic droit sur Solution ’kmdfecho’ (3 projets), puis sélectionnez Gestionnaire de configuration. Assurez-vous que les paramètres de configuration et de plate-forme sont les mêmes pour les trois projets. Par défaut, la configuration est définie sur Win10 Debug, et la plate-forme est définie sur Win64 pour tous les projets. Si vous apportez des modifications de configuration ou de plate-forme à un projet, apportez les mêmes modifications aux trois autres projets.
Les échantillons de pilotes doivent être modifiés pour utiliser des valeurs qui ne chevauchent pas les pilotes existants. Consultez De l’exemple de code au pilote de production - Ce qu’il faut changer dans les exemples pour connaître la façon de créer un échantillon de pilote unique qui coexistera avec les pilotes réels existants installés dans Windows.
Configurez la bibliothèque d’exécution. Ouvrez la page des propriétés du pilote d’écho et localisez C/C++>Génération de code. Modifiez la bibliothèque d’exécution en Multithreaded Debug (/MTd). Pour plus d’informations sur les options de génération, consultez /MD, /MT, /LD (Utiliser la bibliothèque d’exécution).
Dans les propriétés du pilote, assurez-vous que Signature du pilote>Mode de signature est paramétré sur Signature de test.
Dans Visual Studio, sélectionnez Build>Build Solution.
La fenêtre de build devrait afficher un message indiquant que la build pour les trois projets a réussi.
Conseil
Si vous rencontrez un message d’erreur de build, utilisez le numéro d’erreur de build pour déterminer une solution. Par exemple, Erreur MSBuild MSB8040 décrit comment travailler avec des bibliothèques atténuées par spectre.
Dans l’Explorateur de fichiers, accédez au dossier contenant les fichiers extraits pour l’échantillon. Par exemple, allez dans C:\DriverSamples\general\echo\kmdf, si c’est le dossier que vous avez spécifié précédemment. Dans ce dossier, l’emplacement des fichiers du pilote compilé varie en fonction des paramètres de configuration et de plate-forme que vous avez sélectionnés dans le Gestionnaire de configuration. Si vous n’avez pas modifié les paramètres par défaut, alors les fichiers du pilote compilé sont enregistrés dans un dossier nommé \x64\Debug pour une build de débogage 64 bits.
Accédez au dossier contenant les fichiers construits pour le pilote Autosync : C:\DriverSamples\general\echo\kmdf\driver\AutoSync\x64\Debug.
Le dossier devrait contenir ces fichiers :
Fichier Description Echo.sys Le fichier pilote. Echo.inf Un fichier d’informations (INF) qui contient les informations nécessaires pour installer le pilote. De plus, le fichier echoapp.exe a été construit et il devrait être situé ici : C:\DriverSamples\general\echo\kmdf\exe\x64\Debug.
Fichier Description EchoApp.exe Un fichier exécutable d’invite de commandes de test qui communique avec le pilote echo.sys. Localisez une clé USB ou configurez un partage réseau pour copier les fichiers de pilote construits et le test EchoApp de l’hôte vers le système cible.
Dans la section suivante, copiez le code sur le système cible, et installez et testez le pilote.
Installer l’échantillon de pilote d’écho KMDF sur le système cible
Dans cette section, utilisez l’outil DevCon pour installer l’échantillon de pilote d’écho.
L’ordinateur sur lequel vous installez le pilote est appelé l’ordinateur cible ou l’ordinateur de test. Généralement, cet ordinateur est distinct de l’ordinateur sur lequel vous développez et construisez le package de pilotes. L’ordinateur sur lequel vous développez et construisez le pilote est appelé l’ordinateur hôte.
Le processus de déplacement du package de pilotes vers l’ordinateur cible et l’installation du pilote est appelé déploiement du pilote.
Avant de déployer un pilote signé pour les tests, préparez l’ordinateur cible en activant la signature des tests. Vous devez également localiser l’outil DevCon dans votre installation du WDK et le copier sur le système cible.
Pour installer le pilote sur le système cible, suivez les étapes suivantes.
Sur le système cible, activez les pilotes signés pour les tests :
Ouvrez Paramètres Windows.
Dans Mise à jour et sécurité, sélectionnez Récupération.
Sous Démarrage avancé, sélectionnez Redémarrer Maintenant.
Lorsque l’ordinateur redémarre, sélectionnez Options de démarrage. Sous Windows 10, sélectionnez Dépannage>Options avancées>Paramètres de démarrage, puis sélectionnez Redémarrer.
Sélectionnez Désactiver l’application de signature de pilote en appuyant sur la touche F7.
Redémarrer l’ordinateur cible.
Sur le système hôte, accédez au dossier Outils de votre installation du WDK et localisez l’outil DevCon. Par exemple, regardez dans le dossier suivant : C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe.
Créez un dossier sur la cible pour le package de pilote construit, par exemple, C:\PiloteEcho. Copiez devcon.exe vers le système cible. Localisez le certificat .cer sur le système hôte. Il se trouve dans le même dossier sur l’ordinateur hôte dans le dossier contenant les fichiers de pilote construits. Copiez tous les fichiers du pilote construit décrits précédemment sur l’ordinateur hôte et enregistrez-les dans le même dossier que vous avez créé sur l’ordinateur cible.
Sur l’ordinateur cible, sélectionnez et maintenez ou cliquez avec le bouton droit sur le fichier de certificat, puis sélectionnez Installer, puis suivez les invites pour installer le certificat de test.
Si vous avez besoin d’instructions plus détaillées pour configurer l’ordinateur cible, consultez Préparation d’un ordinateur pour le déploiement manuel de pilotes.
Les instructions suivantes vous montrent comment installer et tester le pilote d’échantillon. Voici la syntaxe générale pour l’outil devcon que vous utilisez pour installer le pilote :
devcon install <INF file> <hardware ID>
Le fichier INF requis pour installer ce pilote est echo.inf. Le fichier inf contient l’ID matériel pour installer le echo.sys. Pour l’échantillon d’écho, l’ID matériel est root\ECHO.
Sur l’ordinateur cible, ouvrez une fenêtre d’invite de commande en tant qu’administrateur. Rendez-vous dans votre dossier de package de pilotes, et entrez la commande suivante :
devcon install echo.inf root\ECHO
Si vous obtenez un message d’erreur concernant devcon n’étant pas reconnu, essayez d’ajouter le chemin de l’outil devcon. Par exemple, si vous l’avez copié dans un dossier appelé C:\Outils, essayez d’utiliser la commande suivante :
c:\tools\devcon install echo.inf root\ECHO
Une boîte de dialogue apparaît indiquant que le pilote de test est un pilote non signé. Sélectionnez Installer ce pilote quand même pour continuer.
Conseil
Si vous rencontrez des problèmes avec l’installation, vérifiez le fichier suivant pour plus d’informations. %windir%\inf\setupapi.dev.log
Après avoir installé avec succès le pilote d’échantillon, vous êtes prêt à le tester.
Sur l’ordinateur cible, dans une fenêtre d’invite de commandes, saisissez devmgmt pour ouvrir le Gestionnaire de périphériques. Dans Gestionnaire de périphériques, dans le menu Affichage, choisissez Appareils par type. Dans l’arborescence de l’appareil, recherchez Exemple de pilote Echo WDF dans le nœud d’exemple d’appareil.
Entrez echoapp pour démarrer l’application d’écho de test pour confirmer que le pilote est fonctionnel.
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
Utiliser WinDbg pour afficher des informations sur le pilote
Dans cette section, définissez le chemin du symbole et utilisez les commandes du débogueur du noyau pour afficher des informations sur le pilote d’exemple d’écho KMDF.
Pour afficher des informations sur le pilote :
Sur le système hôte, si vous avez fermé le débogueur, ouvrez-le à nouveau à l’aide de la commande suivante dans la fenêtre d’invite de commandes administrateur.
WinDbg -k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Utilisez Ctrl+Arrêt (verrouillage de défilement) pour entrer dans le code en cours d’exécution sur le système cible.
Pour définir le chemin des symboles sur le serveur de symboles Microsoft dans l’environnement WinDbg, utilisez la commande
.symfix
.0: kd> .symfix
Pour ajouter votre emplacement de symbole local pour utiliser vos symboles locaux, ajoutez le chemin d’accès en utilisant
.sympath+
puis.reload /f
.0: kd> .sympath+ C:\DriverSamples\general\echo\kmdf 0: kd> .reload /f
La commande
.reload
avec l’option/f
force supprime toutes les informations de symbole pour le module spécifié et recharge les symboles. Dans certains cas, cette commande recharge ou décharge également le module lui-même.
Vous devez charger les symboles appropriés pour utiliser les fonctionnalités avancées fournies par WinDbg. Si vous n’avez pas configuré correctement les symboles, lorsque vous tentez d’utiliser des fonctionnalités qui dépendent des symboles, vous recevez des messages indiquant que les symboles ne sont pas disponibles.
0:000> dv
Unable to enumerate locals, HRESULT 0x80004005
Private symbols (symbols.pri) are required for locals.
Type “.hh dbgerr005” for details.
Il existe de nombreuses approches qui peuvent être utilisées pour travailler avec les symboles. Dans de nombreuses situations, vous pouvez configurer l’ordinateur pour accéder aux symboles à partir d’un serveur de symboles que Microsoft fournit lorsque cela est nécessaire. Ce laboratoire utilise cette approche. Si les symboles dans votre environnement sont à un emplacement différent, modifiez les étapes pour utiliser cet emplacement. Pour plus d’informations, veuillez consulter la rubrique Chemin des symboles pour le débogueur Windows.
Pour effectuer un débogage de source, vous devez construire une version vérifiée (débogage) de vos binaires. Le compilateur crée des fichiers de symboles (.pdb). Ces fichiers de symboles montrent au débogueur comment les instructions binaires correspondent aux lignes de code source. Les fichiers source eux-mêmes doivent également être accessibles au débogueur.
Les fichiers de symboles ne contiennent pas le texte du code source. Pour le débogage, il est préférable que le lien n’optimise pas votre code. Le débogage de source et l’accès aux variables locales sont plus difficiles, voire parfois presque impossibles, si le code a été optimisé. Si vous rencontrez des problèmes pour afficher les variables locales ou les lignes de code source, configurez les options de construction suivantes :
set COMPILE_DEBUG=1
set ENABLE_OPTIMIZER=0
Entrez la commande suivante dans la zone de commande du débogueur pour afficher des informations sur le pilote echo :
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 ...
Pour plus d’informations, voir lm.
Parce que ce laboratoire a défini
prefer_dml
précédemment, certains éléments de la sortie sont des liens hypertexte que vous pouvez sélectionner. Sélectionnez le lien Parcourir tous les symboles globaux dans la sortie de débogage pour afficher des informations sur les symboles qui commencent par la lettre « a ».0: kd> x /D Echo!a*
L’échantillon d’écho ne contient aucun symbole qui commence par la lettre « a », donc saisissez
x ECHO!Echo*
pour afficher des informations sur tous les symboles associés au pilote echo qui commencent par « 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__ *) ...
Pour plus d’informations, veuillez consulter la section x (Examiner les symboles).
L’extension
!lmi
affiche des informations détaillées sur un module. Saisissez!lmi echo
. Votre sortie devrait être similaire au texte montré dans cet exemple :0: kd> !lmi echo Loaded Module Info: [echo] Module: ECHO Base Address: fffff8010bf94000 Image Name: ECHO.sys …
Utilisez l’extension
!dh
pour afficher les informations d’en-tête comme indiqué dans cet exemple :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 ...
Entrez la commande suivante pour modifier le masque de débogage par défaut afin que tous les messages de débogage du système cible soient affichés dans le débogueur :
0: kd> ed nt!Kd_DEFAULT_MASK 0xFFFFFFFF
Certains pilotes affichent des informations supplémentaires lorsque le masque de 0xFFFFFFFF est utilisé. Définissez le masque sur 0x00000000 si vous souhaitez réduire la quantité d’informations affichées.
0: kd> ed nt!Kd_DEFAULT_MASK 0x00000000
Utilisez la commande
dd
pour confirmer que le masque est défini pour afficher tous les messages du débogueur.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
Afficher des informations sur l’arbre des périphériques Plug and Play
Dans cette section, affichez des informations sur le pilote de périphérique d’échantillon echo et l’endroit où il se trouve dans l’arbre des périphériques Plug and Play.
Les informations sur le pilote de périphérique dans l’arbre des périphériques Plug and Play peuvent être utiles pour le dépannage. Par exemple, si un pilote de périphérique n’est pas résident dans l’arbre des périphériques, il peut y avoir un problème avec l’installation du pilote de périphérique.
Pour plus d’informations sur l’extension de débogage du nœud de périphérique, veuillez consulter la section !devnode.
Sur le système hôte, pour voir tous les nœuds de périphériques dans l’arbre des périphériques Plug and Play, entrez la commande
!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… …
Utilisez Ctrl+F pour rechercher dans la sortie générée le nom du pilote de périphérique, echo.
Le pilote de périphérique echo devrait être chargé. Utilisez la commande
!devnode 0 1 echo
pour afficher les informations Plug and Play associées à votre pilote de périphérique echo comme indiqué dans cet exemple :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) …
La sortie affichée dans la commande précédente comprend le PDO associé à l’instance en cours d’exécution de votre pilote, dans cet exemple, 0xffffe0007b71a960. Entrez la commande
!devobj <PDO address>
pour afficher les informations Plug and Play associées au pilote de périphérique echo. Utilisez l’adresse PDO que!devnode
affiche sur votre ordinateur, pas celle montrée ici.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.
La sortie affichée dans la commande
!devnode 0 1
comprend l’adresse PDO associée à l’instance en cours d’exécution de votre pilote, dans cet exemple c’est 0xffffe0007b71a960. Entrez la commande!devstack <PDO address>
pour afficher les informations Plug and Play associées au pilote de périphérique. Utilisez l’adresse PDO que!devnode
affiche sur votre ordinateur, pas celle montrée dans cet exemple.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"
La sortie montre que vous avez un empilement de pilotes de périphériques assez simple. Le pilote echo est un enfant du nœud PnPManager. PnPManager est un nœud racine.
\Driver\ECHO
\Driver\PnpManager
Ce schéma montre un arbre de nœuds de périphériques plus complexe.
Pour plus d’informations sur les piles de pilotes plus complexes, veuillez consulter la section Empilements de pilotes et Nœuds de périphériques et piles de périphériques.
Travailler avec des points d’arrêt et du code source
Dans cette section, définissez des points d’arrêt et avancez pas à pas dans le code source en mode kernel.
Pour pouvoir avancer dans le code et vérifier les valeurs des variables en temps réel, activez les points d’arrêt et définissez un chemin vers le code source.
Les points d’arrêt arrêtent l’exécution du code à une ligne de code particulière. Avancez dans le code à partir de ce point pour déboguer cette section spécifique du code.
Pour définir un point d’arrêt à l’aide d’une commande de débogage, utilisez l’une des commandes suivantes b
.
Commande | Description |
---|---|
bp |
Définit un point d’arrêt actif jusqu’à ce que le module dans lequel il se trouve soit déchargé. |
bu |
Définit un point d’arrêt non résolu lorsque le module est déchargé et le réactive lorsque le module est rechargé. |
bm |
Définit un point d’arrêt pour un symbole. Cette commande utilise bu ou bp de manière appropriée et permet d’utiliser des caractères génériques (* ) pour définir des points d’arrêt sur chaque symbole correspondant, comme toutes les méthodes dans une classe. |
Pour plus d’informations, veuillez consulter la section Débogage de code source dans WinDbg.
Sur le système hôte, utilisez l’interface utilisateur de WinDbg pour confirmer que Débogage>Mode Source est activé dans la session WinDbg actuelle.
Entrez la commande suivante pour ajouter l’emplacement de votre code local au chemin d’accès source :
.srcpath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
Entrez la commande suivante pour ajouter l’emplacement de vos symboles locaux au chemin des symboles :
.sympath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
Utilisez la commande
x
pour examiner les symboles associés au pilote echo afin de déterminer le nom de la fonction à utiliser pour le point d’arrêt. Vous pouvez utiliser un caractère générique ou Ctrl+F pour localiser le nom de fonctionDeviceAdd
.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 …
La sortie montre que la
DeviceAdd
méthode pour votre pilote echo estECHO!EchoEvtDeviceAdd
.Alternativement, examinez le code source pour trouver le nom de fonction pour votre point d’arrêt.
Définissez le point d’arrêt avec la commande
bm
en utilisant le nom du pilote, suivi du nom de la fonction, par exemple,AddDevice
, où vous souhaitez définir le point d’arrêt, séparé par un point d’exclamation. Ce laboratoire utiliseAddDevice
pour surveiller le chargement du pilote.0: kd> bm ECHO!EchoEvtDeviceAdd 1: fffff801`0bf9b1c0 @!"ECHO!EchoEvtDeviceAdd"
Vous pouvez utiliser une syntaxe différente en conjonction avec la définition de variables comme
<module>!<symbol>
,<class>::<method>
,'<file.cpp>:<line number>'
, ou sauter un nombre de fois<condition> <#>
. Pour plus d’informations, veuillez consulter la rubrique Points d’arrêt conditionnels dans WinDbg et autres débogueurs Windows.Listez les points d’arrêt actuels pour confirmer que le point d’arrêt a été défini en entrant la commande
bl
:0: kd> bl 1 e fffff801`0bf9b1c0 0001 (0001) ECHO!EchoEvtDeviceAdd
Le « e » dans la sortie indique que le point d’arrêt numéro 1 est activé pour être déclenché.
Redémarrez l’exécution du code sur le système cible en entrant la commande
g
(go).Sur le système cible, dans Windows, ouvrez Gestionnaire de périphériques en utilisant l’icône ou en entrant mmc devmgmt.msc. Dans le Gestionnaire de périphériques, développez le nœud Exemples.
Sélectionnez et maintenez ou faites un clic droit sur l’entrée du pilote echo KMDF et sélectionnez Désactiver dans le menu.
Sélectionnez et maintenez ou faites un clic droit sur l’entrée du pilote echo KMDF à nouveau et sélectionnez Activer dans le menu.
Sur le système hôte, lorsque le pilote est activé, le point d’arrêt de débogage AddDevice devrait se déclencher. L’exécution du code du pilote sur le système cible doit s’arrêter. Lorsque le point d’arrêt est atteint, l’exécution doit s’arrêter au début de la routine AddDevice. La sortie de la commande de débogage affiche
Breakpoint 1 hit
.Avancez dans le code ligne par ligne en entrant la commande
p
ou en appuyant sur F10 jusqu’à atteindre la fin de la routine AddDevice. Le caractère accolade (}
) est mis en surbrillance comme illustré.
Dans la prochaine section, examinez l’état des variables après que le code de DeviceAdd a été exécuté.
Vous pouvez modifier les points d’arrêt existants en utilisant les commandes suivantes :
Commande | Description |
---|---|
bl |
Liste les points d’arrêt. |
bc |
Efface un point d’arrêt de la liste. Utilisez bc * pour effacer tous les points d’arrêt. |
bd |
Désactive un point d’arrêt. Utilisez bd * pour désactiver tous les points d’arrêt. |
be |
Active un point d’arrêt. Utilisez be * pour activer tous les points d’arrêt. |
Alternativement, vous pouvez également modifier les points d’arrêt dans l’interface utilisateur de WinDbg.
Vous pouvez également définir des points d’arrêt qui se déclenchent lorsqu’une adresse mémoire est accédée. Utilisez la commande ba
(break on access), avec la syntaxe suivante :
ba <access> <size> <address> {options}
Option | Description |
---|---|
e |
execute : lorsque le processeur récupère une instruction de l’adresse |
r |
read/write : lorsque le processeur lit ou écrit à l’adresse |
w |
write : lorsque le processeur écrit à l’adresse |
Vous ne pouvez définir que quatre points d’arrêt de données à un moment donné. C’est à vous de vous assurer que vous alignez correctement vos données pour déclencher le point d’arrêt. Les mots doivent se terminer à des adresses divisibles par 2, les double-mots doivent être divisibles par 4, et les quad-mots par 0 ou 8.
Par exemple, pour définir un point d’arrêt de lecture/d’écriture sur une adresse mémoire spécifique, vous pouvez utiliser une commande comme cet exemple.
ba r 4 0x0003f7bf0
Vous pouvez utiliser les commandes suivantes pour avancer dans votre code avec les raccourcis clavier associés indiqués entre parenthèses.
- Interruption (Ctrl+Pause). Cette commande interrompt un système tant que le système est en cours d’exécution et est en communication avec WinDbg. La séquence dans le débogueur noyau est Ctrl+C.
- Exécuter jusqu’au curseur (F7 ou Ctrl+F10). Placez le curseur dans une fenêtre de code source ou de désassemblage où vous souhaitez que l’exécution se bloque, puis appuyez sur F7. L’exécution du code se déroule jusqu’à ce point. Si le flux d’exécution du code n’atteint pas le point indiqué par le curseur, WinDbg ne s’arrêtera pas. Cette situation peut se produire si une instruction IF n’est pas exécutée.
- Exécuter (F5). Exécute jusqu’à ce qu’un point d’arrêt soit rencontré ou qu’un événement comme un contrôle de bug se produise.
- Pas à pas principal (F10). Cette commande permet à l’exécution du code de procéder une instruction ou une instruction à la fois. Si un appel est rencontré, l’exécution du code passe par-dessus l’appel sans entrer dans la routine appelée. Si le langage de programmation est C ou C++ et que WinDbg est en mode source, le mode source peut être activé ou désactivé à l’aide de Debug>Mode Source.
- Passer dans (F11). Cette commande est similaire au passage à la ligne suivante, sauf que l’exécution d’un appel entre dans la routine appelée.
- Passer à l’extérieur (Shift+F11). Cette commande entraîne l’exécution pour sortir de la routine actuelle ou du lieu actuel dans la pile d’appels. Cette commande est utile si vous avez vu assez de la routine.
Pour plus d’informations, veuillez consulter la section Débogage de code source dans WinDbg.
Afficher des variables et des piles d’appels
Dans cette section, affichez des informations sur les variables et les piles d’appels.
Ce laboratoire suppose que vous êtes arrêté à la routine AddDevice en utilisant le processus décrit précédemment. Pour afficher la sortie indiquée ici, répétez les étapes décrites précédemment, si nécessaire.
Sur le système hôte, pour afficher les variables, utilisez l’élément de menu view>local pour afficher les variables locales.
Pour rechercher l’emplacement d’une adresse de variable globale, saisissez ? <variable name>
.
- Passer à l’extérieur (Shift+F11) – Cette commande provoque l’exécution pour sortir de la routine actuelle (lieu actuel dans la pile d’appels). C’est utile si vous avez vu assez de la routine.
Pour plus d’informations, veuillez consulter la rubrique Débogage de code source dans WinDbg (Classique) dans la documentation de référence sur le débogage.
Section 8 : affichage des variables et des piles d’appels
Dans la section 8, vous allez afficher des informations sur les variables et les piles d’appels.
Ce laboratoire suppose que vous êtes arrêté à la routine AddDevice en utilisant le processus décrit précédemment. Pour afficher la sortie indiquée ici, répétez les étapes décrites précédemment, si nécessaire.
<- Sur le système hôte
Afficher les variables
Utilisez l’élément de menu view>local pour afficher les variables locales.
Variables globales
Vous pouvez trouver l’emplacement d’une adresse de variable globale en tapant ? <nom de la variable>.
Variables locales
Vous pouvez afficher les noms et les valeurs de toutes les variables locales pour une trame donnée en tapant la commande dv.
Pour afficher les noms et les valeurs de toutes les variables locales pour une trame spécifique, entrez la commande dv
:
0: kd> dv
Driver = 0x00001fff`7ff9c838
DeviceInit = 0xffffd001`51978190
status = 0n0
La pile d’appels est la chaîne d’appels de fonction qui ont conduit à l’emplacement actuel du compteur de programme. La fonction supérieure sur la pile d’appels est la fonction actuelle, et la fonction suivante est la fonction qui a appelé la fonction actuelle, et ainsi de suite.
Pour afficher la pile d’appels, utilisez les commandes k*
.
Commande | Description |
---|---|
kb |
Affiche la pile et les trois premiers paramètres. |
kp |
Affiche les piles et la liste complète des paramètres. |
kn |
Vous permet de voir la pile avec les informations de trame à côté. |
Sur le système hôte, si vous souhaitez conserver la pile d’appels disponible, sélectionnez view>call stack pour l’afficher. Sélectionnez les colonnes en haut de la fenêtre pour basculer l’affichage d’informations supplémentaires.
Utilisez la commande
kn
pour afficher la pile d’appels tout en déboguant le code de l’adaptateur d’échantillon dans un état d’arrêt.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] ...
La pile d’appels montre que le noyau (nt) a appelé le code Plug and Play (PnP) qui a appelé le code du framework du pilote (WDF) qui a ensuite appelé la fonction du pilote echo DeviceAdd
.
Afficher des processus et des threads
Dans cette section, affichez des informations sur les processus et les threads s’exécutant en mode kernel.
Processus
Vous pouvez afficher ou définir des informations sur le processus en utilisant l’extension de débogueur !process. Définissez un point d’arrêt pour examiner le processus utilisé lorsqu’un son est joué.
Sur le système hôte, entrez la commande
dv
pour examiner les variables locales associées à la routineEchoEvtIo
:0: kd> dv ECHO!EchoEvtIo* ECHO!EchoEvtIoQueueContextDestroy ECHO!EchoEvtIoWrite ECHO!EchoEvtIoRead
Effacez les points d’arrêt précédents en utilisant
bc *
:0: kd> bc *
Définissez un point d’arrêt de symbole sur les routines
EchoEvtIo
en utilisant la commande suivante :0: kd> bm ECHO!EchoEvtIo* 2: aade5490 @!”ECHO!EchoEvtIoQueueContextDestroy” 3: aade55d0 @!”ECHO!EchoEvtIoWrite” 4: aade54c0 @!”ECHO!EchoEvtIoRead”
Listez les points d’arrêt pour confirmer que le point d’arrêt est correctement défini :
0: kd> bl 1 e aabf0490 [c:\Samples\kmdf echo sample\c++\driver\autosync\queue.c @ 197] 0001 (0001) ECHO!EchoEvtIoQueueContextDestroy ...
Entrez
g
pour redémarrer l’exécution du code :0: kd> g
Sur le système cible, exécutez le programme de test du pilote
EchoApp.exe
sur le système cible.Sur le système hôte, lorsque l’application de test s’exécute, la routine d’E/S dans le pilote est appelée. Cet appel déclenche le point d’arrêt, et l’exécution du code du pilote sur le système cible s’arrête.
Breakpoint 2 hit ECHO!EchoEvtIoWrite: fffff801`0bf95810 4c89442418 mov qword ptr [rsp+18h],r8
Utilisez la commande
!process
pour afficher le processus actuel impliqué dans l’exécution de 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
La sortie montre que le processus est associé au thread echoapp.exe, qui s’exécutait lorsque votre point d’arrêt sur l’événement d’écriture du pilote a été atteint. Pour plus d’informations, veuillez consulter la section !process.
Utilisez
!process 0 0
pour afficher les informations de synthèse pour tous les processus. Dans la sortie, utilisez Ctrl+F pour localiser la même adresse de processus pour le processus associé à l’image echoapp.exe. Dans l’exemple, l’adresse du processus estffffe0007e6a7780
.... PROCESS ffffe0007e6a7780 SessionId: 1 Cid: 0f68 Peb: 7ff7cfe7a000 ParentCid: 0f34 DirBase: 1f7fb9000 ObjectTable: ffffc001cec82780 HandleCount: 34. Image: echoapp.exe ...
Enregistrez l’ID de processus associé à echoapp.exe pour l’utiliser plus tard dans ce laboratoire. Vous pouvez également utiliser Ctrl+C pour copier l’adresse dans le presse-papiers pour une utilisation ultérieure.
_____________________________________________________(adresse du processus echoapp.exe)
Saisissez
g
au besoin dans le débogueur pour faire avancer le code jusqu’à ce que echoapp.exe finisse de s’exécuter. Il atteint le point d’arrêt dans l’événement de lecture et d’écriture de nombreuses fois. Lorsque echoapp.exe se termine, interrompez le débogueur en appuyant sur Ctrl+ScrLk (Ctrl+Break).Utilisez la commande
!process
pour confirmer que vous exécutez un processus différent. Dans la sortie montrée ici, le processus avec la valeur Image de Système est différent de la valeur Image de Echo.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 ...
La sortie montre qu’un processus système ffffe0007b65d900 s’exécutait lorsque vous avez arrêté le système d’exploitation.
Utilisez la commande
!process
pour essayer de regarder l’ID de processus qui avait été associé à echoapp.exe que vous avez enregistré précédemment. Fournissez votre adresse de processus echoapp.exe que vous avez enregistrée précédemment, au lieu de l’exemple d’adresse de processus indiquée dans cet exemple.0: kd> !process ffffe0007e6a7780 TYPE mismatch for process object at 82a9acc0
L’objet de processus n’est plus disponible, car le processus echoapp.exe n’est plus en cours d’exécution.
Threads
Les commandes pour afficher et définir les threads sont similaires aux commandes pour les processus. Utilisez la commande !thread pour afficher les threads. Utilisez .thread pour définir les threads actuels.
Sur le système hôte, entrez
g
dans le débogueur pour redémarrer l’exécution du code sur le système cible.Sur le système cible, exécutez le programme de test EchoApp.exe.
Sur le système hôte, le point d’arrêt est atteint et l’exécution du code s’arrête.
Breakpoint 4 hit ECHO!EchoEvtIoRead: aade54c0 55 push ebp
Pour afficher les threads en cours d’exécution, entrez !thread. Des informations similaires à l’exemple suivant doivent être affichées :
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 ...
Notez le nom de l’image d’echoapp.exe. Cela indique que vous examinez le thread associé à l’application de test.
Utilisez la commande
!process
pour déterminer si ce thread est le seul en cours d’exécution dans le processus associé à echoapp.exe. Le numéro du thread en cours d’exécution dans le processus est le même que celui affiché par la commande!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
Utilisez la commande
!process 0 0
pour localiser l’adresse de processus de deux processus liés et enregistrez ces adresses de processus ici.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 …
Vous pouvez également utiliser
!process 0 17
pour afficher des informations détaillées sur chaque processus. La sortie de cette commande peut être longue. La sortie peut être recherchée en utilisant Ctrl+F.Utilisez la commande
!process
pour répertorier les informations de processus pour les deux processus en cours d’exécution sur votre ordinateur. Fournissez l’adresse du processus de votre sortie!process 0 0
, pas l’adresse indiquée dans cet exemple.Cette sortie d’exemple est pour l’ID de processus cmd.exe qui a été enregistré précédemment. Le nom de l’image pour cet ID de processus est 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 ...
Cette sortie d’exemple est pour l’ID de processus echoapp.exe qui a été enregistré précédemment.
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 ...
Enregistrez la première adresse de thread associée aux deux processus ici.
Cmd.exe: ____________________________________________________
EchoApp.exe: _________________________________________________
Utilisez la commande
!Thread
pour afficher des informations sur le thread actuel.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 ...
Comme prévu, le thread actuel est le thread associé à echoapp.exe et il est dans un état d’exécution.
Utilisez la commande
!Thread
pour afficher des informations sur le thread associé au processus cmd.exe. Fournissez l’adresse du thread que vous avez enregistrée précédemment.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] ...
Ce thread est associé au processus cmd.exe et se trouve dans un état d’attente.
Indiquez l’adresse du thread du processus CMD.exe en attente pour changer le contexte de ce thread en attente.
0: kd> .Thread ffffe0007cf34880 Implicit thread is now ffffe000`7cf34880
Utilisez la commande
k
pour afficher la pile d’appels associée au thread en attente.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] ...
Des éléments de la pile d’appels tels que
KiCommitThreadWait
indiquent que ce thread ne s’exécute pas comme prévu.
Pour plus d’informations sur les threads et les processus, consultez les références suivantes :
IRQL, registres et fin de la session WinDbg
Dans cette section, affichez le niveau de requête d’interruption (IRQL) et le contenu des registres.
Afficher l’IRQL enregistré
L’IRQL est utilisé pour gérer la priorité du traitement des interruptions. Chaque processeur a un paramètre d’IRQL que les threads peuvent augmenter ou diminuer. Les interruptions qui se produisent au niveau ou en dessous du paramètre d’IRQL du processeur sont masquées et n’interfèrent pas avec l’opération en cours. Les interruptions qui se produisent au-dessus du paramètre d’IRQL du processeur ont la priorité sur l’opération en cours.
Sur le système hôte, l’extension !irql affiche l’IRQL sur le processeur actuel de l’ordinateur cible avant que l’arrêt du débogueur ne se produise. Lorsque l’ordinateur cible se met en pause dans le débogueur, l’IRQL change, mais l’IRQL qui était efficace juste avant l’arrêt du débogueur est enregistré et est affiché par !irql
.
0: kd> !irql
Debugger saved IRQL for processor 0x0 -- 2 (DISPATCH_LEVEL)
Afficher les registres
Sur le système hôte, affichez le contenu des registres pour le thread actuel sur le processeur actuel à l’aide de la commande r (Registres).
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
Alternativement, vous pouvez afficher le contenu des registres en sélectionnant Affichage>Registres. Pour plus d’informations, voir r (Registres).
Afficher le contenu des registres peut être utile lors du déroulement de l’exécution du code en langage d’assemblage et dans d’autres scénarios. Pour plus d’informations sur le désassemblage en langage d’assemblage, veuillez consulter la rubrique Désassemblage x86 annoté et Désassemblage x64 annoté.
Pour des informations sur le contenu du registre, veuillez consulter la section architecture x86 et architecture x64.
Fin de la session WinDbg
Si vous souhaitez laisser le débogueur attaché, mais que vous voulez travailler sur la cible, effacez tout point d’arrêt en utilisant bc *
, afin que l’ordinateur cible ne tente pas de se connecter au débogueur de l’ordinateur hôte. Ensuite, utilisez la commande g
pour laisser l’ordinateur cible fonctionner à nouveau.
Pour mettre fin à la session de débogage, sur le système hôte, interrompez le débogueur et entrez la commande qd
(Quitter et détacher) ou sélectionnez Arrêter le débogage dans le menu.
0: kd> qd
Pour plus d’informations, veuillez consulter la rubrique Terminer une session de débogage dans WinDbg.
Ressources de débogage Windows
Plus d’informations sont disponibles sur le débogage Windows. Certains de ces livres utilisent des versions antérieures de Windows comme Windows Vista dans leurs exemples, mais les concepts discutés sont applicables à la plupart des versions de Windows.
Livres
- Advanced Windows Debugging par Mario Hewardt et Daniel Pravat
- Inside Windows Debugging : A Practical Guide to Debugging and Tracing Strategies in Windows® de Tarik Soulami.
- Windows Internals (Au cœur de Windows de Pavel Yosifovich, Alex Ionescu, Mark Russinovich et David Solomon
Vidéo
Fournisseurs de formation