Déboguer pas à pas
Points d’arrêt, pas à pas et inspection des variables.
Objectifs
À la fin de cette leçon, vous saurez :
- utiliser un point d'arrêt pour figer l'exécution ;
- distinguer step over, step into et continue ;
- inspecter les variables locales et la call stack pendant l'arrêt ;
- choisir entre console.log ciblé et débogueur.
🔗 Pour vous rafraîchir la mémoire : lire une stack trace
Deux outils complémentaires
Le console.log stratégique reste l'outil n°1 du développeur : rapide, sans configuration. Le débogueur devient indispensable quand la logique s'enchevêtre : il permet d'exécuter le programme ligne par ligne en regardant l'état réel des variables.
console.log ciblé → « quelle est la valeur ici ? » (question ponctuelle)
débogueur → « pourquoi l'état global arrive-t-il là ? » (enquête)
Les commandes du débogueur
Cinq gestes couvrent 95 % des besoins :
| Commande | Effet |
|---|---|
| breakpoint | fige l'exécution à une ligne donnée |
| continue | reprend jusqu'au prochain point d'arrêt |
| step over | exécute la ligne courante, sans entrer dans la fonction |
| step into | entre dans la fonction appelée par la ligne courante |
| call stack + variables | montre où l'on est et avec quelles valeurs |
Règle pratique : step over par défaut ; step into seulement quand vous soupçonnez la fonction appelée.
Démonstration avec node inspect
Node intègre un débogueur en ligne de commande. Prenons ce fichier, somme-bug.js :
function cumulJusqua(limite) {
let total = 0;
for (let i = 1; i <= limite; i++) {
total += i;
}
return total;
}
console.log(cumulJusqua(5)); // attendu : 15
console.log(cumulJusqua(0)); // attendu : 0... vraiment ?
Lançons sous débogueur :
node inspect somme-bug.js
Session type :
debug> sb(2) ← setBreakpoint : point d'arrêt ligne 2
debug> c ← continue : démarrage, puis arrêt au point d'arrêt
debug> repl ← mode interactif : inspecter l'état courant
> limite ← valeur actuelle de la variable dans ce contexte
debug> n ← next : exécuter la ligne suivante
debug> watch("total") ← surveiller une variable
debug> watchers ← afficher les valeurs surveillées
debug> c ← reprendre jusqu'à la fin
Dans VS Code (recommandé dès que possible) : panneau Run and Debug, clic dans la marge pour poser un breakpoint, puis F10 = step over, F11 = step into, F5 = continue. La colonne de gauche montre variables locales et call stack en continu — exactement la table ci-dessus.
Ce qu'on cherche en pas à pas
Un débogage efficace suit un plan :
- Poser le breakpoint avant l'endroit suspect (pas dessus).
- Avancer et observer : chaque variable a-t-elle la valeur attendue ?
- Au premier écart attendu/réel : la cause est sur la ou les lignes précédentes.
- Corriger UNE chose, relancer depuis zéro, vérifier.
Quand le bug disparaît sous le débogueur
Phénomène célèbre (effet Heisenbug) : tout semble correct pendant l'enquête. Causes fréquentes :
- le code exécuté n'est pas le code sauvegardé (fichier non rechargé) ;
- le timing change sous débogueur (cas asynchrone — chapitre ultérieur).
Premier réflexe alors : vérifier que vous exécutez bien le fichier modifié, puis ajouter des logs plutôt que des pauses.
Exercice
Soit ce programme volontairement faux, compteur-bug.js :
function decompte(n) {
let resultat = "";
for (let i = n; i > 0; i--) {
resultat += i;
}
return resultat;
}
const attendu = "321";
const obtenu = decompte(3);
console.log(attendu === obtenu); // false : pourquoi ?
- Sans exécuter : trouvez-vous déjà le bug ?
- Décrivez votre plan de débogage : où posez-vous le breakpoint ?
- Quelles variables surveillez-vous, et auxquels tours de boucle ?
- Quelle correction unique répare le programme ?
Résumé
- Breakpoint → continue / step over / step into : le trio fondamental.
- On observe variables locales et call stack à chaque arrêt.
- Breakpoint AVANT la zone suspecte ; cause toujours en amont du symptôme.
- console.log pour les questions ponctuelles, débogueur pour l'enquête complète.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Réponses détaillées
1. Peut-être ! resultat += i concatène des nombres en chaînes : "3", puis "32", puis "321"… En fait, pour n = 3, ça marche. Mais imaginez decompte(10) : le résultat serait "10987654321". Le vrai piège pédagogique de cet exercice : vérifier vos certitudes par l'exécution. Si votre prédiction était « true » sans avoir pensé à i = 10, c'est exactement le rôle du débogueur : tester au lieu de supposer.
2. Breakpoint sur la ligne resultat += i (pas sur return). Premier arrêt : avant le premier tour, toutes les initialisations visibles.
3. resultat et i, à chaque tour :
tour 1 : i = 3, resultat = "3"
tour 2 : i = 2, resultat = "32"
tour 3 : i = 1, resultat = "321"
sortie : retour "321"
4. Pour ce cas précis, aucune correction n'est nécessaire si l'intention est bien la concaténation — et c'est justement LA question à se poser : que voulait l'auteur ? S'il voulait un nombre décroissant affiché séparé ("3 2 1"), la correction serait resultat += i + " " ou resultat += (resultat ? " " : "") + i. L'exercice démontre la règle finale du chapitre : définir le résultat attendu avant de chercher le bug.