Débogage en mode source

Le débogage d’une application est plus facile si vous pouvez analyser la source du code plutôt que les fichiers binaires désassemblés.

WinDbg, CDB et KD peuvent utiliser le code source dans le débogage, si le langage source est C, C++ ou assembly.

Conditions requises pour la compilation

Pour utiliser le débogage source, votre compilateur ou éditeur de liens doit créer des fichiers de symboles (fichiers .pdb) lorsque les fichiers binaires sont générés. Ces fichiers de symboles montrent au débogueur comment les instructions binaires correspondent aux lignes sources.

En outre, le débogueur doit être en mesure d’accéder aux fichiers sources réels , car les fichiers de symboles ne contiennent pas le texte source réel.

Si cela est possible, le compilateur et l’éditeur de liens ne doivent pas optimiser votre code. Le débogage source et l’accès aux variables locales sont plus difficiles, voire presque impossibles, si le code a été optimisé. Si vous utilisez l’utilitaire Build comme compilateur et éditeur de liens, définissez l’MSC_OPTIMIZATION macro sur /Od /Oi pour éviter l’optimisation.

Localisation des fichiers de symboles et des fichiers sources

Pour déboguer en mode source, le débogueur doit être en mesure de trouver les fichiers sources et les fichiers de symboles. Pour plus d’informations, consultez Chemin d’accès source.

Début du débogage source

Le débogueur peut afficher les informations sources chaque fois qu’il a des symboles et des fichiers sources appropriés pour le thread actuellement débogué.

Si vous démarrez une nouvelle application en mode utilisateur à l’aide du débogueur, l’arrêt initial se produit lorsque Ntdll.dll charge l’application. Étant donné que le débogueur n’a pas accès aux fichiers sources Ntdll.dll, vous ne pouvez pas accéder aux informations sources de votre application à ce stade.

Pour déplacer le compteur du programme au début de l’application, ajoutez un point d’arrêt au point d’entrée à votre fichier binaire. Dans la fenêtre Commande du débogueur, tapez la commande suivante.

bp main
g

L’application est ensuite chargée et s’arrête lorsque la fonction main est entrée. (Bien sûr, vous pouvez utiliser n’importe quel point d’entrée, pas seulement main.)

Si l’application lève une exception, elle s’interrompt dans le débogueur. Les informations sources sont disponibles à ce stade. Toutefois, si vous effectuez un arrêt à l’aide de ctrl+C, ctrl+arrêt ou déboguer | Commande d’arrêt, le débogueur crée un thread, de sorte que vous ne pouvez pas voir votre code source.

Une fois que vous avez atteint un thread pour lequel vous disposez de fichiers sources, vous pouvez utiliser la fenêtre Commande du débogueur pour exécuter des commandes de débogage source. Si vous utilisez WinDbg, la fenêtre Source s’affiche. Si vous avez déjà ouvert une fenêtre Source en cliquant sur Fichier open source dans le menu Fichier , WinDbg crée généralement une nouvelle fenêtre pour la source. Vous pouvez fermer la fenêtre précédente sans affecter le processus de débogage.

Débogage source dans l’interface utilisateur utilisateur WinDbg

Si vous utilisez WinDbg, une fenêtre Source s’affiche dès que le compteur du programme est dans le code pour lequel le débogueur dispose d’informations sources.

WinDbg affiche une fenêtre Source pour chaque fichier source que vous ou WinDbg avez ouvert. Pour plus d’informations sur les propriétés de texte de cette fenêtre, consultez Windows source.

Vous pouvez ensuite parcourir votre application ou exécuter jusqu’à un point d’arrêt ou au curseur. Pour plus d’informations sur les commandes d’étape et de suivi, consultez Contrôle de la cible.

Si vous êtes en mode source, la fenêtre Source appropriée se déplace au premier plan au fur et à mesure que vous parcourez votre application. Étant donné qu’il existe également des routines Microsoft Windows appelées pendant l’exécution de l’application, le débogueur peut déplacer une fenêtre De désassemblement au premier plan lorsque ce type d’appel se produit (car le débogueur n’a pas accès à la source pour ces fonctions). Lorsque le compteur du programme retourne des fichiers sources connus, la fenêtre Source appropriée devient active.

Au fur et à mesure que vous parcourez l’application, WinDbg met en évidence votre emplacement dans la fenêtre Source et dans la fenêtre Désassemblement. Les lignes auxquelles les points d’arrêt sont définis sont également mises en surbrillance. Le code source est coloré en fonction de l’analyse de la langue. Si la fenêtre Source a été sélectionnée, vous pouvez pointer sur un symbole avec la souris pour l’évaluer. Pour plus d’informations sur ces fonctionnalités et sur la façon de les contrôler, consultez Windows source.

Pour activer le mode source dans WinDbg, utilisez la commande l+t , cliquez sur mode source dans le menu déboguer ou cliquez sur le bouton mode source activé . Lorsque le mode source est actif, l’indicateur ASM apparaît indisponible dans la barre de status.

Vous pouvez afficher ou modifier les valeurs de toutes les variables locales à mesure que vous parcourez une fonction en mode source. Pour plus d’informations, consultez Lecture et écriture de la mémoire.

