Guide du débogage pour grands débutants

S’applique à :yesVisual Studio no Visual Studio pour Mac noVisual Studio Code

Le code que nous écrivons en tant que développeurs de logiciels ne fait pas toujours ce que nous attendions. Il fait parfois quelque chose de totalement différent ! Dans ce cas, la tâche suivante consiste à déterminer pourquoi, et bien que nous puissions simplement regarder notre code pendant des heures, il est beaucoup plus facile et plus efficace d’utiliser un outil de débogage ou un débogueur.

Malheureusement, un débogueur n’est pas quelque chose qui peut révéler comme par magie tous les problèmes ou « bogues » dans notre code. Déboguer signifie exécuter votre code pas à pas dans un outil de débogage tel que Visual Studio afin de trouver le point exact où vous avez fait 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 pouvoir continuer à exécuter le programme.

L’utilisation efficace d’un débogueur est également une compétence qui nécessite du temps et des efforts, mais il s’agit d’une tâche essentielle que tout développeur de logiciels doit savoir effectuer. Dans cet article, nous présentons les principes fondamentaux du débogage et fournissons des conseils pour vous aider à démarrer.

Clarifiez le problème en vous posant les bonnes questions

Cela aide d’identifier clairement le problème que vous avez rencontré avant d’essayer de le résoudre. Nous supposons que vous avez déjà rencontré un problème dans votre code, sinon vous ne seriez pas ici à essayer de déterminer comment déboguer ! Par conséquent, avant de commencer le débogage, veillez à bien identifier le problème que vous cherchez à résoudre :

  • Que devait faire votre code initialement ?

  • Que s’est-il passé en réalité ?

    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 de code, généralement une erreur quelconque. Un outil de débogage vous permet d’accéder à l’emplacement exact dans votre code où l’exception s’est produite, et peut vous aider à examiner les solutions possibles.

    Si quelque chose d’autre s’est produit, quel est le symptôme du problème ? Avez-vous déjà une idée de l’emplacement où ce problème s’est produit dans votre code ? Par exemple, si votre code affiche du texte, mais que celui-ci est incorrect, vous savez que soit vos données sont incorrectes, soit le code qui définit le texte d’affichage présente un bogue. En parcourant le code pas à pas dans un débogueur, vous pouvez examiner chaque modification apportée à vos variables pour découvrir exactement quand et comment des valeurs incorrectes sont affectées.

Examinez vos hypothèses

Avant d’étudier un bogue ou une erreur, réfléchissez aux hypothèses qui vous ont mené à attendre certains résultats. Les hypothèses masquées ou inconnues peuvent se trouver dans la façon d’identifier un problème même lorsque vous examinez correctement la cause du problème dans un débogueur. Il se peut que vous ayez une longue liste d’hypothèses ! Voici quelques questions à se poser pour vous aider à y voir plus clair dans vos hypothèses.

  • Utilisez-vous la bonne API (autrement dit, l’objet, la fonction, la méthode ou la propriété adéquat) ? Une API que vous utilisez peut ne pas faire ce que vous pensez qu’elle fait. (Une fois que vous avez examiné l’appel d’API dans le débogueur, sa correction peut nécessiter un aller-retour vers la documentation pour aider à identifier l’API correcte.)

  • Utilisez-vous une API correctement ? Peut-être avez-vous utilisé la bonne API, mais pas de la bonne manière.

  • Votre code contient-il des fautes de frappe ? Certaines fautes de frappe, comme une simple faute d’orthographe dans le nom d’une variable, peuvent être difficiles à voir, en particulier quand vous travaillez avec des langages qui ne nécessitent pas la déclaration des variables avant leur utilisation.

  • Avez-vous apporté une modification à votre code et supposons 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 celle réellement présente ?

  • 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, vous devrez peut-être consacrer du temps à apprendre ce que fait exactement 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 ensemble 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 façon incrémentielle, en effectuant des tests à chaque stade.

Par la remise en question de vos hypothèses, vous pouvez réduire le temps nécessaire pour identifier un problème dans votre code. Vous pouvez également réduire le temps nécessaire pour résoudre un problème.

