web-dev-qa-db-fra.com

Comment déboguer le code le plus efficacement possible?

Les bogues qui se glissent dans le code peuvent être minimisés, mais pas entièrement éliminés tels qu'ils sont écrits - les programmeurs ne sont, bien que beaucoup en désaccord , que des humains.

Lorsque nous détectons une erreur dans notre code, que pouvons-nous faire pour l'éliminer? Comment devrions-nous l'aborder pour tirer le meilleur parti de notre temps précieux et nous permettre de passer moins de temps à essayer de le trouver et plus de temps à coder? Aussi, que devons-nous éviter lors du débogage?

Notez ici que nous ne parlons pas de la prévention des bugs; nous parlons de ce qu'il faut faire lorsque des bugs apparaissent . Il s'agit d'un vaste domaine, je le sais, et peut dépendre fortement de la langue, de la plate-forme et des outils. Si oui, continuez à inclure des réponses telles que les mentalités et les méthodes générales.

33
gablin

L'état d'esprit et l'attitude envers le débogage sont peut-être la partie la plus importante, car ils déterminent l'efficacité avec laquelle vous corrigerez l'erreur et ce que vous en apprendrez - le cas échéant.

Les classiques du développement logiciel comme Le programmeur pragmatique et Code complet plaident pour la même approche: chaque erreur est une opportunité pour apprendre, presque toujours sur vous-même (car seuls les débutants blâment d'abord le compilateur/ordinateur).

Traitez-le donc comme un mystère qu'il sera intéressant de percer. Et percer ce mystère devrait être fait systématiquement, en exprimant nos hypothèses (à nous-mêmes ou à d'autres), puis en testant nos hypothèses, une par une si besoin est, en utilisant tous les outils à notre disposition, en particulier les débogueurs et les cadres de test automatisés. Ensuite, une fois le mystère résolu, vous pouvez faire encore mieux en recherchant dans tout votre code les erreurs similaires que vous avez pu commettre; et rédigez un test automatisé pour vous assurer que l'erreur ne se reproduira pas sans le savoir.

Une dernière note - je préfère appeler les erreurs "erreurs" et non "bogues" - Dijkstra a réprimandé ses collègues pour utiliser ce dernier terme parce qu'il est malhonnête, soutenant l'idée que les fées de bogues pernicieuses et inconstantes ont planté des bogues dans nos programmes pendant que nous étions t regarder, au lieu d'être là à cause de notre propre pensée (bâclée): http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1036.html

Nous pourrions, par exemple, commencer par nettoyer notre langue en n'appelant plus un bug un bug mais en l'appelant une erreur. C'est beaucoup plus honnête, car il met carrément la faute à sa place, à savoir. avec le programmeur qui a fait l'erreur. La métaphore animiste du bogue qui s'est glissée avec malveillance alors que le programmeur ne regardait pas est malhonnête intellectuellement car elle dissimule que l'erreur est la propre création du programmeur. Ce qui est bien avec ce simple changement de vocabulaire, c'est qu'il a un effet si profond: alors qu'avant, un programme avec un seul bogue était "presque correct", ensuite un programme avec une erreur est tout simplement "mauvais" (parce qu'en Erreur).