Débogage source dans la fenêtre Debugger Command

Si vous utilisez CDB, vous n’avez pas de fenêtre Source distincte. Toutefois, vous pouvez toujours voir votre progression au fur et à mesure que vous parcourez la source.

Avant de pouvoir effectuer un débogage source dans CDB, vous devez charger les symboles de ligne source en émettant la commande .lines (Activer la prise en charge de la ligne source) ou en démarrant le débogueur avec l’option de ligne de commande -lines.

Si vous exécutez une commande l+t , tous les pas du programme sont exécutés une ligne source à la fois. Utilisez l-t pour effectuer une instruction d’assembly à la fois. Si vous utilisez WinDbg, cette commande a le même effet que la sélection ou l’effacement du mode source dans le menu Déboguer ou l’utilisation des boutons de la barre d’outils.

La commande l+s affiche la ligne source et le numéro de ligne actuels à l’invite. Si vous souhaitez voir uniquement le numéro de ligne, utilisez plutôt l+l .

Si vous utilisez l+o et l+s, seule la ligne source s’affiche pendant que vous parcourez le programme. Le compteur du programme, le code de désassemblement et les informations de registre sont masqués. Ce type d’affichage vous permet de parcourir rapidement le code et de ne voir que la source.

Vous pouvez utiliser la commande lsp (Définir le nombre de lignes sources) pour spécifier exactement le nombre de lignes sources affichées lorsque vous exécutez ou pas à pas l’application.

La séquence de commandes suivante est un moyen efficace d’parcourir un fichier source.

.lines        enable source line information
bp main       set initial breakpoint
l+t           stepping will be done by source line
l+s           source lines will be displayed at prompt
g             run program until "main" is entered
pr            execute one source line, and toggle register display off
p             execute one source line 

Étant donné qu’ENTER répète la dernière commande, vous pouvez maintenant parcourir l’application à l’aide de la clé ENTRÉE. Chaque étape entraîne l’affichage de la ligne source, du décalage de mémoire et du code d’assembly.

Pour plus d’informations sur l’interprétation de l’affichage de désassemblement, consultez Débogage en mode Assembly.

Lorsque le code d’assembly est affiché, tout emplacement de mémoire accessible s’affiche à l’extrémité droite de la ligne. Vous pouvez utiliser les commandes d* (Mémoire d’affichage) et e* (Entrer des valeurs) pour afficher ou modifier les valeurs dans ces emplacements.

Si vous devez afficher chaque instruction d’assembly pour déterminer les décalages ou les informations de mémoire, utilisez l-t pour obtenir des instructions d’assembly pas à pas au lieu des lignes sources. Les informations de ligne source peuvent toujours être affichées. Chaque ligne source correspond à une ou plusieurs instructions d’assembly.

Toutes ces commandes sont disponibles dans WinDbg et dans CDB. Vous pouvez utiliser les commandes pour afficher les informations de ligne source à partir de la fenêtre Commande du débogueur de WinDbg au lieu de la fenêtre Source.

Lignes sources et décalages

Vous pouvez également effectuer un débogage source à l’aide de l’évaluateur d’expression pour déterminer le décalage qui correspond à une ligne source spécifique.

La commande suivante affiche un décalage de mémoire.

? `[[module!]filename][:linenumber]` 

Si vous omettez le nom de fichier, le débogueur recherche le fichier source qui correspond au compteur du programme actuel.

Le débogueur lit linenumber sous la forme d’un nombre décimal, sauf si vous ajoutez 0x avant lui, quel que soit le radix par défaut actuel. Si vous omettez linenumber, l’expression correspond à l’adresse initiale du fichier exécutable qui correspond au fichier source.

Cette syntaxe est comprise dans CDB uniquement si la commande .lines ou l’option de ligne de commande -lines a chargé des symboles de ligne source.

Cette technique est très polyvalente, car vous pouvez l’utiliser quel que soit l’endroit où pointe le compteur du programme. Par exemple, cette technique vous permet de définir des points d’arrêt à l’avance, à l’aide de commandes telles que les suivantes.

bp `source.c:31` 

Pour plus d’informations, consultez Syntaxe de ligne source et Utilisation des points d’arrêt.

Pas à pas et suivi en mode source

Lorsque vous déboguez en mode source, il peut y avoir plusieurs appels de fonction sur une seule ligne source. Vous ne pouvez pas utiliser les commandes p et t pour séparer ces appels de fonction.

Par exemple, dans la commande suivante, la commande t effectue des étapes dans GetTickCount et printf, tandis que la commande p effectue des étapes sur les deux appels de fonction.

printf( "%x\n", GetTickCount() );

Si vous souhaitez passer à pas sur certains appels tout en effectuant le suivi dans d’autres appels, utilisez .step_filter (Définir le filtre d’étape) pour indiquer les appels à passer à pas.

Vous pouvez utiliser _step_filter pour filtrer les fonctions d’infrastructure (par exemple, les appels MFC (Microsoft Foundation Classes) ou ATL (Active Template Library).