Exercice - Déboguer avec Visual Studio Code

Effectué

Il est temps de mettre en pratique vos connaissances nouvellement acquises en débogage. C’est votre premier jour de travail, et il est temps de mettre en pratique vos compétences en matière de débogage .NET en corrigeant un bogue dans le produit phare de l’entreprise, une calculatrice Fibonacci.

Créer un exemple de projet .NET pour le débogage

Afin de configurer Visual Studio Code pour le débogage de .NET, nous avons d’abord besoin d’un projet .NET. Visual Studio Code comprend un terminal intégré qui facilite la création d’un projet.

  1. Dans Visual Studio Code, sélectionnez Fichier>Ouvrir un dossier.

  2. Créez un dossier nommé DotNetDebugging à l’emplacement de votre choix. Choisissez ensuite Sélectionner un dossier.

  3. Ouvrez le terminal intégré à partir de Visual Studio Code en sélectionnant Affichage>Terminal dans le menu principal.

  4. Dans la fenêtre de terminal, copiez et collez la commande suivante :

    dotnet new console
    

    Cette commande crée un fichier Program.cs dans votre dossier avec un programme « Hello World » de base déjà écrit. Elle crée également un fichier projet C# nommé DotNetDebugging.csproj.

  5. Dans la fenêtre de terminal, copiez et collez la commande suivante pour exécuter le programme « Hello World ».

    dotnet run
    

    La fenêtre de terminal affiche « Hello World ! » comme sortie.

Configurer Visual Studio Code pour le débogage de .NET

  1. Ouvrez Program.cs en le sélectionnant.

  2. La première fois que vous allez ouvrir un fichier C# dans Visual Studio Code, vous allez être invité à installer les extensions recommandées pour C#. Si vous voyez cette invite, sélectionnez le bouton Installer.

    Capture d’écran de l’invite Visual Studio Code à installer l’extension C#.

  3. Visual Studio Code va installer l’extension C# et afficher une autre invite à ajouter les ressources nécessaires pour générer et déboguer votre projet. Sélectionnez le bouton Oui.

    Capture d’écran de l’invite de Visual Studio Code à ajouter les ressources requises pour générer et déboguer votre projet .NET.

  4. Vous pouvez fermer l’onglet Extension : C# pour vous concentrer sur le code que nous allons déboguer.

Ajouter la logique du programme Fibonacci

Notre projet actuel affiche un message « Hello World » dans la console, et il n’y a donc pas grand chose à déboguer. Vous allez plutôt utiliser un petit programme .NET pour calculer la Nème valeur de la suite de Fibonacci.

La suite de Fibonacci est une suite de nombres qui commence par le nombre 0 et 1, tous les autres nombres suivants étant la somme des deux précédents. La séquence continue comme indiqué ici :

0, 1, 1, 2, 3, 5, 8, 13, 21...
  1. Ouvrez Program.cs en le sélectionnant.

  2. Remplacez le contenu du fichier Program.cs par le code suivant :

    int result = Fibonacci(5);
    Console.WriteLine(result);
    
    static int Fibonacci(int n)
    {
        int n1 = 0;
        int n2 = 1;
        int sum;
    
        for (int i = 2; i < n; i++)
        {
            sum = n1 + n2;
            n1 = n2;
            n2 = sum;
        }
    
        return n == 0 ? n1 : n2;
    }
    

    Notes

    Ce code contient une erreur, que nous allons déboguer plus tard dans ce module. Tant que ce bogue n’est pas corrigé, nous vous déconseillons d’utiliser cette méthode dans des applications Fibonacci critiques.

  3. Enregistrez le fichier en sélectionnant Ctrl+S sur Windows et Linux. Sélectionnez Cmd+S sur Mac.

  4. Voyons comment fonctionne le code mis à jour avant son débogage. Exécutez le programme en entrant la commande suivante dans le terminal :

    dotnet run
    

    Fenêtre de terminal avec sortie du programme modifiée.

  5. Le résultat, 3, est indiqué dans la sortie du terminal. Lorsque vous consultez ce graphique de séquence Fibonacci qui affiche la position de séquence de base zéro pour chaque valeur entre parenthèses, vous constatez que le résultat aurait dû être 5. Il est temps de vous familiariser avec le débogueur et de corriger ce programme.

    0 (0), 1 (1), 1 (2), 2 (3), 3 (4), 5 (5), 8 (6), 13 (7), 21 (8)...
    

