|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 |
|
Membre chevronné
![]() ![]() ![]() Inscription : mai 2002 Messages : 504 ![]() |
Suite a la recrudescence de cas problematique, voici le fruit d'une petite reflexion. Si vous avez d'autre choses a ajouter
Tout d'abord pour debugger un programme, il faut avoir les idees clair deja quant au programme, c'est a dire : - qu'est-ce qu'il fait - comment il le fait et pour aider a cela, rien de tel que du code clair : - indentation (on decale le code de quelques espaces apres un if, etc.) - commentaire (telle fonction fait ceci, telle variable contient le resultat, etc.) - fractionnement des "fonctions" (faire des fonctions generique plutot que d'avoir une fonction de 150 lignes super chiant a debugger) Ensuite, pour les erreurs de compilations, - compiler avec le maximum de warnings (-Wall pour gcc). Et comprendre ces warnings : un bon programme ne doit avoir aucun warning : un warning est succeptible de causer une erreur. - utiliser man (manuel en ligne pour voir la syntaxe des primitives des librairies) (rappel: 'man fprintf' sous linux/unix), ou l'aide en ligne si disponible. - reflechir au sens des instructions : pourquoi on fait ceci, cela etc. Enfin, quand vous ne voyez pas l'erreur (et c'est comprehensible), afin de simplifier la tache de ceux qui vont vous aider, il faut specifier au maximum les erreurs rencontrees, en donnant: - le message d'erreur, - l'environement utilise (win/linux, compilo, librairies...) - la ligne du code ou se produit cette erreur - le code des structures et autres definitions si besoin est (pour montrer les types des donnees utilisees) Il n'est pas necessaire : - de donner le code complet (sauf si demande expressement) Remarque, lorsque du code est donne, il doit l'etre entre les balises [code ] et [/code ] |
|
|
10
|
|
|
#2 |
![]() ![]() Inscription : juin 2002 Messages : 2 036 ![]() |
Petit complement, non pour debugger (quoique) mais pour limiter le risque de bug :
- toujours tester les valeurs de retours des fonctions - fermer immediatement une accolade puis mettre le code ensuite (ca evite de se retrouver avec un programme qui ne compile pas, et c'est assez penible de tout reprendre pour voir ou se situe le pb) - de meme lors d'une allocation, ecrire la ligne de desallocation, puis le traitement entre les deux. En passant une petite remarque sur un des conseils de D[r]eadLock : "fractionnement des fonctions", c'est une remarque tout a faite vrai dans le cas de la programmation sur PC, mais pour avoir programmer sur des systemes embarques avec rlativement peu de memoire (peu de pile en particulier), le trop grand fractionnement peu etre source dans certains cas de bug memoire (depassement de pile) assez penible a debugger. |
|
|
00
|
|
|
#3 |
|
Membre chevronné
![]() ![]() ![]() Inscription : mai 2002 Messages : 504 ![]() |
Pour gvim :
- set showmatch, pour faire clignoter l'accolade/la parenthese/le crochet ouvrant correspondant quand on en ecrit un/une fermant. - % (en mode commande) sur une accolade/parenthese/crochet ouvrant ou fermant pour aller a celui correspondant. D'autre part, la syntaxe highlight permet de ne pas trop se planter sur les mots cles, mais surtout, permet de reconnaitre les chaines de caracteres et donc de toutes les fermer. |
|
|
00
|
|
|
#4 | ||||||||||||
|
Membre actif
![]() ![]() ![]() Inscription : juin 2002 Messages : 97 ![]() |
(quelques notions sont en double avec le premier post)
D'une façon générale, quand une erreur de compilation ou d'exécution imcompréhensible ne semble pas avoir de rapport avec l'endroit du source où elle survient, elle n'en a effectivement pas et est la conséquence d'une erreur silencieuse précédente. Autrement dit, quand le système remarque que quelque chose ne va pas, il est déjà trop tard ! L'exemple typique pour la compilation est le ";" manquant à la fin d'une struct/class. Très vicieux si elle est dans un header, car l'erreur est signalée dans un autre fichier ! L'exemple typique pour l'exécution est l'écrasement de mémoire. Par exemple, "char* copie= strcpy(malloc(strlen(source)),source);" oublies le +1 nécessaire au '\0' terminal. Pour ne pas faire d'erreurs, le mieux est de comprendre ce que l'on fait (facile à dire). Pour éviter les situations indéboguables, le développement incrémental est très bien: Cmmencer avec un truc ridiculement simple mais qui marche. Rajouter une petite fonctionnalité, tester. Rajouter tout le reste pareil: petit à petit, en testant à chaque fois. Pour capturer les erreurs, un moyen simple est de protéger son code avec plein d'assertions. Elles ne sont actives qu'en mode déboguage. Code :
Des nids à erreurs: Structures if/else/switch imbriquées trop complexes. Un bogue peut se terrer dans une branche rarement parcourue. Fonctions trop longues. Signe que des concepts distincts sont mal indentifiés/séparés. Variables utilisées à des endroits très distants. Signe d'inter-dépendance excessive du code. L'éditeur est ton ami, il t'aide à ne pas faire de fautes si: -Il dispose d'une coloration syntaxique riche. -Il propose l'auto-complétion (avec correction majuscule/minuscule please). -Il permet de (ré)indenter automatiquement le code. Le compilateur se doit de donner des messages d'erreurs compréhensibles, en désignant l'endroit exact où se trouve le problème dans la ligne. Régler les alertes au maximum est une bonne pratique. Le débogueur est indispensable. Il doît être capable de: -Éxécuter le code source pas à pas, en montrant les valeurs des variables et la pile d'appel des fonctions. -Gérer des points d'arrêts (conditionnels c'est mieux). -Pister les écrasements/fuites de mémoire. Un environnement de éveloppement intégré (EDI) regrouppant ces trois-là, plus l'appel de la documentation et d'autres outils, c'est un must ! La librairie a un rôle à jouer aussi. Si elle est de qualité, elle est blindée d'assertions. Son interface devrait être intuitive et peu sujette au erreurs. Erreurs de débutants fréquentes Divers: Code :
Code :
Code :
Code :
Code :
__________________
"J'ai toujours rêvé d'un ordinateur qui soit aussi facile à utiliser qu'un téléphone. Mon rêve s'est réalisé : je ne sais plus comment utiliser mon téléphone."-Bjarne Stroustrup www.stroustrup.com |
||||||||||||
|
|
10
|
|
|
#5 | ||||||
|
Nouveau Membre du Club
![]() Inscription : décembre 2002 Messages : 29 ![]() |
petits ajouts et correctifs :
Citation:
Citation:
il faut juste faire tres attention a la gestion de la memoire Citation:
enfin de plus je ne preconise pas l'emploie d'un malloc directement dans une fonction, ceci entraine la perte d'un pointeur et donc une fuite de memoire, pas forcement source d'erreur, mais bon mieux vaut quand meme faire les choses bien. il est preferable de separer le code clairement plutot que d'imbriquer trop de fonctions, car ceci peut mener a une erreur de parenthese, voir a une erreur de prioriter dans la gestion du code. ... Citation:
bon sinon une assez bonne methode de debugging, pour ceux qui travail sur les outils arcailliques, ou pour ceux qui travail sur de bons outils mais qui prefere la methode a la flamme bien moyennageuse vous placez un printf sur chaques lignes, et cela donne ceci : Code :
voila, pour des questions n'hesitez surtout pas a poster dans le forum
__________________
Fatalis "La femme est le chef-d'oeuvre de Dieu, surtout quand elle a le diable au corps" Alphonse Allais |
||||||
|
|
11
|
|
|
#6 | ||||
|
Candidat au titre de Membre du Club
![]() |
Quelques rectificatifs/précisions :
Citation:
Citation:
|
||||
|
|
00
|
|
|
#7 | |
![]() ![]() Inscription : juin 2002 Messages : 2 036 ![]() |
Citation:
|
|
|
|
00
|
|
|
#8 | |
|
Membre actif
![]() ![]() ![]() Inscription : juin 2002 Messages : 97 ![]() |
Citation:
__________________
"J'ai toujours rêvé d'un ordinateur qui soit aussi facile à utiliser qu'un téléphone. Mon rêve s'est réalisé : je ne sais plus comment utiliser mon téléphone."-Bjarne Stroustrup www.stroustrup.com |
|
|
|
10
|
|
|
#9 | ||
|
Membre éclairé
![]() ![]() Thierry Ingénieur développement logiciels Inscription : avril 2002 Messages : 121 ![]() |
Citation:
|
||
|
|
00
|
|
|
#10 | |
|
Membre habitué
![]() Thomas P. Inscription : avril 2003 Messages : 119 ![]() |
Citation:
__________________
Tom |
|
|
|
00
|
|
|
#11 | |
|
Futur Membre du Club
![]() Inscription : mai 2003 Messages : 30 ![]() |
Citation:
IL y a aussi la fonction C perror() est c'est la simplicite meme pour afficher les messages d'erreurs. |
|
|
|
10
|
|
|
#12 |
|
Membre habitué
![]() Thomas P. Inscription : avril 2003 Messages : 119 ![]() |
Ouais, elle donne plus d'informations sur l'erreur. Elle traduit la variable errno.
Le message peut être récupéré grâce à sys_errlist[errno]. errno et sys_errlist sont des variables de stdlib.h qu'il faut déclarer (sans oublier le extern) pour les utiliser.
__________________
Tom |
|
|
00
|
|
|
#13 | |
![]() ![]() ![]() Administrateur systèmes et développeur Web Inscription : juin 2003 Messages : 8 029 ![]() |
Citation:
Quant à printf sur stdout, normalement tout \n envoyé vide le buffer... Ceci dit envoyer le message sur stderr permet d'être sûr que le texte sera affiché, car stderr n'est pas bufferisé (c'est une caractéristique du flux d'erreur et non de fprintf), de plus, sous Unix uniquement, il est possible de dissocier la sortie normale du processus de la sortie d'erreur, grâce aux opérateurs de redirection > et 2>. |
|
|
10
|
|
|
#14 |
|
Membre Expert
![]() ![]() Inscription : juillet 2003 Messages : 2 066 ![]() |
Lut
Si bien que l'on ne s'est pas quel debugger il faut préférer:Vous utilisez lequel? Souos windows comme sous linux? |
|
00
|
|
|
#15 | ||
|
Invité régulier
![]() Inscription : mars 2004 Messages : 9 ![]() |
Citation:
- Vous les voyez immédiatement apparaître à l'écran (et non pas après l'arrivée d'un \n ou un truc du genre pour stdout) - Vous pouvez ne garder que les sorties de stderr avec une syntaxe de lancement du genre : @++ |
||
|
|
00
|
|
|
#16 | |
|
Invité régulier
![]() Inscription : mars 2004 Messages : 9 ![]() |
Citation:
J'utilise ddd sous linux qui utilise, je crois gdb. (comme bcp d'autres) @++ |
|
|
|
00
|
|
|
#17 |
|
Membre émérite
![]() Inscription : mai 2004 Messages : 1 020 ![]() |
Bonjour,
Mon expérience professionnelle et personnelle m’a appris que bien debuguer consiste à prévoir cette phase essentielle dès le départ d’un projet. Voici les trois phases d’un bon debug : 1) Dés l’étude du cahier des charges, quand on prend connaissance des fonctionnalités de l’application, il est utile de prévoir les tests globaux du projet suivant les contraintes, les objectifs et l’ergonomie de l’application. 2) Lors de la conception, plus approfondie, mais surtout avant d’avoir les premiers jets de lignes de code, élaborer une vision de l’ensemble des tests unitaires, ainsi que de l’ensemble des tests d’intégration de l’application. 3) Maintenant les tests listés, commencer à développer les utilitaires de tests. Pourquoi se lancer dans l’étude des tests si tôt ? Avant même d’avoir les premières lignes de codes ? La raison est simple : Une fois lancé dans le développement proprement dit, on perd la vision de l’ensemble. Il y a le risque d’oublier des interactions entre modules, ou bien encore carrément de tester certaines valeurs triviales. C’est pourtant sur ces points que l’utilisateur final (un client, un prof…) ne manquera pas de tomber sans forcer le jour J. De plus si dés la conception, vous affinez la liste des tests d’intégrations, vous gagnerez du tant lorsqu’un test unitaire échouera au cours de l’évolution du logiciel. En effet, plutôt que de recommencer l’ensemble des tests suite à une correction dans un modules, vous serez quels tests d’intégration rejouer à coup sûr. Sans rentrer dans le détail pour ce qui est des tests unitaires (choisir errorno, fprintf avec stderr…), voici quelques conseils : 1) Ecrire un code clair : Indenter les sources proprement, écrivez des commentaires précis, pertinents et concis (pas besoin de romans). 2) Tout bloc de code ne servan,t qu’au debug (même la plus petite déclaration) doit être inclus dans un bloc conditionnel. 3) Vérifier systématiquement les arguments des fonctions et procédures avec des assertions. Si vous connaissez la preuve algorithmique, n’hésitez pas en faire usage. 4) Préférez des test automatisés à des tests manuels. Enfin, une fois cette phase achevée, n’oubliez pas des tests de monter en charge de l’application ou de performance : Charge CPU, Vérifier qu’il n’y a pas de fuites mémoires … Bon débug à tous, et toutes |
|
|
00
|
|
|
#18 | ||||
|
Candidat au titre de Membre du Club
![]() Inscription : mars 2005 Messages : 27 ![]() |
juste un complément pour faire de belles traces...
Code :
Code :
'Content de peu n'a rien à craindre' http://jm.marino.free.fr |
||||
|
|
10
|
|
|
#19 | |||||
![]() ![]() Inscription : décembre 2003 Messages : 14 505 ![]() |
Citation:
C'est drôlement compliqué... Tiré de ma bibliothèque: http://emmanuel-delahaye.developpez....b/ed/inc/sys.h Code :
__________________
Pas de Wi-Fi à la maison : CPL Des infos sur la programmation et le langage C: http://bien-programmer.blogspot.com/ http://www.bien-programmer.fr/ http://bien-programmer.forum-actif.net/forum.htm |
|||||
|
|
00
|
|
|
#20 | |
|
Invité régulier
![]() Inscription : septembre 2004 Messages : 5 ![]() |
Citation:
dbx sous solaris quand gdb n'est pas dispo (et que je ne suis pas root). |
|
|
|
00
|
Copyright © 2000-2013 - www.developpez.com