Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Déboguer en vérifiant une chose à la fois

Après cette leçon: Je peux trouver un bogue en lisant l’erreur et en vérifiant une chose à la fois.

Leçon de 60 min13 commandesLab Linux du quotidien : la trentaine de commandes que les ingénieurs tapent de tête

Comment déboguer un programme qui se trompe

Déboguer, c’est trouver pourquoi un programme fait le mauvais travail, puis le corriger. Le plus dur n’est pas de taper la correction. C’est de savoir quoi regarder parmi cent choses.

Deviner et changer le code au hasard peut prendre un après-midi. Vérifier une chose à la fois prend quelques minutes. Cette leçon montre comment.

À la fin de cette leçon

Remarque

Je peux trouver un bogue en lisant l’erreur et en vérifiant une chose à la fois.

Mots-clés

MotCe que ça veut dire
Bogueune faute dans un programme qui lui fait faire le mauvais travail
Reproduirerefaire apparaître le bogue, de la même façon, à volonté
Trace d’erreurla liste des appels que Python affiche quand un programme s’arrête sur une erreur
Hypothèseune idée sur la cause qu’une seule vérification peut réfuter
Affichage de contrôleune ligne qui montre une valeur, pour voir ce que le programme contient vraiment
Coupe en deuxvérifier le milieu de ce qui reste, pour écarter la moitié à chaque fois

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

D’abord, faire apparaître le bogue à volonté

On ne corrige pas ce qu’on ne voit pas. Avant de changer quoi que ce soit, trouvez une entrée qui provoque le bogue à chaque fois, et gardez-la.

Ici, un petit programme calcule la moyenne des ventes d’un fichier, une ligne par jour. Les données ont un trou. Créez d’abord le dossier et le fichier.

Créer un dossier pour la leçon

Commande
mkdir -p ~/debogage

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Entrer dans le dossier

Commande
cd ~/debogage

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire le fichier des ventes

Commande
printf 'lun 120\nmar 80\nmer n/d\njeu 200\n' > ventes.txt

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire le programme du rapport

Commande
printf 'def lire_ligne(ligne):\n    jour, montant = ligne.split()\n    return jour, int(montant)\n\n\ndef moyenne(lignes):\n    total = 0\n    for ligne in lignes:\n        jour, montant = lire_ligne(ligne)\n        total = total + montant\n    return total / len(lignes)\n\n\nprint(moyenne(open("ventes.txt").read().splitlines()))\n' > rapport.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Le lancer et le voir s’arrêter

Commande
python3 rapport.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Lire une trace d’erreur en partant du bas

Une trace d’erreur liste les appels ouverts quand le programme s’est arrêté. L’appel le plus récent est en bas : lisez donc en partant du bas.

La dernière ligne dit ce qui s’est passé : ValueError, avec un message. La ligne File juste au-dessus dit où : un fichier, un numéro de ligne et une fonction. Les lignes plus haut disent par où le programme est passé.

Lister seulement les lignes File

Commande
python3 rapport.py 2>&1 | grep "File"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Vérifier une chose, puis la suivante

L’erreur montre où le programme s’est arrêté, pas pourquoi la donnée était fausse. Faites donc une hypothèse : une idée qu’une seule vérification peut réfuter.

Ici, l’idée est qu’une ligne des données n’est pas un nombre. Cherchez-la dans le fichier. Si la vérification ne trouve rien, l’idée était fausse, et c’est aussi un progrès.

Chercher le texte dans les données

Commande
grep -n "n/d" ventes.txt

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une correction rapide peut cacher le bogue suivant

La ligne 3 dit mer n/d : il n’y avait pas de chiffre de vente ce jour-là. Le changement le plus rapide est de le compter pour 0. Essayez, puis relancez le programme.

Compter un chiffre absent pour 0

Commande
sed -i 's|    return jour, int(montant)|    if montant == "n/d":\n        return jour, 0\n    return jour, int(montant)|' rapport.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Le relancer

Commande
python3 rapport.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Sans erreur, le bogue peut rester

Le programme s’est exécuté et a affiché 100.0. Or la moyenne des trois jours qui ont un chiffre, 120, 80 et 200, est 133.3. Le programme se trompe et ne dit rien.

Il n’y a plus de trace à lire. Ajoutez un affichage de contrôle à l’endroit où l’on additionne, et regardez ce que le programme contient vraiment.

Afficher chaque jour au moment de l’ajouter

Commande
sed -i 's|        total = total + montant|        print(jour, montant)\n        total = total + montant|' rapport.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Le lancer et lire chaque ligne

Commande
python3 rapport.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Couper le problème en deux

Le programme a quatre étapes. Vérifiez d’abord celle du milieu. Si le total est juste, la faute est après. S’il est faux, la faute est avant. Chaque vérification écarte la moitié.

C’est ainsi qu’une équipe trouve lequel de mille changements a cassé une fonction.

Exemple travaillé : vérifier les étapes

ÉtapeCe qu’elle devrait contenirCe qu’elle contenaitVerdict
Lire le fichier4 lignes4 lignesJuste
Lire chaque montant120, 80, n/d, 200120, 80, 0, 200Le 0 est un nombre inventé
Additionner400400Juste
Diviser par les jours comptés400 / 3 = 133.3400 / 4 = 100.0Un jour sans chiffre a été compté

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Réécrire le programme, avec la correction

Commande
printf 'def lire_ligne(ligne):\n    jour, montant = ligne.split()\n    if not montant.isdigit():\n        return None\n    return jour, int(montant)\n\n\ndef moyenne(lignes):\n    total = 0\n    nombre = 0\n    for ligne in lignes:\n        paire = lire_ligne(ligne)\n        if paire is not None:\n            total = total + paire[1]\n            nombre = nombre + 1\n    return total / nombre\n\n\nprint(round(moyenne(open("ventes.txt").read().splitlines()), 1))\n' > rapport.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Lancer le programme corrigé

Commande
python3 rapport.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une erreur fréquente

Attention

Beaucoup changent le code avant de connaître la cause, puis changent autre chose quand cela échoue. Après cinq changements, personne ne sait lequel a aidé. Vérifiez d’abord, changez une seule chose, puis relancez.

Pour aller plus loin : trouver le changement fautif

Une équipe garde chaque changement dans Git. Quand un bogue apparaît, elle sait qu’une ancienne version était bonne et que la dernière est mauvaise. La commande git bisect demande de tester la version du milieu, et coupe l’historique en deux jusqu’à ce qu’il ne reste qu’un changement.

Écrivez les étapes pour 1000 changements. Combien de versions testez-vous au plus ?

À propos de ce labo et de sa source: Lab Linux du quotidien : la trentaine de commandes que les ingénieurs tapent de tête

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.