Analyser les problèmes

  1. Démarrez le programme en sélectionnant l’onglet Exécuter et déboguer sur la gauche de l’écran, puis le bouton Démarrer le débogage. Vous devrez peut-être d’abord sélectionner le bouton Exécuter et déboguer, puis le fichier Program.cs.

    Capture d’écran du bouton Démarrer le débogage dans Visual Studio Code

    Le programme doit se terminer rapidement. En effet, vous n’avez pas encore ajouté de points d’arrêt.

  2. Si la console de débogage ne s’affiche pas, sélectionnez Ctrl+Maj+Y sur Windows et Linux ou Cmd+Maj+Y pour Mac. Plusieurs lignes d’informations de diagnostic doivent s’afficher, suivies de ces lignes à la fin :

    ...
    Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\System.Threading.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
    Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\System.Text.Encoding.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
    3
    The program '[88820] DotNetDebugging.dll' has exited with code 0 (0x0).
    

Les lignes du haut indiquent que les paramètres de débogage par défaut activent l’option « Uniquement mon code ». Cela signifie que le débogueur débogue uniquement votre code, et qu’il ne va pas effectuer un pas à pas détaillé dans le code source pour .NET, sauf si vous désactivez ce mode. Cette option vous permet de vous concentrer sur le débogage de votre code.

À la fin de la sortie de la console de débogage, le programme inscrit 3 dans la console, puis se ferme avec le code 0. En général, le code de sortie du programme 0 indique que le programme s’est exécuté et s’est arrêté sans blocage. Toutefois, il existe une différence entre le blocage et le renvoi de la valeur correcte. Dans ce cas, nous avons demandé au programme de calculer la cinquième valeur de la suite de Fibonacci :

0 (0), 1 (1), 1 (2), 2 (3), 3 (4), 5 (5), 8 (6), 13 (7), 21 (8)...

La cinquième valeur de cette liste est 5, mais notre programme a retourné 3. Utilisons le débogueur pour diagnostiquer et corriger cette erreur.

Utiliser des points d’arrêt et l’exécution pas à pas

  1. Ajoutez un point d’arrêt en cliquant dans la marge de gauche à la ligne 1 sur int result = Fibonacci(5);.

    Capture d’écran de l’emplacement du point d’arrêt dans le code

  2. Redémarrez le débogage. Le programme commence à s’exécuter. Il s’interrompt (suspend l’exécution) à la ligne 1 en raison du point d’arrêt que vous avez défini. Utilisez les contrôles du débogueur pour examiner en détail la fonction Fibonacci().

    Capture d’écran du bouton Pas à pas détaillé

Vérifier l’état de variables

Maintenant, prenez le temps d’inspecter les différentes valeurs des variables en utilisant le panneau Variables.

Capture d’écran du panneau Variables

  • Quelle est la valeur indiquée pour le paramètre n ?
  • Au début de l’exécution de la fonction, quelles sont les valeurs des variables locales n1, n2 et sum ?
  1. Nous allons ensuite avancer dans la boucle for à l’aide du contrôle du débogueur Pas à pas principal.

    Capture d’écran du bouton Pas à pas principal

  2. Continuez à avancer jusqu’à atteindre la première ligne à l’intérieur de la boucle for, ligne qui indique :

    sum = n1 + n2;
    

Notes

Vous avez peut-être remarqué que plusieurs pas sont nécessaires dans les commandes pour se déplacer dans la ligne for(...) {}. En effet, il existe plusieurs instructions sur cette ligne. Quand vous exécutez pas à pas, vous passez à l’instruction suivante de votre code. En général, il n’y a qu’une instruction par ligne. Si ce n’est pas le cas, vous avez besoin de plusieurs pas pour passer à la ligne suivante.

Réfléchir au code

Une partie importante du débogage consiste à prendre le temps d’émettre des suppositions informées sur les actions que tentent d’effectuer certaines parties du code (fonctions et blocs, telles que des boucles). Ne vous inquiétez pas si vous hésitez : cela fait partie du processus de débogage. Mais le fait d’être activement engagé dans le processus de débogage vous aidera à repérer plus rapidement les bogues.

Avant d’approfondir la question, rappelons que la suite de Fibonacci est une suite de nombres qui commence par le nombre 0 et 1, tous les autres nombres suivants étant la somme des deux précédents.

Cela signifie que :

