Déclencheurs
- debug
- debugging
- bug fix
- test failure
- test failing
- root cause
- broken test
- error trace
- stack trace
- unexpected behavior
- flaky test
- build failure
- integration issue
- performance problem
- why is this failing
- fix this bug
Débogage systématique
Vue d'ensemble
Les corrections aléatoires gaspillent du temps et créent de nouveaux bugs. Les patchs rapides masquent les problèmes sous-jacents.
Principe fondamental : TOUJOURS trouver la cause racine avant de tenter des corrections. Les corrections de symptômes sont un échec.
Violer la lettre de ce processus, c'est violer l'esprit du débogage.
La loi de fer
PAS DE CORRECTIONS SANS INVESTIGATION DE LA CAUSE RACINE D'ABORD
Si vous n'avez pas complété la Phase 1, vous ne pouvez pas proposer de corrections.
Quand l'utiliser
Utilisez-le pour TOUT problème technique :
- Défaillances de tests
- Bugs en production
- Comportements inattendus
- Problèmes de performance
- Défaillances de build
- Problèmes d'intégration
Utilisez-le SURTOUT quand :
- Vous êtes sous pression temporelle (les urgences rendent les suppositions tentantes)
- "Juste une correction rapide" semble évidente
- Vous avez déjà essayé plusieurs corrections
- La correction précédente n'a pas fonctionné
- Vous ne comprenez pas totalement le problème
Ne sautez pas quand :
- Le problème semble simple (les bugs simples ont aussi des causes racines)
- Vous êtes pressé (la précipitation garantit du travail à refaire)
- Le manager veut que ce soit corrigé MAINTENANT (le systématique est plus rapide que le patinage)
Les quatre phases
Vous DEVEZ compléter chaque phase avant de procéder à la suivante.
Phase 1 : Investigation de la cause racine
AVANT de tenter TOUTE correction :
-
Lire les messages d'erreur attentivement
- Ne sautez pas les erreurs ou les avertissements
- Ils contiennent souvent la solution exacte
- Lire les stack traces complètement
- Noter les numéros de ligne, les chemins de fichier, les codes d'erreur
-
Reproduire de manière cohérente
- Pouvez-vous le déclencher de manière fiable ?
- Quelles sont les étapes exactes ?
- Cela se produit-il à chaque fois ?
- Si non reproductible → rassembler plus de données, ne pas deviner
-
Vérifier les modifications récentes
- Qu'est-ce qui a changé et pourrait causer ceci ?
- Git diff, commits récents
- Nouvelles dépendances, changements de config
- Différences d'environnement
-
Rassembler les preuves dans les systèmes multi-composants
QUAND le système a plusieurs composants (CI → build → signing, API → service → database) :
AVANT de proposer des corrections, ajouter une instrumentation diagnostique :
Pour CHAQUE limite de composant : - Logger les données qui entrent dans le composant - Logger les données qui sortent du composant - Vérifier la propagation de l'environnement/config - Vérifier l'état à chaque couche Exécuter une fois pour rassembler les preuves montrant OÙ ça casse PUIS analyser les preuves pour identifier le composant défaillant PUIS enquêter sur ce composant spécifiqueExemple (système multi-couches) :
# Couche 1 : Workflow echo "=== Secrets disponibles dans le workflow: ===" echo "IDENTITY: ${IDENTITY:+SET}${IDENTITY:-UNSET}" # Couche 2 : Script de build echo "=== Variables d'env dans le script de build: ===" env | grep IDENTITY || echo "IDENTITY pas dans l'environnement" # Couche 3 : Script de signing echo "=== État du trousseau: ===" security list-keychains security find-identity -v # Couche 4 : Signing réel codesign --sign "$IDENTITY" --verbose=4 "$APP"Cela révèle : Quelle couche échoue (secrets → workflow ✓, workflow → build ✗)
-
Tracer le flux de données
QUAND l'erreur est profonde dans la pile d'appels :
Voir
root-cause-tracing.mddans ce répertoire pour la technique complète de traçage rétrograde.Version rapide :
- D'où provient la mauvaise valeur ?
- Qui a appelé ceci avec une mauvaise valeur ?
- Continuer à tracer jusqu'à trouver la source
- Corriger à la source, pas au symptôme
Phase 2 : Analyse des motifs
Trouver le motif avant de corriger :
-
Trouver des exemples fonctionnels
- Localiser un code similaire fonctionnant dans le même codebase
- Qu'est-ce qui fonctionne et qui est similaire à ce qui est cassé ?
-
Comparer par rapport aux références
- Si vous implémentez un motif, lire l'implémentation de référence COMPLÈTEMENT
- Ne pas survoler - lire chaque ligne
- Comprendre le motif entièrement avant de l'appliquer
-
Identifier les différences
- Qu'est-ce qui est différent entre le fonctionnement et le cassé ?
- Énumérer chaque différence, aussi petite soit-elle
- Ne pas supposer "ça ne peut pas avoir d'importance"
-
Comprendre les dépendances
- De quels autres composants ceci a-t-il besoin ?
- Quels paramètres, configurations, environnements ?
- Quelles hypothèses fait-il ?
Phase 3 : Hypothèse et test
Méthode scientifique :
-
Former une seule hypothèse
- Énoncer clairement : "Je pense que X est la cause racine parce que Y"
- L'écrire
- Être spécifique, pas vague
-
Tester minimalement
- Faire le PLUS PETIT changement possible pour tester l'hypothèse
- Une variable à la fois
- Ne pas corriger plusieurs choses à la fois
-
Vérifier avant de continuer
- Ça a fonctionné ? Oui → Phase 4
- Ça n'a pas fonctionné ? Former une NOUVELLE hypothèse
- NE PAS ajouter plus de corrections par-dessus
-
Quand vous ne savez pas
- Dire "Je ne comprends pas X"
- Ne pas prétendre savoir
- Demander de l'aide
- Faire plus de recherches
Phase 4 : Implémentation
Corriger la cause racine, pas le symptôme :
-
Créer un cas de test défaillant
- Reproduction la plus simple possible
- Test automatisé si possible
- Script de test ponctuel si pas de framework
- DOIT exister avant la correction
- Utiliser la compétence
test-driven-developmentpour écrire des tests défaillants appropriés
-
Implémenter une seule correction
- Adresser la cause racine identifiée
- UN changement à la fois
- Pas d'améliorations "tant que j'y suis"
- Pas de refactorisation groupée
-
Vérifier la correction
- Le test passe maintenant ?
- Pas d'autres tests cassés ?
- Le problème est vraiment résolu ?
-
Si la correction ne fonctionne pas
- ARRÊTER
- Compter : Combien de corrections avez-vous essayées ?
- Si < 3 : Retourner à la Phase 1, réanalyser avec les nouvelles informations
- Si ≥ 3 : ARRÊTER et remettre en question l'architecture (étape 5 ci-dessous)
- NE PAS tenter une 4e correction sans discussion architecturale
-
Si 3+ corrections ont échoué : Remettre en question l'architecture
Motif indiquant un problème architectural :
- Chaque correction révèle un nouvel état partagé/couplage/problème ailleurs
- Les corrections nécessitent une "refactorisation massive" pour être implémentées
- Chaque correction crée de nouveaux symptômes ailleurs
ARRÊTER et remettre en question les fondamentaux :
- Ce motif est-il fondamentalement sain ?
- Sommes-nous "coincés par pure inertie" ?
- Devrions-nous refactoriser l'architecture vs continuer à corriger les symptômes ?
Discuter avec l'utilisateur avant de tenter d'autres corrections
Ce n'est PAS une hypothèse échouée - c'est une architecture erronée.
Drapeaux rouges - ARRÊTER et suivre le processus
Si vous vous surprenez à penser :
- "Correction rapide pour maintenant, investigation plus tard"
- "Juste essayer de changer X et voir si ça marche"
- "Ajouter plusieurs changements, exécuter les tests"
- "Sauter le test, je vais vérifier manuellement"
- "C'est probablement X, laissez-moi corriger ça"
- "Je ne comprends pas totalement mais ça pourrait fonctionner"
- "Le motif dit X mais je vais l'adapter différemment"
- "Voici les principaux problèmes : [énumère les corrections sans investigation]"
- Proposer des solutions avant de tracer le flux de données
- "Une correction de plus" (quand déjà essayé 2+)
- Chaque correction révèle un nouveau problème ailleurs
TOUS ceux-ci signifient : ARRÊTER. Retourner à la Phase 1.
Si 3+ corrections ont échoué : Remettre en question l'architecture (voir Phase 4.5)
Les signaux de l'utilisateur que vous vous trompez
Observez ces redirections :
- "Ça ne se passe pas ?" - Vous avez supposé sans vérifier
- "Ça nous montrera...?" - Vous auriez dû ajouter la collecte de preuves
- "Arrêtez de deviner" - Vous proposez des corrections sans comprendre
- "Pensez-y ultra bien" - Remettre en question les fondamentaux, pas seulement les symptômes
- "Nous sommes bloqués ?" (frustré) - Votre approche ne fonctionne pas
Quand vous voyez ceux-ci : ARRÊTER. Retourner à la Phase 1.
Rationalisations courantes
| Excuse | Réalité |
|---|---|
| "Le problème est simple, pas besoin du processus" | Les problèmes simples ont aussi des causes racines. Le processus est rapide pour les bugs simples. |
| "Urgence, pas le temps pour le processus" | Le débogage systématique est PLUS RAPIDE que le patinage du devinage. |
| "Juste essayer d'abord, puis enquêter" | La première correction définit le motif. Faire correctement dès le début. |
| "Je vais écrire le test après la confirmation de la correction" | Les corrections non testées ne restent pas. Le test en premier le prouve. |
| "Plusieurs corrections à la fois économise du temps" | Impossible d'isoler ce qui a fonctionné. Cause de nouveaux bugs. |
| "La référence est trop longue, je vais adapter le motif" | La compréhension partielle garantit des bugs. La lire complètement. |
| "Je vois le problème, laissez-moi le corriger" | Voir les symptômes ≠ comprendre la cause racine. |
| "Une correction de plus" (après 2+ échecs) | 3+ échecs = problème architectural. Remettre en question le motif, ne pas corriger à nouveau. |
Référence rapide
| Phase | Activités clés | Critères de succès |
|---|---|---|
| 1. Cause racine | Lire les erreurs, reproduire, vérifier les changements, rassembler les preuves | Comprendre QUOI et POURQUOI |
| 2. Motif | Trouver des exemples fonctionnels, comparer | Identifier les différences |
| 3. Hypothèse | Former une théorie, tester minimalement | Confirmée ou nouvelle hypothèse |
| 4. Implémentation | Créer un test, corriger, vérifier | Bug résolu, tests réussissent |
Quand le processus révèle "Pas de cause racine"
Si l'investigation systématique révèle que le problème est vraiment environnemental, dépendant du temps, ou externe :
- Vous avez complété le processus
- Documenter ce que vous avez enquêté
- Implémenter une gestion appropriée (retry, timeout, message d'erreur)
- Ajouter la surveillance/logging pour une future investigation
Mais : 95% des cas "pas de cause racine" sont une investigation incomplète.
Techniques de soutien
Ces techniques font partie du débogage systématique et sont disponibles dans ce répertoire :
root-cause-tracing.md- Tracer les bugs rétrograde à travers la pile d'appels pour trouver le déclencheur originaldefense-in-depth.md- Ajouter la validation à plusieurs couches après avoir trouvé la cause racinecondition-based-waiting.md- Remplacer les timeouts arbitraires par le polling basé sur les conditions
Compétences connexes :
- test-driven-development - Pour créer un cas de test défaillant (Phase 4, Étape 1)
- verification-before-completion - Vérifier que la correction a fonctionné avant de déclarer le succès
Impact réel
À partir des sessions de débogage :
- Approche systématique : 15-30 minutes pour corriger
- Approche des corrections aléatoires : 2-3 heures de patinage
- Taux de correction au premier essai : 95% vs 40%
- Nouveaux bugs introduits : Près de zéro vs courant
Vérifier
- La cause racine est énoncée en une phrase et est soutenue par un artefact concret (stack trace, ligne de log, diff, sortie du profiler)
- Le reproducteur est minimal et s'exécute localement ; la commande exacte et la sortie observée sont capturées
- La correction a été vérifiée en réexécutant le reproducteur et en montrant que la sortie précédemment défaillante réussit maintenant
- Un test de régression (ou monitoring/alerte) a été ajouté pour que le même bug soit attrapé automatiquement la prochaine fois
- Les chemins de code adjacents qui partagent le même mode de défaillance ont été vérifiés, pas seulement le symptôme signalé
- Si la correction touche la sécurité, les performances ou l'intégrité des données, le compromis est nommé et quantifié