Developpez.com

Le Club des Développeurs et IT Pro

Comment bien déboguer vos programmes ?

Partagez vos expériences

Le 2016-11-29 10:31:42, par Michael Guilloux, Chroniqueur Actualités
Apprendre un langage de programmation peut s’avérer être une expérience agréable. Mais le passage de la théorie et des exemples de cours à l’écriture d’un code pour répondre à un besoin réel est une expérience beaucoup moins intéressante lorsque le code ne fonctionne pas correctement. Le programmeur va rencontrer, dans son code, de nombreuses erreurs dont le processus de correction n’est pas toujours intuitif, surtout pour les débutants. Pour ces derniers en particulier, Hartley Brody, un développeur web full stack et lead technique a donc décidé de partager certains conseils de débogage pour détecter et corriger les erreurs dans leur code plus facilement.

1. Beaucoup utiliser la fonction Print. Cette fonction permet d’afficher des valeurs fournies en arguments. D’après Hartley, sur chaque ligne de code, vous devez avoir une idée claire des valeurs que prennent vos variables. Si vous avez un doute, il faudrait donc utiliser le Print pour voir comment changent les valeurs de vos variables quand vous exécutez votre code. Cette attitude peut vous permettre de découvrir très tôt que vos variables prennent certaines valeurs auxquelles vous ne vous attendiez pas, et donc de corriger le problème.

2. Commencer avec un code qui fonctionne déjà. Hartley suggère ici de chercher sur les moteurs de recherche un code existant qui fait ce que vous essayez de faire. Ensuite, exécutez le code pour vérifier qu’il fonctionne correctement et fait ce qu'il prétend faire. À partir de ce moment, vous pouvez faire de petits changements au code existant (pour l’adapter à votre besoin) et le tester au fur et à mesure pour voir si vos modifications ont introduit des bogues.

3. Exécuter votre code à chaque petit changement. Si vous passez une heure à coder avant d’exécuter votre programme pour la première fois, vous remarquerez probablement une quantité énorme de petites erreurs qui se sont glissées pendant que vous écriviez votre code. Examiner chaque erreur pour comprendre ce qui s’est passé et les corriger devient alors très fastidieux. Hartley recommande donc de ne pas laisser les erreurs s’empiler les unes sur les autres, mais de les corriger au fur et mesure. Pour cela, il faudrait, selon lui, exécuter régulièrement votre code à chaque petit changement, dans un intervalle de quelques minutes. « Plus la quantité de code que vous ajoutez à votre programme entre deux exécutions est grande, plus le nombre d’endroits où vous devrez revenir pour rechercher vos erreurs sera élevé », dit-il. Il ajoute encore qu’exécuter son code régulièrement permet de savoir si l'on se rapproche de ce qu’on veut, ou si l'on s’éloigne soudainement, et à quel moment.

4. Bien lire les messages d'erreur. En se basant sur son expérience, Hartley estime que deux tiers des messages d'erreur affichés sont assez précis et descriptifs pour donner une bonne idée des endroits où il faut commencer à chercher les erreurs. Il faudrait donc prendre soin de bien les lire avant de chercher ces erreurs.

5. Rechercher le message d'erreur sur Google. Si en lisant le message d’erreur, vous ne parvenez pas à comprendre ce qu’il essaie de vous dire, la chose à faire est de copier le message et de le coller dans la barre de recherche de Google ou d’un autre moteur de recherche. Il y a de fortes chances que votre problème ait déjà été résolu quelque part. Mais en fonction du caractère spécifique ou générique de votre message, vous trouverez plus ou moins vite vos réponses.

6. Deviner et vérifier. Une méthode un peu hasardeuse, mais tout de même conseillée par Hartley. Il propose de faire une hypothèse sur la manière de corriger le problème et de la vérifier. « Si vous n'êtes pas sûr à 100 % de comment corriger quelque chose, soyez disposé à essayer 2 ou 3 choses pour voir ce qui se passe… Cela corrige-t-il mon erreur ? Non ? Bon, revenons en arrière et essayons autre chose », explique-t-il. C’est probablement l’un des derniers recours lorsqu’on ne sait que faire. « Essayer certaines choses par vous-même est important parce que si vous allez demander de l'aide à quelqu'un d'autre, une des premières choses qu’on vous demandera est d'énumérer 2-3 choses que vous avez déjà essayées », dit-il. « Cela permet de sauver tout le monde en évitant les suggestions que vous avez déjà essayées et montre que vous êtes déterminé à résoudre votre problème et pas simplement à la recherche de quelqu'un d'autre pour vous donner gratuitement le code qui marche. »