Fibonacci(0) = 0
Fibonacci(1) = 1
Fibonacci(2) = 1 (0 + 1)
Fibonacci(3) = 2 (1 + 1)
Fibonacci(4) = 3 (1 + 2)
Fibonacci(5) = 5 (2 + 3)

En comprenant cette définition et en observant cette boucle for, nous pouvons déduire ce qui suit :

  1. La boucle calcule de la valeur 2 à n (le numéro de la suite de Fibonacci que nous recherchons).
  2. Si n est inférieure à 2, la boucle ne s’exécutera jamais. L’instruction return à la fin de la fonction retourne 0 si n a la valeur 0, et 1 si n est 1 ou 2. Il s’agit de la valeur 0, de la première valeur et de la deuxième valeur dans la suite de Fibonacci, par définition.
  3. Le cas le plus intéressant est lorsque n est supérieure à 2. Dans ce cas, la valeur actuelle est définie comme la somme des deux valeurs précédentes. Ainsi, pour cette boucle, n1 et n2 sont les deux valeurs précédentes, et sum est la valeur de l’itération actuelle. Pour cette raison, chaque fois que nous calculons la somme des deux valeurs précédentes et que nous l’avons définie sur sum, nous mettons à jour nos valeurs n1 et n2.

Bon, inutile de nous attarder trop ici. Nous pouvons nous reposer un peu sur notre débogueur. Mais cela vaut la peine d’examiner le code pour vérifier s’il fait ce que nous attendons et être mieux informés quand il ne le fait pas.

Rechercher le bogue avec des points d’arrêt

Le parcours de votre code peut être utile, bien que fastidieux, surtout lorsque utilisez des boucles ou d’autres codes appelés à plusieurs reprises. Au lieu d’exécuter pas à pas la boucle sans interruption, nous pouvons définir un nouveau point d’arrêt sur la première ligne de la boucle.

