Débogage C# : de « pourquoi ça ne marche pas ? » à « je sais où est l'erreur »
\n\nTout développeur C# rencontre un jour ou l'autre une situation où le code compile, s'exécute, mais fait complètement autre chose que ce qui était attendu. Ou bien il plante avec une erreur impossible à reproduire en environnement de test. Dans ces moments-là, le débogage C# passe d'une tâche routinière à un véritable art.
\n\nDans cet article, nous allons explorer les techniques et outils qui vous aideront non seulement à trouver le bug, mais à le faire rapidement et efficacement. Nous ne nous limiterons pas au simple F5 — nous aborderons les points d'arrêt avancés, les expressions conditionnelles, l'analyse mémoire et même le travail avec les dumps dans WinDbg. C'est parti !
\n\nTechniques de débogage C# basiques mais puissantes
\n\nAvant de passer aux outils exotiques, assurons-nous que vous tirez le maximum de Visual Studio. De nombreux développeurs n'utilisent que F9 (poser un point d'arrêt) et F10 (pas à pas principal), et c'est dommage.
Points d'arrêt conditionnels (Conditional Breakpoints)
\n\nImaginez : vous avez une boucle de 1000 itérations, et le bug n'apparaît qu'à la 567e. Poser un point d'arrêt et appuyer sur F5 567 fois ? Non. Utilisez les points d'arrêt conditionnels.
\n\nfor (int i = 0; i < 1000; i++)\n{\n // Une logique quelconque\n ProcessItem(items[i]);\n}\n\nFaites un clic droit sur le cercle rouge du point d'arrêt → choisissez « Conditions » → entrez i == 567. Lorsque le compteur atteint la valeur souhaitée, le débogueur s'arrête automatiquement. Cela vous fait gagner des heures.
Comme condition, vous pouvez utiliser non seulement une comparaison, mais aussi n'importe quelle expression booléenne en C#. Par exemple : items[i].IsValid == false && items[i].Id > 100.
Points d'arrêt avec actions (Tracepoints / Actions)
\n\nParfois, vous n'avez pas besoin d'arrêter l'exécution, mais simplement de journaliser un message à un moment précis. C'est là qu'interviennent les points d'arrêt avec actions. Posez un point d'arrêt, faites un clic droit → « Actions » → entrez un message comme Méthode appelée avec le paramètre : {parameter}.
Cela fonctionne comme un Console.WriteLine, mais sans modifier le code. Vous pouvez afficher les valeurs des variables directement dans la fenêtre Output, sans interrompre l'application.
« S'attacher au processus » (Attach to Process)
\n\nIl vous est déjà arrivé qu'un bug ne se reproduise qu'en production, mais pas en local ? Utilisez Debug → Attach to Process. Vous pouvez vous connecter à un processus déjà en cours d'exécution (par exemple, IIS, un service Windows ou une application de bureau).
Un détail important : assurez-vous de disposer des fichiers PDB (symboles) pour la version de l'assembly qui est exécutée. Sinon, au lieu des noms de variables, vous verrez Variable1 et Variable2.
Techniques avancées : diagnostic sans interruption
\n\nTous les bugs ne peuvent pas être attrapés dans le débogueur. Parfois, l'arrêt de l'exécution modifie le comportement du programme (par exemple, à cause des timings dans le code multithread). Pour ces cas, il existe d'autres techniques de débogage C#.
\n\nJournalisation avec DiagnosticSource et Serilog
\n\nLe System.Diagnostics.Trace intégré est correct, mais pour les projets sérieux, il est préférable d'utiliser une journalisation structurée. Serilog est l'un des journaliseurs les plus populaires pour .NET.
using Serilog;\n\nLog.Logger = new LoggerConfiguration()\n .WriteTo.Console()\n .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day)\n .CreateLogger();\n\ntry\n{\n var result = SomeRiskyOperation();\n Log.Information("Opération réussie. Résultat : {Result}", result);\n}\ncatch (Exception ex)\n{\n Log.Error(ex, "Erreur lors de l'exécution de l'opération");\n}\n\nLes journaux structurés permettent de rechercher des erreurs non pas par texte, mais par champs. Par exemple, vous pouvez trouver tous les logs avec OrderId = 12345 pour la dernière heure. C'est plus puissant qu'un grep sur un fichier texte.