Débogage pour grands débutants
Inévitablement, le code que nous écrivons en tant que développeurs de logiciels ne fait pas toujours ce à quoi nous nous attendions. Parfois, il fait quelque chose de complètement différent ! Lorsque l’inattendu se produit, la tâche suivante consiste à déterminer pourquoi, et bien que nous soyez tentés de simplement regarder notre code pendant des heures, il est plus facile et plus efficace d’utiliser un outil de débogage ou un débogueur.
Un débogueur, malheureusement, n’est pas quelque chose qui peut révéler magiquement tous les problèmes ou « bogues » dans notre code. Débogage signifie exécuter votre code pas à pas dans un outil de débogage tel que Visual Studio, pour trouver le point exact où vous avez commis une erreur de programmation. Vous comprenez ensuite quelles corrections vous devez apporter dans votre code et vos outils de débogage vous permettent souvent d’apporter des modifications temporaires afin de continuer à exécuter le programme.
L’utilisation efficace d’un débogueur est également une compétence qui prend du temps et de la pratique pour apprendre, mais qui est finalement une tâche fondamentale pour chaque développeur de logiciels. Dans cet article, nous présentons les principes fondamentaux du débogage et fournissons des conseils pour vous aider à démarrer.
Clarifier le problème en vous posant les bonnes questions
Il permet de clarifier le problème que vous avez rencontré avant d’essayer de le résoudre. Nous vous attendons à ce que vous ayez déjà rencontré un problème dans votre code, sinon vous n’êtes pas ici en essayant de déterminer comment le déboguer ! Avant de commencer le débogage, vérifiez que vous avez identifié le problème que vous essayez de résoudre :
Que s’attendiez-vous à ce que votre code fasse ?
Qu’est-ce qui s’est passé à la place ?
Si vous rencontrez une erreur (exception) lors de l’exécution de votre application, cela peut être une bonne chose ! Une exception est un événement inattendu rencontré lors de l’exécution du code, généralement une erreur d’un certain type. Un outil de débogage peut vous amener à l’emplacement exact dans votre code où l’exception s’est produite et peut vous aider à examiner les correctifs possibles.
Si quelque chose d’autre s’est produit, quel est le symptôme du problème ? Suspectez-vous déjà où ce problème s'est produit dans votre code ? Par exemple, si votre code affiche du texte, mais que le texte est incorrect, vous savez que vos données sont incorrectes ou que le code qui définit le texte d’affichage contient un certain type de bogue. En parcourant le code dans un débogueur, vous pouvez examiner chaque modification apportée à vos variables pour découvrir exactement quand et comment les valeurs incorrectes sont affectées.
Examiner vos hypothèses
Avant d’examiner un bogue ou une erreur, pensez aux hypothèses qui vous ont fait attendre un certain résultat. Les hypothèses cachées ou inconnues peuvent entraver l'identification d'un problème même lorsque vous examinez sa cause dans un débogueur. Vous pourriez avoir une longue liste d’hypothèses possibles ! Voici quelques questions à vous poser pour contester vos hypothèses.
Utilisez-vous l’API appropriée (c’est-à-dire l’objet, la fonction, la méthode ou la propriété appropriés) ? Une API que vous utilisez peut ne pas faire ce que vous pensez faire. (Après avoir examiné l’appel d’API dans le débogueur, la correction peut nécessiter un voyage vers la documentation pour vous aider à identifier l’API correcte.)
Utilisez-vous correctement une API ? Peut-être que vous avez utilisé l’API appropriée, mais que vous ne l’avez pas utilisée de la bonne façon.
Votre code contient-il des fautes de frappe ? Certaines fautes de frappe, comme une simple faute d’orthographe d’un nom de variable, peuvent être difficiles à voir, en particulier lorsque vous travaillez avec des langues qui ne nécessitent pas de variables à déclarer avant qu’elles ne soient utilisées.
Avez-vous apporté une modification à votre code et supposez qu’il n’est pas lié au problème que vous voyez ?
Vous attendiez-vous à ce qu’un objet ou une variable contienne une certaine valeur (ou un certain type de valeur) différente de ce qui s’est réellement passé ?
Connaissez-vous l’intention du code ? Il est souvent plus difficile de déboguer le code d’une autre personne. Si ce n’est pas votre code, il est possible que vous deviez passer du temps à apprendre exactement ce que fait le code avant de pouvoir le déboguer efficacement.
Conseil
Lorsque vous écrivez du code, commencez petit et commencez par du code qui fonctionne ! (Un bon exemple de code est utile ici.) Parfois, il est plus facile de corriger un jeu de code volumineux ou compliqué en commençant par un petit morceau de code qui illustre la tâche principale que vous essayez d’atteindre. Ensuite, vous pouvez modifier ou ajouter du code de manière incrémentielle, en testant à chaque point des erreurs.
En interrogeant vos hypothèses, vous pouvez réduire le temps nécessaire pour trouver un problème dans votre code. Vous pouvez également réduire le temps nécessaire pour résoudre un problème.
Parcourez votre code en mode débogage pour trouver où le problème s’est produit
Lorsque vous exécutez normalement une application, vous voyez des erreurs et des résultats incorrects uniquement après l’exécution du code. Un programme peut également se terminer de façon inattendue sans vous dire pourquoi.
Lorsque vous exécutez une application dans un débogueur, également appelé mode de débogage, le débogueur surveille activement tout ce qui se passe au fur et à mesure que le programme s’exécute. Il vous permet également de suspendre l’application à tout moment pour examiner son état, puis parcourir votre ligne de code par ligne pour observer chaque détail tel qu’il se produit.
Dans Visual Studio, vous entrez en mode débogage à l'aide de F5 (ou de la commande de menu Démarrer le débogage> ou du bouton Démarrer le débogage dans la barre d’outils Débogage). Si des exceptions se produisent, l’Assistance à l’exception de Visual Studio vous amène au point exact où l’exception s’est produite et fournit d’autres informations utiles. Pour plus d’informations sur la gestion des exceptions dans votre code, consultez techniques et outils de débogage.
Si vous n’avez pas obtenu d’exception, vous avez probablement une bonne idée de l’endroit où rechercher le problème dans votre code. C’est à cette étape-là que l’on utilise des points d’arrêt avec le débogueur, pour pouvoir examiner le code plus attentivement. Les points d'arrêt constituent la fonctionnalité la plus élémentaire et essentielle pour un débogage fiable. Un point d’arrêt indique où Visual Studio doit suspendre votre code en cours d’exécution afin de pouvoir examiner les valeurs des variables, ou le comportement de la mémoire, la séquence dans laquelle le code s’exécute.
Dans Visual Studio, vous pouvez définir rapidement un point d’arrêt en cliquant sur la marge gauche en regard d’une ligne de code. Ou placez le curseur sur une ligne et appuyez sur F9 .
Pour vous aider à illustrer ces concepts, nous vous prenons dans un exemple de code qui contient déjà plusieurs bogues. Nous utilisons C#, mais les fonctionnalités de débogage s’appliquent à Visual Basic, C++, JavaScript, Python et d’autres langages pris en charge. L’exemple de code pour Visual Basic est également fourni, mais les captures d’écran sont en C#.
Créer un exemple d’application (avec certains bogues)
Ensuite, vous créez une application qui contient quelques bogues.
Visual Studio et la charge de travail Développement .NET Desktop doivent être installés.
Si vous n’avez pas encore installé Visual Studio, allez à la page des téléchargements de Visual Studio pour l’installer gratuitement.
Si vous devez installer la charge de travail mais que Visual Studio est déjà installé, sélectionnez Tools>Obtenir des outils et des fonctionnalités. Le programme d’installation de Visual Studio démarre. Choisissez la charge de travail Développement .NET Desktop, puis choisissez Modifier.
Ouvrez Visual Studio.
Dans la fenêtre de démarrage, choisissez Créer un projet. Tapez console dans la zone de recherche, sélectionnez C# ou Visual Basic comme langue, puis choisissez application console pour .NET. Sélectionnez Suivant. Tapez ConsoleApp_FirstApp comme nom du projet, puis sélectionnez suivant.
Si vous utilisez un autre nom de projet, vous devez modifier la valeur de l’espace de noms pour qu’elle corresponde au nom de votre projet lorsque vous copiez l’exemple de code.
Choisissez le framework cible recommandé ou .NET 8, puis choisissez Créer.
Si vous ne voyez pas le modèle de projet Application console pour .NET, accédez à Outils>Obtenir les outils et fonctionnalités, qui ouvre Visual Studio Installer. Choisissez la charge de travail Développement .NET Desktop, puis Modifier.
Visual Studio crée le projet de console, qui apparaît dans Explorateur de solutions dans le volet droit.
Dans Program.cs (ou Program.vb), remplacez tout le code par défaut par le code suivant. (Sélectionnez d’abord l’onglet de langue approprié, C# ou Visual Basic.)
using System; using System.Collections.Generic; namespace ConsoleApp_FirstApp { class Program { static void Main(string[] args) { Console.WriteLine("Welcome to Galaxy News!"); IterateThroughList(); Console.ReadKey(); } private static void IterateThroughList() { var theGalaxies = new List<Galaxy> { new Galaxy() { Name="Tadpole", MegaLightYears=400, GalaxyType=new GType('S')}, new Galaxy() { Name="Pinwheel", MegaLightYears=25, GalaxyType=new GType('S')}, new Galaxy() { Name="Cartwheel", MegaLightYears=500, GalaxyType=new GType('L')}, new Galaxy() { Name="Small Magellanic Cloud", MegaLightYears=.2, GalaxyType=new GType('I')}, new Galaxy() { Name="Andromeda", MegaLightYears=3, GalaxyType=new GType('S')}, new Galaxy() { Name="Maffei 1", MegaLightYears=11, GalaxyType=new GType('E')} }; foreach (Galaxy theGalaxy in theGalaxies) { Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears + ", " + theGalaxy.GalaxyType); } // Expected Output: // Tadpole 400, Spiral // Pinwheel 25, Spiral // Cartwheel, 500, Lenticular // Small Magellanic Cloud .2, Irregular // Andromeda 3, Spiral // Maffei 1, 11, Elliptical } } public class Galaxy { public string Name { get; set; } public double MegaLightYears { get; set; } public object GalaxyType { get; set; } } public class GType { public GType(char type) { switch(type) { case 'S': MyGType = Type.Spiral; break; case 'E': MyGType = Type.Elliptical; break; case 'l': MyGType = Type.Irregular; break; case 'L': MyGType = Type.Lenticular; break; default: break; } } public object MyGType { get; set; } private enum Type { Spiral, Elliptical, Irregular, Lenticular} } }
Notre intention pour ce code est d’afficher le nom de la galaxie, la distance à la galaxie, et la galaxie type tous dans une liste. Pour déboguer, il est important de comprendre l’intention du code. Voici le format d’une ligne de la liste que nous voulons afficher dans la sortie :
nom de galaxie, distance, type de galaxie.
Exécuter l’application
Appuyez sur F5 ou sur le bouton Démarrer le débogage dans la barre d’outils Debug, située au-dessus de l’éditeur de code.
L’application démarre et aucune exception n’est signalée par le débogueur. Toutefois, la sortie que vous voyez dans la fenêtre de console n’est pas ce que vous attendez. Voici la sortie attendue :
Tadpole 400, Spiral
Pinwheel 25, Spiral
Cartwheel, 500, Lenticular
Small Magellanic Cloud .2, Irregular
Andromeda 3, Spiral
Maffei 1, Elliptical
Toutefois, vous voyez ce résultat plutôt :
Tadpole 400, ConsoleApp_FirstApp.GType
Pinwheel 25, ConsoleApp_FirstApp.GType
Cartwheel, 500, ConsoleApp_FirstApp.GType
Small Magellanic Cloud .2, ConsoleApp_FirstApp.GType
Andromeda 3, ConsoleApp_FirstApp.GType
Maffei 1, 11, ConsoleApp_FirstApp.GType
En examinant la sortie et notre code, nous savons que GType
est le nom de la classe qui stocke le type de galaxie. Nous essayons de montrer le type de galaxie réel (comme « Spiral »), pas le nom de la classe !
Déboguer l’application
L'application étant toujours en cours d'exécution, insérez un point d'arrêt.
Dans la boucle
foreach
, cliquez avec le bouton droit à côté de la méthodeConsole.WriteLine
pour ouvrir le menu contextuel et sélectionnez Point d’arrêt>Insérer un point d’arrêt dans le menu déroulant.foreach (Galaxy theGalaxy in theGalaxies) { Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears + ", " + theGalaxy.GalaxyType); }
Lorsque vous définissez le point d’arrêt, un point rouge apparaît dans la marge gauche.
Comme vous voyez un problème dans la sortie, vous commencez à déboguer en examinant le code précédent qui définit la sortie dans le débogueur.
Sélectionnez le bouton Redémarrer
dans la barre d’outils Déboguer (Ctrl + Maj + F5).
L’application s’interrompt au point d’arrêt que vous définissez. La mise en surbrillance jaune indique où le débogueur est suspendu (la ligne jaune du code n’a pas encore été exécutée).
Placez le curseur sur la variable
GalaxyType
à droite puis, à gauche de l’icône de clé, développeztheGalaxy.GalaxyType
. Vous voyez queGalaxyType
contient une propriétéMyGType
et que la valeur de la propriété est définie surSpiral
.« Spiral » est la valeur correcte que vous attendiez dans la console ! C'est donc un bon début que vous puissiez accéder à la valeur dans ce code lors de l'exécution de l'application. Dans ce scénario, nous utilisons l’API incorrecte. Voyons si vous pouvez résoudre ce problème lors de l’exécution du code dans le débogueur.
Dans le même code, tout en déboguant, placez votre curseur à la fin de
theGalaxy.GalaxyType
et remplacez-le partheGalaxy.GalaxyType.MyGType
. Bien que vous puissiez effectuer la modification, l'éditeur de code vous affiche une erreur (soulignée en rouge). (En Visual Basic, l’erreur n’est pas affichée et cette section de code fonctionne.)Appuyez sur F11 (Déboguer>Pas à pas détaillé ou le bouton Pas à pas détaillé dans la barre d’outils de débogage) pour exécuter la ligne de code actuelle.
F11 fait avancer le débogueur (et exécute le code) une instruction à la fois. F10 (Pas à pas) est une commande similaire, et toutes deux sont utiles pour apprendre à utiliser le débogueur.
Lorsque vous essayez de faire avancer le débogueur, la boîte de dialogue Rechargement à chaud s’affiche, indiquant que les modifications ne peuvent pas être compilées.
La boîte de dialogue Modifier et continuer s’affiche, indiquant que les modifications ne peuvent pas être compilées.
Remarque
Pour déboguer l’exemple de code Visual Basic, ignorez les étapes suivantes jusqu'à ce qu'on vous demande de cliquer sur le bouton Redémarrer
.
Sélectionnez Modifier dans la zone de message Rechargement à Chaud ou Modifier et Continuer. Un message d’erreur s’affiche maintenant dans la fenêtre Liste d’erreurs. L’erreur indique que le
'object'
ne contient pas de définition pourMyGType
.Même si nous définissons chaque galaxie avec un objet de type
GType
(qui a la propriétéMyGType
), le débogueur ne reconnaît pas l’objettheGalaxy
comme un objet de typeGType
. Que se passe-t-il? Vous souhaitez examiner n’importe quel code qui définit le type de galaxie. Lorsque vous faites cela, vous voyez que la classeGType
a certainement une propriété deMyGType
, mais quelque chose n’est pas correct. Le message d’erreur surobject
s’avère être l’indice ; pour l’interpréteur de langage, le type semble être un objet de typeobject
au lieu d’un objet de typeGType
.En examinant votre code lié à la définition du type de galaxie, vous trouvez la propriété
GalaxyType
de la classeGalaxy
est spécifiée commeobject
au lieu deGType
.public object GalaxyType { get; set; }
Modifiez le code précédent comme suit :
public GType GalaxyType { get; set; }
Sélectionnez le bouton Redémarrer
dans la barre d’outils Déboguer (Ctrl + Maj + F5) pour recompiler le code et redémarrer.
À présent, lorsque le débogueur s’interrompt sur
Console.WriteLine
, vous pouvez pointer surtheGalaxy.GalaxyType.MyGType
et voir que la valeur est correctement définie.Supprimez le point d’arrêt en cliquant sur le cercle de point d’arrêt dans la marge gauche (ou cliquez avec le bouton droit et choisissez point d’arrêt>Supprimer le point d’arrêt), puis appuyez sur F5 pour continuer.
L’application s’exécute et affiche la sortie. Ça a l'air bien, mais tu remarques une chose. Vous attendiez que la petite galaxie Magellanic Cloud s’affiche sous la forme d’une galaxie irrégulière dans la sortie de la console, mais elle n’affiche aucun type de galaxie du tout.
Tadpole 400, Spiral Pinwheel 25, Spiral Cartwheel, 500, Lenticular Small Magellanic Cloud .2, Andromeda 3, Spiral Maffei 1, Elliptical
Définissez un point d’arrêt sur cette ligne de code avant l’instruction
switch
(avant l’instructionSelect
en Visual Basic).public GType(char type)
Ce code est l’endroit où le type de galaxie est défini, donc nous voulons examiner de plus près.
Sélectionnez le bouton Redémarrer
dans la barre d’outils Déboguer (Ctrl + Maj + F5) pour redémarrer.
Le débogueur s’interrompt sur la ligne de code où vous définissez le point d’arrêt.
Placez le curseur sur la variable
type
. Vous voyez une valeur deS
(suivant le code de caractère). Vous êtes intéressé par une valeur deI
, comme vous savez qu’il s’agit d’un type de galaxie irrégulière.Appuyez F5 et pointez sur la variable
type
à nouveau. Répétez cette étape jusqu’à ce que vous voyiez une valeur deI
dans la variabletype
.Appuyez à présent sur F11 (Déboguer>Effectuer un pas à pas détaillé).
Appuyez sur F11 jusqu’à ce que vous arrêtiez sur la ligne de code dans l’instruction
switch
pour obtenir la valeur « I » (instructionSelect
pour Visual Basic). Ici, vous voyez un problème clair résultant d’une faute de frappe. Vous attendiez que le code passe à l’emplacement où il définitMyGType
comme type de galaxie irrégulière, mais le débogueur ignore ce code complètement et s’interrompt complètement sur la sectiondefault
de l’instructionswitch
(instructionElse
en Visual Basic).En examinant le code, vous voyez une faute de frappe dans l’instruction
case 'l'
. Cela devrait êtrecase 'I'
.Sélectionnez le code de
case 'l'
et remplacez-le parcase 'I'
.Supprimez votre point d’arrêt, puis sélectionnez le bouton Redémarrer pour redémarrer l’application.
Les bogues sont maintenant corrigés et vous voyez le résultat attendu !
Appuyez sur n’importe quelle touche pour terminer l’application.
Résumé
Lorsque vous rencontrez un problème, utilisez le débogueur et les commandes d’étape telles que F10 et F11 pour rechercher la région du code avec le problème.
Remarque
S’il est difficile d’identifier la région du code où le problème se produit, définissez un point d’arrêt dans le code qui s’exécute avant que le problème ne se produise, puis utilisez les commandes d’étape jusqu’à ce que vous voyiez le manifeste du problème. Vous pouvez également utiliser des points de trace pour enregistrer des messages dans la fenêtre Sortie. En examinant les messages enregistrés (et en notant quels messages n’ont pas encore été enregistrés !), vous pouvez souvent isoler la région du code avec le problème. Vous devrez peut-être répéter ce processus plusieurs fois pour le limiter.
Lorsque vous trouvez la région du code avec le problème, utilisez le débogueur pour examiner. Pour trouver la cause d’un problème, inspectez le code du problème lors de l’exécution de votre application dans le débogueur :
Inspecter les variables et vérifier si elles contiennent le type de valeurs qu’elles doivent contenir. Si vous trouvez une valeur incorrecte, découvrez où la valeur incorrecte a été définie (pour déterminer où la valeur a été définie, vous devrez peut-être redémarrer le débogueur, examiner la pile d’appels , ou les deux).
Vérifiez si votre application exécute le code attendu. (Par exemple, dans l’exemple d’application, nous nous attendions à ce que le code de l’instruction
switch
définisse le type de galaxie sur Irrégulier, mais l’application a ignoré le code en raison de la faute de frappe.)
Conseil
Vous utilisez un débogueur pour vous aider à trouver des bogues. Un outil de débogage est en mesure de trouver des bogues à votre place uniquement s’il connaît l’intention de votre code. Un outil ne peut connaître que l’intention de votre code si vous, le développeur, exprimez cette intention. Vous devez pour cela écrire des tests unitaires.
Étapes suivantes
Dans cet article, vous avez appris quelques concepts généraux de débogage. Ensuite, vous pouvez commencer à en savoir plus sur le débogueur.