Parcourez votre code pas à pas en mode débogage pour déterminer où le problème s’est produit.

Quand vous exécutez normalement une application, vous voyez les erreurs et les résultats incorrects uniquement après l’exécution du code. Un programme peut également se terminer de façon inattendue sans vous indiquer pourquoi.

Quand vous exécutez une application dans un débogueur (autrement dit en mode débogage), le débogueur surveille activement tout ce qui se produit durant l’exécution du programme. Il vous permet également de suspendre l’application à n’importe quel moment pour examiner son état, puis de 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 du > menuDémarrer le débogage ou de l’icône du bouton Démarrer le débogage montrant le bouton Démarrer le débogage. Dans la barre d’outils Debug). Si des exceptions se produisent, l’Assistance sur 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 prise en charge des exceptions dans le 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’emplacement où rechercher le problème dans votre code. C’est dans ce cas-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 une fonctionnalité élémentaire et essentielle de toute procédure de 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 rapidement définir un point d’arrêt en cliquant dans la marge de gauche en regard d’une ligne de code, ou en plaçant le curseur sur une ligne et en appuyant sur F9.

Pour illustrer ces concepts, nous allons vous guider à travers un exemple de code qui a 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 des bogues)

Ensuite, nous allons créer une application qui contient quelques bogues.

  1. Visual Studio doit être installé et la charge de travail de développement multiplateforme .NET Core doit être installée.

    Si vous n’avez pas encore installé Visual Studio, accédez à la page Téléchargements Visual Studio pour l’installer gratuitement.

    Si vous avez besoin d’installer la charge de travail mais que Vous disposez déjà de Visual Studio, cliquez sur OutilsObtenir des outils> et des fonctionnalités. Visual Studio Installer est lancé. Choisissez la charge de travail de développement multiplateforme .NET Core , puis choisissez Modifier.

  2. Ouvrez Visual Studio.

    Dans la fenêtre de démarrage, choisissez Créer un projet. Tapez la console dans la zone de recherche, sélectionnez C# ou Visual Basic comme langage, puis choisissez Application console pour .NET Core. Choisissez Suivant. Tapez un nom de projet comme ConsoleApp_FirstApp , puis cliquez sur Suivant.

    Choisissez le framework cible recommandé ou .NET 6, puis choisissez Créer.

    ::: moniker-end

    Si vous ne voyez pas le modèle de projet d’application console pour .NET Core, accédez à ToolsGet Tools >and Features, qui ouvre le Visual Studio Installer. Choisissez la charge de travail de développement multiplateforme .NET Core , puis choisissez Modifier.

    Visual Studio crée le projet de console, qui apparaît dans Explorateur de solutions dans le volet droit.

  3. 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 consiste à afficher le nom de la galaxie, sa distance et son type dans une même 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 la galaxie, distance, type de galaxie.

Exécuter l’application

Appuyez sur F5 ou sur l’icône du bouton Démarrer le débogagemontrant 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

Et voici ce que nous obtenons à la place :

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 c’est le nom de la classe qui stocke le type galaxy. Nous essayons de montrer le type de galaxie réel (comme « Spirale »), pas le nom de classe !