Dans ce cas, il important de définir une stratégie sur les endroits où nous plaçons nos points d’arrêt. Nous nous intéressons particulièrement à la valeur de sum, car elle représente la valeur de Fibonacci maximale actuelle. Pour cette raison, nous allons placer le point d’arrêt sur la ligne après la définition de sum.

  1. Ajoutez un deuxième point d’arrêt sur la ligne 13.

    Capture d’écran montrant la définition d’un deuxième point d’arrêt.

    Notes

    Si vous remarquez que vous continuez à exécuter votre code, puis une ligne ou deux, vous pouvez facilement mettre à jour vos points d’arrêt avec des lignes plus efficaces.

  2. Maintenant que nous avons un point d’arrêt correct défini dans la boucle, utilisez le contrôle du déboguer Continuer pour avancer jusqu’au point d’arrêt. En examinant nos variables locales, nous voyons les lignes suivantes :

    n [int]: 5
    n1 [int]: 0
    n2 [int]: 1
    sum [int]: 1
    i [int]: 2
    

    Ces lignes semblent toutes correctes. La première fois que vous parcourez la boucle, la sum des deux valeurs précédentes est 1. Au lieu d’avancer ligne par ligne, nous pouvons tirer parti de nos points d’arrêt pour accéder au prochain point d’arrêt par le biais de la boucle.

  3. Sélectionnez Continuer pour continuer l’exécution du programme jusqu’à atteindre le point d’arrêt suivant, qui intervient au prochain passage de la boucle.

    Notes

    Ne vous inquiétez pas trop si vous ignorez le bogue quand vous utilisez le contrôle Continuer. Il n’est pas rare d’avoir à déboguer le code plusieurs fois avant de trouver le problème. Souvent, vous perdez moins de temps à l’exécuter plusieurs fois, qu’à l’exécuter pas à pas en y prêtant une grande attention.

    Cette fois, nous voyons les valeurs suivantes :

    n [int]: 5
    n1 [int]: 1
    n2 [int]: 1
    sum [int]: 2
    i [int]: 3
    

    Prenons le temps de réfléchir. Ces valeurs sont-elles toujours pertinentes ? Cela semble être le cas. Pour le troisième nombre Fibonacci, nous pensions que notre opération sum serait égale à 2, et c’est effectivement le cas.

  4. Bon, sélectionnons Continuer pour relancer la boucle.

    n [int]: 5
    n1 [int]: 1
    n2 [int]: 2
    sum [int]: 3
    i [int]: 4
    

    Ici encore, tout semble correct. La quatrième valeur de la série est supposée être 3.

  5. À ce stade, vous commencez peut-être à vous demander si le code est finalement correct et si vous n’avez pas imaginé ce bogue ! Nous allons le conserver pour la dernière fois dans la boucle. Sélectionnez Continuer une dernière fois.

    Patientez une minute. Le programme a fini de s’exécuter et affiche la valeur 3 ! Cela ne va pas.

    Ne vous inquiétez pas. Nous n’avons pas échoué, nous avons appris. Nous savons maintenant que le code s’exécute correctement dans la boucle jusqu’à ce que i soit égal à 4, mais qu’il se termine avant de calculer la valeur finale. Je commence à avoir une petite idée de l’endroit où se trouve le bogue. Pas vous ?

  6. Nous allons définir un point d’arrêt supplémentaire sur la ligne 17, qui contient :

    return n == 0 ? n1 : n2;
    

    Ce point d’arrêt nous permet d’inspecter l’état du programme avant la fin de la fonction. Nous avons déjà appris tout ce que nous pouvons attendre de nos précédents points d’arrêt aux lignes 1 et 13 : nous pouvons donc les effacer.

  7. Supprimez les points d’arrêt précédents aux lignes 1 et 13. Vous pouvez faire cela en cliquant dessus dans la marge à côté des numéros de ligne, ou en décochant les cases des points d’arrêt pour les lignes 1 et 13 dans le volet Points d’arrêt de la partie inférieure gauche.

    Capture d’écran des points d’arrêt répertoriés dans le volet des points d’arrêt.

    Maintenant que nous comprenons mieux ce qui se passe et que nous avons défini un point d’arrêt pour accéder à notre programme en cas de dysfonctionnement, nous devrions être en mesure d’identifier ce bogue.

  8. Démarrez le débogueur une dernière fois.

    n [int]: 5
    n1 [int]: 2
    n2 [int]: 3
    sum [int]: 3
    

    Eh bien, ce n’est pas correct. Nous avons spécifiquement demandé Fibonacci(5) et nous avons obtenu Fibonacci(4). Cette fonction retourne n2, et chaque itération de la boucle calcule la valeur sum et définit une valeur n2 égale à sum.

    À partir de ces informations et de notre précédente exécution du débogage, nous pouvons voir que la boucle s’est arrêtée lorsque i était 4, et non pas 5.

    Examinons d’un peu plus près la première ligne de la boucle for.

    for (int i = 2; i < n; i++)
    

    OK, attendez une minute ! Cela signifie que l’exécution de la boucle s’arrête dès que le haut de la boucle for voit que i n’est plus inférieur à n. Cela signifie que le code de la boucle ne s’exécute pas quand i est égal à n. Il semble que nous voulions l’exécuter jusqu’à atteindre i <= n, mais à la place :

    for (int i = 2; i <= n; i++)
    

    Avec cette modification, votre programme mis à jour doit ressembler à cet exemple :

    int result = Fibonacci(5);
    Console.WriteLine(result);
    
    static int Fibonacci(int n)
    {
        int n1 = 0;
        int n2 = 1;
        int sum;
    
        for (int i = 2; i <= n; i++)
        {
            sum = n1 + n2;
            n1 = n2;
            n2 = sum;
        }
    
        return n == 0 ? n1 : n2;
    }
    
  9. Arrêtez la session de débogage si vous ne l’avez pas déjà fait.

  10. Apportez ensuite la modification précédente à la ligne 10, puis laissez le point d’arrêt à la ligne 17.

  11. Redémarrez le débogueur. Cette fois, lorsque nous atteignons le point d’arrêt à la ligne 17, les valeurs suivantes s’affichent :

    n [int]: 5
    n1 [int]: 3
    n2 [int]: 5
    sum [int]: 5
    

    Curieux ! On dirait que nous avons réussi ! Excellent travail, Fibonacci, Inc. vous doit une fière chandelle !

  12. Sélectionnez Continuer, juste pour vérifier que le programme retourne la valeur correcte.

    5
    The program '[105260] DotNetDebugging.dll' has exited with code 0 (0x0).
    

    Et il retourne effectivement la sortie correcte.

Vous avez réussi. Vous avez débogué du code que vous n’avez pas écrit à l’aide du débogueur .NET dans Visual Studio Code.

Dans l’unité suivante, vous allez apprendre à faciliter le débogage du code que vous écrivez à l’aide des fonctionnalités de journalisation et de suivi intégrées à .NET.