38
limist
  1. Écrivez des tests. Les tests sont non seulement excellents pour prévenir les bogues (d'après mon expérience, TDD bien fait élimine presque tous les bogues triviaux et stupides), mais aide également beaucoup au débogage. Les tests obligent votre conception à être plutôt modulaire, ce qui facilite l'isolement et la reproduction du problème. De plus, vous contrôlez l'environnement, il y aura donc beaucoup moins de surprises. De plus, une fois que vous avez un cas de test défaillant, vous pouvez être raisonnablement sûr que vous avez identifié la vraie raison du comportement qui vous dérange.

  2. Apprenez à utiliser un débogueur. print Les instructions peuvent fonctionner raisonnablement bien à un certain niveau, mais un débogueur la plupart du temps est très utile (et une fois que vous savez comment utilisez-le, c'est beaucoup plus confortable que les instructions print).

  3. Parlez de quelqu'un à propos de votre problème, même si ce n'est qu'un canard en caoutchouc . Vous forcer à exprimer le problème sur lequel vous travaillez en mots fait vraiment des miracles.

  4. Donnez-vous une limite de temps. Si, par exemple, après 45 minutes, vous sentez que vous n'allez nulle part, passez simplement à d'autres tâches pendant un certain temps. Lorsque vous reviendrez à votre bug, vous pourrez, espérons-le, voir d'autres solutions possibles que vous n'auriez pas envisagées auparavant.

16
Ryszard Szopa

Il y a un excellent livre que j'ai lu sur ce sujet appelé Why Programs Fail , qui décrit diverses stratégies pour trouver des bogues allant de l'application de la méthode scientifique pour isoler et résoudre un bogue au débogage delta. L'autre partie intéressante de ce livre est qu'il supprime le terme "bug". L'approche de Zeller est la suivante:

(1) Un programmeur crée un défaut dans le code. (2) Le défaut provoque une infection (3) L'infection se propage (4) L'infection provoque une défaillance.

Si vous souhaitez améliorer vos compétences de débogage, je recommande fortement ce livre.

Dans ma propre expérience personnelle, j'ai trouvé beaucoup de bugs dans notre application, mais la direction nous pousse simplement à sortir de nouvelles fonctionnalités. J'ai souvent entendu "Nous avons trouvé ce bogue nous-mêmes et le client ne l'a pas encore remarqué, alors laissez-le jusqu'à ce qu'il le fasse". Je pense qu'être réactif plutôt que proactif dans la correction des bogues est une très mauvaise idée car lorsque vient le temps de mettre un correctif, vous avez d'autres problèmes qui doivent être résolus et plus de gestion des fonctionnalités veulent sortir dès que possible, donc vous êtes pris dans un cercle vicieux qui peut entraîner beaucoup de stress et de burn-out et, finalement, un système défectueux.

La communication est également un autre facteur lorsque des bogues sont détectés. L'envoi d'un e-mail ou sa documentation sur le traqueur de bogues est très bien, mais selon ma propre expérience, d'autres développeurs trouvent un bogue similaire et plutôt que de réutiliser la solution que vous avez mise pour corriger le code (car ils ont tout oublié ), ils ajoutent leurs propres versions, vous avez donc 5 solutions différentes dans votre code et cela semble plus gonflé et déroutant en conséquence. Donc, lorsque vous corrigez un bogue, assurez-vous que quelques personnes examinent le correctif et vous donnent des commentaires au cas où ils auraient corrigé quelque chose de similaire et trouvé une bonne stratégie pour y remédier.

limist a mentionné le livre The Pragmatic Programmer qui contient des informations intéressantes sur la correction des bogues. En utilisant l'exemple que j'ai donné dans le paragraphe précédent, je regarderais ceci: Software Entrophy , où l'analogie d'une veuve cassée est utilisée. Si deux nombreuses fenêtres cassées apparaissent, votre équipe peut devenir apathique à l'idée de la réparer, à moins que vous ne preniez une position proactive.

3
Desolate Planet

J'aime la plupart des autres réponses, mais voici quelques conseils sur ce qu'il faut faire AVANT de faire tout cela. Vous fera gagner beaucoup de temps.

  1. Déterminez s'il y a vraiment un bug. Un bogue est TOUJOURS une différence entre le comportement du système et les exigences; le testeur doit être capable d'articuler le comportement attendu et réel. S'il n'est pas en mesure de fournir une assistance pour le comportement attendu, il n'y a aucune exigence et il n'y a pas de bug - juste l'opinion de quelqu'un. Renvoie le.

  2. Considérez la possibilité que le comportement attendu soit incorrect. Cela pourrait être dû à une mauvaise interprétation de l'exigence. Cela pourrait également être dû à un défaut de l'exigence elle-même (un delta entre une exigence détaillée et une exigence commerciale). Vous pouvez également les renvoyer.

  3. Isolez le problème. Seule l'expérience vous apprendra le moyen le plus rapide de le faire - certaines personnes peuvent presque le faire avec leurs tripes. Une approche de base consiste à varier une chose tout en gardant toutes les autres choses constantes (le problème se produit-il dans d'autres environnements? Avec d'autres navigateurs? Dans une région de test différente? À différents moments de la journée?) Une autre approche consiste à examiner les vidages de pile ou messages d'erreur - parfois, vous pouvez dire simplement par la façon dont il est formaté quel composant du système a provoqué l'erreur d'origine (par exemple, s'il est en allemand, vous pouvez blâmer le tiers avec lequel vous travaillez à Berlin).

  4. Si vous l'avez limité à deux systèmes qui collaborent, inspectez les messages entre les deux systèmes via le moniteur de trafic ou les fichiers journaux, et déterminez quel système se comporte conformément aux spécifications et lequel ne l'est pas. S'il y a plus de deux systèmes dans le scénario, vous pouvez effectuer des vérifications par paire et progresser dans la pile des applications.

  5. La raison pour laquelle l'isolement du problème est si critique est que le problème peut ne pas être dû à un défaut de code sur lequel vous avez le contrôle (par exemple, des systèmes tiers ou l'environnement) et que vous souhaitez que cette partie prenne le relais le plus rapidement possible . C'est à la fois pour vous faire économiser du travail et pour les mettre immédiatement sur le point afin que la résolution puisse être obtenue dans un délai aussi court que possible. Vous ne voulez pas travailler sur un problème pendant dix jours seulement pour découvrir que c'est vraiment un problème avec le service Web de quelqu'un d'autre.

  6. Si vous avez déterminé qu'il y a vraiment un défaut et que c'est vraiment dans le code que vous contrôlez, vous pouvez isoler davantage le problème en recherchant la dernière "bonne bonne" génération et en inspectant les journaux de contrôle des sources pour les modifications qui peuvent avoir causé le problème. Cela peut vous faire gagner beaucoup de temps.

  7. Si vous ne pouvez pas le comprendre à partir du contrôle de code source, il est maintenant temps d'attacher votre débogueur et de parcourir le code pour le comprendre. Il y a de fortes chances que vous ayez de toute façon une assez bonne idée du problème.

Une fois que vous savez où se trouve le bogue et que vous pouvez penser à un correctif, voici une bonne procédure pour le corriger:

  1. Écrivez un test unitaire qui reproduit le problème et échoue.

  2. Sans modifier le test unitaire, faites-le passer (en modifiant le code d'application).

  3. Conservez le test unitaire dans votre suite de tests pour empêcher/détecter la régression.

3
John Wu

Bug, erreur, problème, défaut - peu importe comment vous l'appelez, cela ne fait pas beaucoup de différence. Je vais m'en tenir au problème puisque c'est ce à quoi je suis habitué.

  1. Déterminez quelle est la perception du problème: traduisez du "Bob n'est toujours pas dans le système" d'un client en "Lorsque j'essaie de créer un enregistrement utilisateur pour Bob, il échoue avec une exception de clé en double, bien que Bob ne soit pas déjà là-dedans '
  2. Déterminez si c'est vraiment un problème ou juste un malentendu (en effet, Bob n'est pas là, il n'y a personne appelé bob, et l'insertion devrait fonctionner).
  3. Essayez d'obtenir des étapes fiables minimales que vous pouvez suivre pour reproduire le problème - quelque chose comme "Étant donné un système avec un enregistrement utilisateur" Bruce ", lorsqu'un enregistrement utilisateur" Bob "est inséré, une exception se produit"
  4. C'est votre test - si possible, mettez-le dans un harnais de test automatisé que vous pouvez exécuter encore et encore, cela sera inestimable lors du débogage. Vous pouvez également l'intégrer à votre suite de tests pour vous assurer que ce problème particulier ne réapparaîtra plus tard.
  5. Sortez votre débogueur et commencez à mettre des points d'arrêt - déterminez le chemin du code lorsque vous exécutez votre test et identifiez ce qui ne va pas. Pendant ce temps, vous pouvez également affiner votre test en le rendant le plus étroit possible - idéalement un test unitaire.
  6. Réparez-le - vérifiez vos tests réussis.
  7. Vérifiez que le problème d'origine tel que décrit par le client est également résolu (très important - vous pourriez simplement avoir corrigé un sous-ensemble du problème). Vérifiez que vous n'avez pas introduit de régressions dans d'autres aspects du programme.

Si vous connaissez très bien le code, ou si le problème ou la solution est évident, vous pouvez ignorer certaines de ces étapes.

Comment devrions-nous l'aborder pour utiliser le plus efficacement possible notre temps précieux et nous permettre de passer moins de temps à essayer de le trouver et plus de temps à coder?

Je m'oppose à cela, car cela implique que l'écriture de nouveau code est plus utile que d'avoir un programme de travail de haute qualité. Il n'y a rien de mal à être aussi efficace que possible pour résoudre les problèmes, mais un programme ne s'améliore pas nécessairement en y ajoutant simplement plus de code.

3
ptyx

Je pense que la reproduction d'un bug est également importante. Tous les cas qui reproduisent le bogue peuvent être répertoriés et vous pouvez alors vous assurer que votre correction de bogue couvre tous ces cas.

3
aslisabanci

Lorsque nous détectons une erreur dans notre code, que pouvons-nous faire pour l'éliminer? Comment devrions-nous l'aborder pour utiliser le plus efficacement possible notre temps précieux et nous permettre de passer moins de temps à essayer de le trouver et plus de temps à coder? Aussi, que devons-nous éviter lors du débogage?

En supposant que vous êtes dans un environnement de production, voici ce que vous devez faire:

  1. Décrivez correctement "l'erreur" et identifiez les événements qui la provoquent.

  2. Déterminez si l '"erreur" est une erreur de code ou une erreur de spécification. Par exemple, la saisie d'un nom à 1 lettre peut être considérée comme une erreur pour certains systèmes mais un comportement acceptable pour d'autres systèmes. Parfois, un utilisateur signalait une erreur qu'il pensait être un problème, mais l'attente de l'utilisateur pour le comportement du système ne faisait pas partie des exigences.

  3. Si vous avez prouvé qu'il y a une erreur et que l'erreur est due au code, vous pouvez déterminer quelles parties de code doivent être corrigées pour éviter l'erreur. Examinez également l'effet du comportement sur les données actuelles et les opérations futures du système (analyse d'impact sur le code et les données).

  4. À ce stade, vous auriez probablement une estimation de la quantité de ressources qui seront utilisées pour corriger le bogue. Vous pouvez soit le corriger immédiatement, soit planifier un correctif dans une prochaine version du logiciel. Cela dépend également de la volonté de l'utilisateur final de payer pour le correctif. Vous devez également évaluer les différentes options disponibles pour corriger l'erreur. Il peut y avoir plus d'une façon. Vous devez sélectionner l'approche qui convient le mieux à la situation.

  5. Analysez les raisons qui ont provoqué l'apparition de ce bogue (exigences, codage, tests, etc.). Appliquer des processus qui empêcheraient que la condition ne se reproduise.

  6. Documentez l'épisode de manière adéquate.

  7. Relâchez le correctif (ou la nouvelle version)

1
NoChance

Voici comment je le fais:

  1. utilisez la même méthode à chaque fois pour trouver le problème. Cela améliorera votre temps de réaction aux erreurs.
  2. La meilleure façon est probablement de lire le code. En effet, toutes les informations sont disponibles dans le code. Vous avez juste besoin de moyens efficaces pour trouver la position correcte et la capacité de comprendre tous les détails.
  3. le débogage est très lent et n'est nécessaire que si vos programmeurs ne comprennent pas encore comment l'ordinateur exécute les instructions asm/ne peut pas comprendre les piles d'appels et les choses de base
  4. Essayez de développer des techniques de preuve comme l'utilisation de prototypes de fonctions pour raisonner sur le comportement du programme. Cela vous aidera à trouver la position correcte plus rapidement
1
tp1