Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Ce guide vous montre comment utiliser WinDbg pour déboguer des applications en mode utilisateur. Vous pratiquez des compétences de débogage essentielles en vous attachant à un processus en cours d’exécution, en définissant des points d’arrêt et en diagnostiquez les blocages de l’application.
Dans cet article :
- Attachez WinDbg à Notepad et explorez les fonctions de base du débogage
- Déboguer votre propre application et analyser un incident
- Commandes de débogage essentielles
Contenu
- Attacher WinDbg à un processus en cours d’exécution
- Configurer des fichiers de symboles pour la sortie de débogage lisible
- Définir des points d’arrêt et contrôler l’exécution du programme
- Analyser les blocages d’applications
- Parcourir les threads et les piles d’appels
Prerequisites
- WinDbg installé sur votre ordinateur. Pour obtenir des instructions d’installation, consultez Télécharger et installer le débogueur Windows WinDbg.
- Connaissance de base des interfaces de ligne de commande
- (Facultatif) Application compilée avec des symboles de débogage pour le deuxième exercice
Durée estimée : 30 minutes
Ouvrir le Bloc-notes et attacher WinDbg
Accédez à votre répertoire d’installation et ouvrez WinDbg.exe.
Dans le menu Fichier , sélectionnez Lancer l’exécutable. Dans la boîte de dialogue Lancer l’exécutable , accédez au dossier qui contient notepad.exe. (Le fichier notepad.exe se trouve généralement dans
C:\Windows\System32.) Pour le nom de fichier, entrez notepad.exe. Cliquez sur Ouvrir.
Configurez les fichiers de symboles afin que WinDbg puisse afficher des noms de fonction et de variables lisibles.
Dans la ligne de commande située en bas de la fenêtre WinDbg, entrez cette commande :
Le résultat ressemble à l’exemple suivant :
Symbol search path is: srv* Expanded Symbol search path is: cache*;SRVQu’est-ce que les symboles ? Les fichiers de symboles (PDB) contiennent des informations sur les modules de code, tels que les noms de fonctions et les noms de variables. Sans symboles, vous voyez uniquement des adresses mémoire.
Entrez ensuite cette commande :
La
.reloadcommande indique à WinDbg d’effectuer sa recherche initiale pour rechercher et charger des fichiers de symboles.Pour afficher les symboles du module notepad.exe , entrez cette commande :
Remarque
Si aucune sortie n’apparaît, entrez
.reload /fpour tenter de forcer le chargement des symboles. Utilisez !sym bruyant pour afficher des informations de chargement de symboles supplémentaires.Pour afficher les symboles dans le module notepad.exe qui contiennent, utilisez la commande
mainpour répertorier les modules qui correspondent au masque :x notepad!wWin*Le résultat ressemble à l’exemple suivant :
00007ff6`6e76b0a0 notepad!wWinMain (wWinMain) 00007ff6`6e783db0 notepad!wWinMainCRTStartup (wWinMainCRTStartup)Pour placer un point d’arrêt à
notepad!wWinMain, entrez cette commande :Pour vérifier que vous définissez votre point d’arrêt, entrez cette commande :
Le résultat ressemble à l’exemple suivant :
0 e Disable Clear 00007ff6`6e76b0a0 0001 (0001) 0:**** notepad!wWinMainPour démarrer le processus du Bloc-notes, entrez cette commande :
Notepad s’exécute jusqu'à ce qu'il arrive à la
WinMainfonction, puis s'arrête dans le débogueur.Breakpoint 0 hit notepad!wWinMain: 00007ff6`6e76b0a0 488bc4 mov rax,rspPour afficher la liste des modules de code actuellement chargés dans le bloc-notes, entrez cette commande :
Le résultat ressemble à l’exemple suivant :
0:000> lm start end module name 00007ff6`6e760000 00007ff6`6e798000 notepad (pdb symbols) C:\ProgramData\Dbg\sym\notepad.pdb\BC04D9A431EDE299D4625AD6201C8A4A1\notepad.pdb 00007ff8`066a0000 00007ff8`067ab000 gdi32full (deferred) 00007ff8`067b0000 00007ff8`068b0000 ucrtbase (deferred) 00007ff8`06a10000 00007ff8`06aad000 msvcp_win (deferred) 00007ff8`06ab0000 00007ff8`06ad2000 win32u (deferred) 00007ff8`06b40000 00007ff8`06e08000 KERNELBASE (deferred) 00007ff8`07220000 00007ff8`072dd000 KERNEL32 (deferred) 00007ff8`07420000 00007ff8`07775000 combase (deferred) 00007ff8`07820000 00007ff8`079c0000 USER32 (deferred) 00007ff8`079c0000 00007ff8`079f0000 IMM32 (deferred) 00007ff8`07c00000 00007ff8`07c2a000 GDI32 (deferred) 00007ff8`08480000 00007ff8`085ab000 RPCRT4 (deferred) 00007ff8`085b0000 00007ff8`0864e000 msvcrt (deferred) 00007ff8`08c40000 00007ff8`08cee000 shcore (deferred) 00007ff8`08db0000 00007ff8`08fa5000 ntdll (pdb symbols) C:\ProgramData\Dbg\sym\ntdll.pdb\53F12BFE149A2F50205C8D5D66290B481\ntdll.pdb 00007fff`f8580000 00007fff`f881a000 COMCTL32 (deferred)Pour afficher une trace de pile, entrez cette commande :
Le résultat ressemble à l’exemple suivant :
0:000> k 00 000000c8`2647f708 00007ff6`6e783d36 notepad!wWinMain 01 000000c8`2647f710 00007ff8`07237034 notepad!__scrt_common_main_seh+0x106 02 000000c8`2647f750 00007ff8`08e02651 KERNEL32!BaseThreadInitThunk+0x14 03 000000c8`2647f780 00000000`00000000 ntdll!RtlUserThreadStart+0x21Pour redémarrer le Bloc-notes, entrez cette commande :
Prochain: Vous allez interrompre l’exécution et explorer les modules chargés.
Pour entrer dans le Bloc-notes, dans le menu Fichier , sélectionnez Arrêt.
Pour définir et vérifier un point d’arrêt à l’adresse
ZwWriteFilesuivante, entrez les commandes suivantes :Pour redémarrer le Bloc-notes, entrez g. Dans la fenêtre du Bloc-notes, entrez du texte. Dans le menu Fichier , sélectionnez Enregistrer. Le code en cours d’exécution s’arrête quand il s’agit de
ZwCreateFile. Entrez la commande k pour afficher la trace de la pile.
Dans la fenêtre WinDbg, à gauche de la ligne de commande, le processeur et les numéros de thread sont affichés. Dans cet exemple, le numéro de processeur actuel est 0 et le numéro de thread actuel est 11 (
0:011>). La fenêtre affiche la trace de pile pour le thread 11 s’exécutant sur le processeur 0.Pour afficher la liste de tous les threads du processus du Bloc-notes, entrez cette commande (le tilde) :
Le résultat ressemble à l’exemple suivant :
0:011> ~ 0 Id: 5500.34d8 Suspend: 1 Teb: 000000c8`262c4000 Unfrozen 1 Id: 5500.3960 Suspend: 1 Teb: 000000c8`262c6000 Unfrozen 2 Id: 5500.5d68 Suspend: 1 Teb: 000000c8`262c8000 Unfrozen 3 Id: 5500.4c90 Suspend: 1 Teb: 000000c8`262ca000 Unfrozen 4 Id: 5500.4ac4 Suspend: 1 Teb: 000000c8`262cc000 Unfrozen 5 Id: 5500.293c Suspend: 1 Teb: 000000c8`262ce000 Unfrozen 6 Id: 5500.53a0 Suspend: 1 Teb: 000000c8`262d0000 Unfrozen 7 Id: 5500.3ca4 Suspend: 1 Teb: 000000c8`262d4000 Unfrozen 8 Id: 5500.808 Suspend: 1 Teb: 000000c8`262da000 Unfrozen 10 Id: 5500.3940 Suspend: 1 Teb: 000000c8`262dc000 Unfrozen . 11 Id: 5500.28b0 Suspend: 1 Teb: 000000c8`262de000 Unfrozen 12 Id: 5500.12bc Suspend: 1 Teb: 000000c8`262e0000 Unfrozen 13 Id: 5500.4c34 Suspend: 1 Teb: 000000c8`262e2000 UnfrozenDans cet exemple, 14 threads ont des index 0 à 13.
Pour examiner la trace de pile pour le thread 0, entrez les commandes suivantes :
Le résultat ressemble à l’exemple suivant :
0:011> ~0s 0:011> ~0s win32u!NtUserGetProp+0x14: 00007ff8`06ab1204 c3 ret 0:000> k # Child-SP RetAddr Call Site 00 000000c8`2647bd08 00007ff8`07829fe1 win32u!NtUserGetProp+0x14 01 000000c8`2647bd10 00007fff`f86099be USER32!GetPropW+0xd1 02 000000c8`2647bd40 00007ff8`07d12f4d COMCTL32!DefSubclassProc+0x4e 03 000000c8`2647bd90 00007fff`f8609aba SHELL32!CAutoComplete::_EditWndProc+0xb1 04 000000c8`2647bde0 00007fff`f86098b7 COMCTL32!CallNextSubclassProc+0x9a 05 000000c8`2647be60 00007ff8`0782e858 COMCTL32!MasterSubclassProc+0xa7 06 000000c8`2647bf00 00007ff8`0782de1b USER32!UserCallWinProcCheckWow+0x2f8 07 000000c8`2647c090 00007ff8`0782d68a USER32!SendMessageWorker+0x70b 08 000000c8`2647c130 00007ff8`07afa4db USER32!SendMessageW+0xdaPour quitter le débogage et détacher du processus du Bloc-notes, entrez cette commande :
Ouvrez votre propre application et attachez WinDbg
Par exemple, supposons que vous avez écrit et créé cette petite application console :
...
void MyFunction(long p1, long p2, long p3)
{
long x = p1 + p2 + p3;
long y = 0;
y = x / p2;
}
void main ()
{
long a = 2;
long b = 0;
MyFunction(a, b, 5);
}
Pour cet exercice, supposons que l’application générée (MyApp.exe) et le fichier de symboles (MyApp.pdb) se trouvent dans C :\MyApp\x64\Debug. Supposons également que le code source de l’application se trouve dans C:\MyApp\MyApp and that the target machine compiled MyApp.exe.
Ouvrez WinDbg.
Dans le menu Fichier , sélectionnez Lancer l’exécutable. Dans la boîte de dialogue Lancer l’exécutable , accédez à C :\MyApp\x64\Debug. Pour le nom de fichier, entrez MyApp.exe. Cliquez sur Ouvrir.
Entrez ces commandes :
.sympath+ C :\MyApp\x64\Debug
Ces commandes indiquent à WinDbg où rechercher des symboles et du code source pour votre application. Dans ce cas, vous n’avez pas besoin de définir l’emplacement du code source à l’aide de .srcpath , car les symboles ont des chemins d’accès complets aux fichiers sources.
Entrez ces commandes :
Votre application passe en mode débogage lorsqu’elle atteint la fonction
main.WinDbg affiche votre code source et la fenêtre Commande.
Dans le menu Débogage, sélectionnez Entrer (ou sélectionnez F11). Continuez à marcher jusqu'à ce que vous pénétriez dans
MyFunction. Lorsque vous effectuez un pas à pas dans la ligney = x / p2, votre application se bloque et se décompose dans le débogueur.Le résultat ressemble à l’exemple suivant :
(1450.1424): Integer divide-by-zero - code c0000094 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. MyApp!MyFunction+0x44: 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] ss:00000063`2036f808=00000000Entrez cette commande :
WinDbg affiche une analyse du problème (dans ce cas, division par 0).
FAULTING_IP: MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7] 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] EXCEPTION_RECORD: ffffffffffffffff -- (.exr 0xffffffffffffffff) ExceptionAddress: 00007ff63be11064 (MyApp!MyFunction+0x0000000000000044) ExceptionCode: c0000094 (Integer divide-by-zero) ExceptionFlags: 00000000 NumberParameters: 0 ... STACK_TEXT: 00000063`2036f7e0 00007ff6`3be110b8 : ... : MyApp!MyFunction+0x44 00000063`2036f800 00007ff6`3be1141d : ... : MyApp!main+0x38 00000063`2036f840 00007ff6`3be1154e : ... : MyApp!__tmainCRTStartup+0x19d 00000063`2036f8b0 00007ffc`b1cf16ad : ... : MyApp!mainCRTStartup+0xe 00000063`2036f8e0 00007ffc`b1fc4629 : ... : KERNEL32!BaseThreadInitThunk+0xd 00000063`2036f910 00000000`00000000 : ... : ntdll!RtlUserThreadStart+0x1d STACK_COMMAND: dt ntdll!LdrpLastDllInitializer BaseDllName ;dt ntdll!LdrpFailureData ;.cxr 0x0 ;kb FOLLOWUP_IP: MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7] 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] FAULTING_SOURCE_LINE: c:\myapp\myapp\myapp.cpp FAULTING_SOURCE_FILE: c:\myapp\myapp\myapp.cpp FAULTING_SOURCE_LINE_NUMBER: 7 FAULTING_SOURCE_CODE: 3: void MyFunction(long p1, long p2, long p3) 4: { 5: long x = p1 + p2 + p3; 6: long y = 0; > 7: y = x / p2; 8: } 9: 10: void main () 11: { 12: long a = 2; ...
Étapes suivantes
Après avoir débogué une application système et votre propre code, vous êtes prêt à explorer des scénarios de débogage plus avancés :
- Prise en main de WinDbg (mode noyau) - Déboguer le noyau et les pilotes Windows
- Opération de débogueur - En savoir plus sur les concepts d’opération du débogueur
- Techniques de débogage - Explorer les méthodes de débogage avancées
Résumé des commandes
Voici les commandes essentielles que vous utilisez dans ce tutoriel :
Configuration et symboles :
- .sympath (Définir le chemin du symbole) - Configurer l’emplacement où WinDbg recherche des fichiers de symboles
- .reload (Module de rechargement) - Charger des fichiers de symboles
Contrôle de l’exécution :
- g (Go) - Continuer l’exécution du programme
- bu (Définir un point d’arrêt) - Suspendre l’exécution à une fonction spécifique
-
Step Into(F11) - Exécuter une instruction et entrer dans les fonctions
Inspection de votre programme :
- x (Examiner les symboles) - Répertorier les fonctions et variables
- lm (List Loaded Modules) - Afficher toutes les DLL et exécutables chargés
- k (Affichage du rétrotraçage de pile) - Afficher la pile des appels
- ~ (État du thread) - Répertorier tous les threads
- !analyze -v - Analyser automatiquement les blocages
Référence :
- bl (liste de points d’arrêt)
- ~s (Définir le thread actuel)
- .sympath+
- .srcpath (Définir le chemin de la source)
- qd (Quitter et détacher)
Voir aussi
Commencez avec WinDbg (mode noyau)