Déboguer l’application

  1. Une fois l’application en cours d’exécution, insérez un point d’arrêt. Cliquez avec le bouton droit en regard de la Console.WriteLine méthode pour obtenir le menu contextuel et sélectionnez Insérer un point d’arrêt dans le menu volant.

    foreach (Galaxy theGalaxy in theGalaxies)
    {
        Console.WriteLine(theGalaxy.Name + "  " + theGalaxy.MegaLightYears + ",  " + theGalaxy.GalaxyType);
    }
    

    Quand vous définissez le point d’arrêt, un point rouge apparaît dans la marge de gauche.

    Comme nous voyons un problème dans la sortie, nous allons commencer le débogage en examinant le code précédent qui définit la sortie dans le débogueur.

  2. Cliquez sur l’icône Redémarrermontrant le bouton RedémarrerApp dans la barre d’outils Debug. Dans la barre d’outils Debug (Ctrl + Maj + F5).

    L’application s’interrompt au point d’arrêt que vous avez défini. 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).

  3. Placez le curseur sur la variable GalaxyType à droite puis, à gauche de l’icône de clé, développez theGalaxy.GalaxyType. Vous pouvez constater que GalaxyType contient une propriété MyGType, et que la valeur de propriété est définie sur Spiral.

    Capture d’écran du débogueur Visual Studio avec une ligne de code en jaune et un menu développé sous la propriétéGalaxy.GalaxyType à la fin de la ligne.

    « Spiral » est la valeur correcte que vous attendiez dans la console. Un bon point de départ consiste donc à pouvoir accéder à cette valeur dans ce code pendant l’exécution de l’application. Dans ce scénario, nous utilisons l’API incorrecte. Nous verrons si nous pouvons résoudre ce problème lors de l’exécution du code dans le débogueur.

  4. Dans le même code, toujours pendant le débogage, placez votre curseur à la fin de theGalaxy.GalaxyType et remplacez-le par theGalaxy.GalaxyType.MyGType. Bien que vous puissiez effectuer cette modification, l’éditeur de code signale une erreur indiquant qu’il ne peut pas compiler ce code. (En Visual Basic, vous ne verrez pas l’erreur et cette section de code fonctionne)

    Capture d’écran du débogueur Visual Studio avec une ligne de code mise en surbrillance en rouge et une boîte de message Modifier et Continuer avec le bouton Modifier sélectionné.

    Notes

    Pour déboguer l’exemple de code Visual Basic, ignorez les étapes suivantes jusqu’à ce que vous ayez demandé de cliquer sur l’icône Redémarrermontrant le bouton Redémarrer l’application dans la barre d’outils Debug.

  5. Cliquez sur Modifier dans la boîte de message Modifier et Continuer. Un message d’erreur s’affiche maintenant dans la fenêtre Liste d’erreurs. L’erreur indique que 'object' ne contient pas de définition pour MyGType.

    Capture d’écran du débogueur Visual Studio avec une ligne de code mise en surbrillance en rouge et une fenêtre Liste d’erreurs avec deux erreurs répertoriées.

    Même si nous définissons chaque galaxie avec un objet de type GType (qui a la MyGType propriété), le débogueur ne reconnaît pas l’objet theGalaxy comme un objet de type GType. Que se passe-t-il ? Vous devez examiner tout code qui définit le type de galaxie. Vous constatez alors que la classe GType a indubitablement une propriété MyGType, mais quelque chose ne va pas. Le message d’erreur concernant object s’avère être l’indice : pour l’interpréteur de langage, le type semble être un objet de type object au lieu d’un objet de type GType.

  6. En examinant votre code associé à la définition du type de galaxie, vous constatez que la propriété GalaxyType de la classe Galaxy est spécifiée comme object au lieu de GType.

    public object GalaxyType { get; set; }
    
  7. Remplacez le code précédent par ceci :

    public GType GalaxyType { get; set; }
    
  8. Cliquez sur l’icône Redémarrermontrant le bouton Redémarrer l’application dans la barre d’outils Debug. Dans la barre d’outils Debug (Ctrl + Maj + F5) pour recompiler le code et redémarrer.

    Maintenant, quand le débogueur s’arrête sur Console.WriteLine, vous pouvez pointer sur theGalaxy.GalaxyType.MyGType et vérifier que la valeur est définie correctement.

  9. 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êtSupprimer le point> d’arrêt), puis appuyez sur F5 pour continuer.

    L’application s’exécute et affiche la sortie. Il semble assez bon maintenant, mais vous remarquez une chose; vous vous attendiez à ce que la galaxie petit nuage magellanique s’affiche comme une galaxie irrégulière dans la sortie de la console, mais il 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
    
  10. Définissez un point d’arrêt sur cette ligne de code avant l’instruction switch (avant l’instruction Select en Visual Basic).

    public GType(char type)
    

    Ce code étant celui où le type de galaxie est défini, nous devons l’examiner plus en détail.

  11. Cliquez sur l’icône Redémarrermontrant le bouton Redémarrer l’application dans la barre d’outils Debug. Dans la barre d’outils Debug (Ctrl + Maj + F5) pour redémarrer.

    Le débogueur s’arrête sur la ligne de code où vous avez défini le point d’arrêt.

  12. Pointez sur la variable type. Vous voyez la valeur S (après le code de caractère). Vous êtes intéressé par une valeur de , comme vous savez que c’est un type de Igalaxie irrégulière.

  13. Appuyez sur F5 et pointez à nouveau sur la variable type. Répétez cette étape jusqu’à voir la valeur I dans la variable type.

    Capture d’écran du débogueur Visual Studio avec une ligne de code en jaune et une petite fenêtre montrant la valeur de la variable de type 73 « I ».

  14. Maintenant, appuyez sur F11 (Déboguer>Pas à pas détaillé ou le bouton Pas à pas détaillé dans la barre d’outils Débogage).

    F11 fait avancer le débogueur (et exécute le code) une seule instruction à la fois. F10 (Pas à pas principal) est une commande similaire, et toutes deux sont extrêmement utiles pour apprendre à utiliser le débogueur.

  15. Appuyez sur F11 jusqu’à ce que vous arrêtiez sur la ligne de code dans l’instruction switch pour obtenir la valeur « I » (Select instruction pour Visual Basic). Vous constatez ici un problème évident résultant d’une faute de frappe. Vous vous attendiez à ce que le code passe à l’emplacement où il se définit MyGType comme un type galaxy irrégulier, mais le débogueur ignore complètement ce code et s’interrompt complètement sur la default section de l’instruction switch (Else instruction en Visual Basic).

    Capture d’écran montrant l’erreur de faute de frappe.

    En examinant le code, vous voyez une faute de frappe dans l’instruction case 'l'. Elle doit avoir la valeur case 'I'.

  16. Cliquez dans le code case 'l' et remplacez-le par case 'I'.

  17. Supprimez votre point d’arrêt, puis cliquez sur le bouton Redémarrer pour redémarrer l’application.

    Les bogues sont maintenant corrigés et vous voyez la sortie attendue.

    Appuyez sur n’importe quelle touche pour fermer l’application.