7. Déguiser votre code en commentaire. Les commentaires ne servent pas seulement à décrire certaines actions que vous effectuez ou à laisser des notes dans votre code, mais aussi à demander au runtime de ne pas essayer d’exécuter certaines parties de votre code. Autrement dit, si vous ne souhaitez pas exécuter une partie de votre code, vous pouvez la déguiser en commentaire en ajoutant en début de ligne (et parfois à la fin), le caractère indiquant qu’il s’agit d’un commentaire. Cette approche permet de rendre l’exécution de votre code plus rapide et de faciliter la recherche de l’erreur dans le reste du code. Vous devez toutefois vous assurer que les variables utilisées dans le reste du programme ne soient pas dans la partie que vous voulez déguiser en commentaire.

8. Effectuer une recherche dichotomique. Il s’agit ici de diviser votre code en deux parties et d'exécuter chacune d’entre elles pour voir celle où se trouve le problème. Si elle est identifiée, on peut encore diviser cette partie en deux et suivre le même processus jusqu’à trouver les quelques lignes à l’origine du problème.
« Pour trouver des bogues dans votre script ou votre application Web, il suffit d'exécuter la première moitié de votre code, de déguiser la seconde moitié en commentaire, puis d'afficher les résultats à mi-chemin. Si ceux-ci apparaissent corrects, alors la première moitié de votre code fonctionne bien et le problème que vous rencontrez doit être dans la seconde moitié. S'il y a un problème avec les résultats à mi-chemin, alors l'erreur se produit quelque part dans la première moitié. Répétez ce processus encore et encore, et vous serez en mesure de trouver rapidement les 2 ou 3 lignes qui semblent être à l'origine du problème dans votre programme », explique Hartley. Vous pouvez remarquer que cette technique en combine bien d’autres, comme le fait de déguiser une partie du code en commentaire et l’utilisation de Print.

9. Faire une pause et s'éloigner du clavier. Il ne faut pas s’entêter quand plusieurs tentatives pour trouver et corriger un problème dans votre code échouent. C’est peut-être votre esprit qui est fatigué. Il faudrait donc songer à s’éloigner du clavier, et penser à autre chose. Quelque chose de relaxant ou divertissant pourrait vous permettre de retrouver vos esprits et de revenir plus tard, plus frais pour essayer une autre approche.

10. Savoir comment demander de l’aide. Si rien ne marche, vous devez penser à demander de l’aide à quelqu’un d’autre. Mais avant cela, Hartley estime qu’il est important de savoir préparer sa demande d’aide, qui devrait comprendre un certain nombre d’éléments comme une explication claire de ce que vous essayez de faire, le code et le message d’erreur, le résultat obtenu par le code et celui qui était attendu, ainsi que deux ou trois choses que vous avez essayées et pourquoi elles n’ont pas marché.

Tous ces conseils ciblent particulièrement les débutants, mais certains pourraient également concerner des développeurs expérimentés.

Source : Hartley Brody

Et vous ?

Qu’en pensez-vous ?
Quels sont les meilleurs conseils pour bien déboguer son code ?
  Discussion forum