Résumé

Quand vous constatez un problème, utilisez le débogueur et les commandes de pas à pas telles que F10 et F11 pour rechercher la région de code où se trouve le problème.

Notes

Si son identification est difficile, définissez un point d’arrêt dans le code qui s’exécute avant le moment où le problème se produit, puis utilisez les commandes de pas à pas jusqu’à ce que le problème se manifeste. 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 observant ceux qui n’ont pas encore été enregistrés), vous pouvez souvent isoler la région de code présentant un problème. Vous devrez peut-être répéter ce processus plusieurs fois afin de localiser l’emplacement précis du problème.

Une fois identifiée la région de code à problème, utilisez le débogueur pour l’examiner. Pour rechercher la cause d’un problème, inspectez le code défectueux tout en exécutant votre application dans le débogueur :

  • Inspectez les variables et vérifiez si elles contiennent le type de valeur prévu. Si vous trouvez une valeur incorrecte, recherchez où elle a été définie (vous devrez peut-être pour cela redémarrer le débogueur, examiner la pile des appels, ou les deux).

  • Vérifiez si votre application exécute le code prévu. (Par exemple, dans l’exemple d’application, nous nous attendions à ce que le code de l’instruction switch définisse le type galaxy sur Irrégulière, 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 peut trouver des bogues à votre place uniquement s’il connaît l’intention de votre code. Un outil ne peut avoir connaissance de l’intention de votre code que si vous, le développeur, exprimez cette intention. Vous devez pour cela écrire des tests unitaires.

Étapes suivantes

Dans cet article, vous avez découvert quelques concepts généraux liés au débogage. Vous pouvez à présent en découvrir plus sur le débogueur.