86 commentaires
  • Nico_F
    Membre expérimenté
    Je suis surpris de ne pas y trouver ce que j'aurais mis au moins dans le top 3 à savoir le debug pas à pas.

    J'ignore s'il est disponible dans tous les langages mais dans ceux que j'utilise à savoir le PHP (avec Xdebug) et le Javascript (en console navigateur) c'est en général la solution à privilégier lorsqu'on ne souhaite pas accumuler les print (ou var_dump ou echo ou die et tutti quanti).

    Non seulement il permet de suivre le chemin parcouru par l'exécution du code mais également d'analyser la valeur chaque variable sans la dumper dans chaque méthode à analyser.
    Il possède aussi l'avantage lorsqu'on est un peu courageux/curieux de découvrir le fonctionnement du framework/de la lib que l'on utilise.

    Une méthode plus exotique que j'utilise parfois et qui donne souvent des résultats étonnamment efficaces c'est le rubber duck debugging
  • gstratege
    Membre actif
    Combien allez-vous aujourd'hui ?
  • Matthieu Vergne
    Expert éminent
    Franchement, je ne cautionne pas grand chose sur ces conseils :

    Envoyé par Michael Guilloux
    1. Beaucoup utiliser la fonction Print.
    Aujourd'hui, ce n'est pas cela qu'on devrait conseiller. Mais d'utiliser un débogueur, qui permet de faire la même chose et même mieux. Utiliser de temps en temps ce genre de combine pour un code dont on sait qu'on n'est pas sûr du comportement (en mettant un ensemble de print tout au long de la fonction) a une certaine utilité, mais beaucoup utiliser la fonction print c'est justement l'habitude à ne pas prendre (pour en privilégier de bonnes comme le débogueur).

    Envoyé par Michael Guilloux
    2. Commencer avec un code qui fonctionne déjà.
    Si on est un pro, les problèmes de licences sont à prendre en compte. Chercher sur le net c'est bien, mais ce n'est pas pour chercher du code, mais des bibliothèques à intégrer. Un bout de code copier-coller sur le net, ça peut poser problème d'un point de vue légal ! Mais vu comme l'auteur est un fan de scraping, même quand le site visé n'en veut pas, j'imagine que ce n'est pas ce qui le préoccupe le plus.

    Si en revanche on est un étudiant... c'est pas bien de recopier son voisin ! Bref, encore une fois non je ne le recommande pas. En tout cas pas de manière aussi naïve.

    Envoyé par Michael Guilloux
    3. Exécuter votre code à chaque petit changement.
    Là je suis d'accord.

    Envoyé par Michael Guilloux
    4. Bien lire les messages d'erreur.
    Là, encore, le conseil est bancal. Certes, les messages d'erreurs sont importants, mais j'ai presque envie de dire "qui ne les lie pas à part ceux qui ne veulent pas corriger, et donc pas programmer ?". Le soucis est bien que les messages d'erreurs ne sont pas forcément toujours clairs, surtout les messages génériques qui ne sont jamais en lien avec le contexte, ce qui peut poser problème quand le contexte est important. Le vrai conseil me semble-t-il est de mettre en place des messages d'erreurs dans ses propres fonctions. Quand une fonction peut retourner un code d'erreur, il ne faut pas l'ignorer (et attendre que ça explose on ne sait où avec un message ambiguë le jour où ça arrive). Il faut le récupérer et générer un message d'erreur en lien direct avec la fonction en question.

    Envoyé par Michael Guilloux
    5. Rechercher le message d'erreur sur Google.
    Oui, bon, sur Internet. Y'a pas que Google, hein !

    Envoyé par Michael Guilloux
    6. Deviner et vérifier. Une méthode un peu hasardeuse, mais tout de même conseillée par Hartley. Il propose de faire une hypothèse sur la manière de corriger le problème et de la vérifier. « Si vous n'êtes pas sûr à 100 % comment corriger quelque chose, soyez disposé à essayer 2 ou 3 choses pour voir ce qui se passe… Cela corrige-t-il mon erreur ? Non ? Bon, revenons en arrière et essayons autre chose », explique-t-il. C’est probablement l’un des derniers recours lorsqu’on ne sait que faire. « Essayer certaines choses par vous-même est important parce que si vous allez demander de l'aide à quelqu'un d'autre, une des premières choses qu’on vous demandera est d'énumérer 2-3 choses que vous avez déjà essayées », dit-il. « Cela permet de sauver tout le monde en évitant les suggestions que vous avez déjà essayées et montre que vous êtes déterminé à résoudre votre problème et pas simplement à la recherche de quelqu'un d'autre pour vous donner gratuitement le code qui marche. »
    La partie en gras, non je ne le conseille pas. Les corrections style j'essaye un truc, ça marche alors je passe, c'est à éviter. Ça ne montre qu'une seule chose : qu'on n'a pas compris à quoi on a affaire. Et ça, à moins d'avoir une batterie de tests pour éviter les régressions, c'est un comportement style bombe à retardement.

    La description est mieux, mais encore on oublie le plus important. L'important n'est pas de montrer qu'on a essayer des trucs, mais de comprendre le code qu'on a. Si on ne sait pas quoi faire, plutôt que d'essayer au hasard on peut aussi aller demander tout de suite... non pas comment modifier mais d'expliquer le message d'erreur ou le code déjà existant. Bien entendu, c'est si on parle d'un code pro sur lequel des collègues peuvent aider. Si on parle d'un code d'étudiant... à ben non, c'est pareil. On demande au copain ou au prof pour mieux comprendre à quoi on a affaire. Enfin, si c'est son propre code (le seule cas que je vois où on n'a personne à qui demander), ben dans ce cas il est temps d'arrêter les bêtises est de faire une vrai conception. Parce qu'amasser les lignes de code au point de ne plus comprendre ce qu'on fait, c'est clairement qu'on est parti du mauvais pied.

    Envoyé par Michael Guilloux
    7. Déguiser votre code en commentaire. Les commentaires ne servent pas seulement à décrire certaines actions que vous effectuez ou à laisser des notes dans votre code, mais aussi à demander au runtime de ne pas essayer d’exécuter certaines parties de votre code. Autrement dit, si vous ne souhaitez pas exécuter une partie de votre code, vous pouvez la déguiser en commentaire en ajoutant en début de ligne (et parfois à la fin), le caractère indiquant qu’il s’agit d’un commentaire. Cette approche permet de rendre l’exécution de votre code plus rapide et faciliter la recherche de l’erreur dans le reste du code. Vous devez toutefois vous assurer que les variables utilisées dans le reste du programme ne soient pas dans la partie que vous voulez déguiser en commentaire.
    ARGH ! On revient au premier commentaire : apprend à utiliser un débogueur, plutôt que de trafiquer le code pour le rendre débogable. Je vais finir par croire que ce ne sont pas des conseils pour des débutants mais des conseils de débutants.

    Envoyé par Michael Guilloux
    8. Effectuer une recherche binaire. Il s’agit ici de diviser votre code en deux parties et exécuter chacune d’entre elles pour voir celle où se trouve le problème. Si elle est identifiée, on peut encore diviser cette partie en deux et suivre le même processus jusqu’à trouver les quelques lignes à l’origine du problème.
    « Pour trouver des bogues dans votre script ou votre application Web, il suffit d'exécuter la première moitié de votre code, de déguiser la seconde moitié en commentaire, puis d'afficher les résultats à mi-chemin. Si ceux-ci apparaissent corrects, alors la première moitié de votre code fonctionne bien et le problème que vous rencontrez doit être dans la seconde moitié. S'il y a un problème avec les résultats à mi-chemin, alors l'erreur se produit quelque part dans la première moitié. Répétez ce processus encore et encore, et vous serez en mesure de trouver rapidement les 2 ou 3 lignes qui semblent être à l'origine du problème dans votre programme », explique Hartley. Vous pouvez remarquer que cette technique combine bien d’autres, comme le fait de déguiser une partie du code en commentaire et l’utilisation de Print.
    On dit dichotomique, pas binaire. {-_-}
    Et si de manière générale je peux cautionner un tel conseil, le détails qui cloche est qu'il parle de déguiser la moitié du code en commentaires... Autant dire qu'il y a des cas où ça ne marche pas. En plus qu'on parle encore de trafiquer le code pour le déboguer.

    Envoyé par Michael Guilloux
    9. Faire une pause et s'éloigner du clavier.
    Une bonne nuit de sommeil. Oui, là je suis d'accord.

    Envoyé par Michael Guilloux
    10. Savoir comment demander de l’aide.
    On est tous d'accord.
  • satenske
    Membre confirmé
    1. Beaucoup utiliser la fonction Print. Cette fonction permet d’afficher des valeurs fournies en arguments. D’après Hartley, sur chaque ligne de code, vous devez avoir une idée claire des valeurs que prennent vos variables. Si vous avez un doute, il faudrait donc utiliser le Print pour voir comment changent les valeurs de vos variables quand vous exécutez votre code. Cette attitude peut vous permettre de découvrir très tôt que vos variables prennent certaines valeurs auxquelles vous ne vous attendiez pas, et donc corriger le problème.
    Pour moi, la fonction print n'est pas fait pour ça. Le debug pas à pas et bien plus puissant, et nous permet de voir l'état complet de notre objet, et non ce que l'on veut bien afficher. Et dans le cadre d'un très grand volume de données, le print me parait contre productif. Alors qu'avec des breakpoints conditionnels...

    Sans parler des gens qui laissent des "print toto" en prod o/
  • Garvelienn
    Membre éprouvé
    Envoyé par Michael Guilloux
    Combien bien déboguer vos programmes ?
    ouch (ou alors je n'ai pas compris le jeu de mot si il y en a un )

    Sinon, cela dépend tellement du langage et du programme final qu'on ne peut pas répondre comme ça au sondage.

    ps: Il faudrait rajouter la recherche de bug par dichotomie avec print de variable
  • Ryu2000
    Membre extrêmement actif
    Je n'ai pas vu le choix "dérouler l’exécution en pas à pas grâce au débogueur".
    Mais bon, quelque part c'est comme utiliser PRINT.

    Bien lire les messages d'erreurs et s'éloigner du clavier, ça fonctionne bien.
    Souvent on se concentre sur un endroit précis et on peut passer des heures sans faire de progrès.

    Il faut faire complètement autre chose, se changer les idées.
    Quand on revient on est plus fixé sur un détail on voit plus large et très souvent on trouve la source du problème.
  • Alvaten
    Membre éprouvé
    Pour moi, la fonction print n'est pas fait pour ça. Le debug pas à pas et bien plus puissant, et nous permet de voir l'état complet de notre objet, et non ce que l'on veut bien afficher. Et dans le cadre d'un très grand volume de données, le print me parait contre productif. Alors qu'avec des breakpoints conditionnels...
    Gros +1, savoir utiliser efficacement le debuger de son IDE est pour moi le point le plus important.

    Sinon j'ai aussi voté pour "Faire une pause et s'éloigner du clavier", quand on à un problème et qu'on butte dessus, prendre du recul ça aide. Si on en en a la possibilité, montrer son problème à quelqu'un peut aussi aider, j'ai souvent remarqué que rien que faisant l'exercice d'expliquer sa problématique, ça permet de trouver une solution ou une piste sans même que l'autre n'intervienne.
  • EliXirr
    Membre habitué
    heu ... utiliser des points d’arrêts, on en parle pas dans les vote ?!?
  • Shepard
    Membre expérimenté
    Envoyé par hotcryx
    ou qui te retourne une BrolException
    J'ai un ami qui avait laissé traîner une PenisTooSmallException. Je vous laisse imaginer sa tête quand elle a été levée lors d'une défense de projet :p
  • kilroyFR
    Membre éprouvé
    Oui le "PRINT" est largement utile en PROD.

    La derniere trouvaille en date d'un developpeur chez nous... installer visual studio sur un serveur de PROD pour deboguer son programme
    (pourtant tous ces TU etaient OK ... ce qui lui avait fait dire qu'il pouvait enlever totalement les traces dans son soft ("ca sert a rien si les TU sont OK")

    Oui aux tests unitaires mais les tests fonctionnels de bout en bout (enchainement de plusieurs traitements) est largement plus important - et souvent c'est en PROD qu'on decouvre des situations en marge non prévues/mal identifiées.

    Personnellement je n'utilise jamais le debogueur et ca ne m'a jamais fait defaut (pourtant je fais beaucoup de C++ et pointeurs). Avec de la rigueur et en appliquant les principes du KISS (et eviter les mille feuilles logiciels 9 fois sur 10 on s'en sort rien qu'avec quelques traces bien placées - mon experience depuis 30 ans de devpt en tout cas).