Mise au point de programmes avec GDB
(Vos commentaires sont les bienvenus : mailto:jciehl@bat710.univ-lyon1.fr)
"Votre programme ne marche pas", ... ne marche pas ...
Il est souvent nécessaire de corriger une
erreur dans un programme, l'erreur commise est souvent due à une
faute d'inattention (ou de copier-coller ... ) et sa correction est en
général immédiate. D'autres erreurs sont plus
difficiles à identifier, des outils spécialisés
permettent de gagner beaucoup de temps : GDB par exemple.
- GDB ?
GDB est un utilitaire, compagnon du compilateur GCC,
qui permet d'arrêter un programme en cours
d'éxécution et de vérifier les valeurs des
variables, d'éxécuter les instructions une par une, etc.
ces observations permettent de comprendre l'erreur à corriger.
L'utilisation de GDB n'est pas toujours très
intuitive, mais elle permet de comprendre le comportement du programme
en quelques minutes. Avant de pouvoir utiliser GDB pour analyser un
programme, il faut modifier les options de compilation du projet. La
partie suivante présente le fonctionnement de gdb.
1. Compiler le programme pour l'analyser avec GDB
GDB a besoin d'informations qui ne sont normalement
pas disponibles dans un programme compilé, il suffit d'ajouter
l'option -g lors de la compilation et de l'édition de liens pour
que GCC génère ces informations.
exemple de Makefile :
CFLAGS= -Wall -g
LDFLAGS= -g
prog: main.o struct.o elem.o
gcc $(LDFLAGS) -o $@ $+
%.o: %.c
gcc $(CFLAGS) -o $@ -c $<
clean:
rm -f prog *.o
2. Utilisation de GDB
remarque sur la notation :
$ represente le prompt de l'interpréteur de commandes (shell),
(gdb) représente le prompt interne de gdb
Pour lancer gdb, il suffit de lui donner en paramètre le nom de votre programme :
$ gdb prog
pour lancer votre programme (à l'intérieur de gdb) :
(gdb) run
si vous souhaitez donner des paramètres de ligne de commande à votre programme :
(gdb) run param1 param2
Si votre programme plante, gdb vous indique quel
type d'erreur s'est produit et à quel endroit de votre programme
(fichier source, fonction, numéro de ligne) :
Program received signal SIGSEGV, Segmentation fault.
- la commande backtrace (abbréviation bt)
permet d'afficher la pile d'appel et de déterminer dans quelle
fonction votre programme vient de planter.
- frame n permet de sélectionner un niveau dans
la pile d'appel et de revenir en arrière dans la suite d'appels
qui a provoqué l'erreur.
- print (abbréviation p) affiche la valeur d'une variable
- continue (abbréviation cont) permet de
reprendre l'éxécution du programme (sauf en cas d'erreur,
bien sur)
- next / step permettent de suivre pas à pas l'éxécution du programme
- break / tbreak permettent de donner un point d'arret
2.1. afficher la valeur d'une variable (print)
print (abbréviation p)
2.2. les points d'arrêts
Il est possible d'indiquer à gdb d'arreter le
programme avant que l'erreur ne se produise. L'endroit ou gdb doit
interrompre l'éxécution du programme s'appelle un point
d'arret (break point). Un point d'arret correspond à une ligne
dans un fichier source. On peut spécifier un point d'arret en
donnant un numéro de ligne, un nom de fonction dans le fichier
source courant ou dans un autre fichier :
break numéro de ligne
break nom de fonction
break nom de fichier:nom de fonction
break nom de fichier:numero de ligne
Un point d'arret est permament, c'est à dire
qu'il arretera l'éxécution du programme à chaque
fois, il existe une variante qui n'est active qu'une seule fois, le
point d'arret temporaire, commande tbreak. Les commandes clear et
delete permettent de détruire les points d'arrets connus.
2.3. arreter l'éxecution du programme
gdb interompra le programme lorsqu'il rencontre un
point d'arret ou lorsque vous appuyez sur ctrl+C. Il est ensuite
possible de naviguer dans le programme en fixant un point d'arret
et en demandant de continuer l'éxécution avec la commande
continue (abbréviation cont) ou en mode pas à pas
(commandes next et step).
2.4. visualiser l'éxécution du programme (continue, next, step)
Il est aussi possible de faire
éxécuter le programme instruction par instruction avec la
commande next (abbréviation n), ou la commande step
(abbrévation s). Ces deux commandes font la même chose, la
seule différence est que next ne montre pas les instructions
éxécutées dans les fonctions
appélées alors que step le permet.
2.5. visualiser la pile d'appel
Lorsque le programme est arrété, il
possible de voir l'enchainement des fonctions en cours
d'éxécution avec la commande backtrace
(abbréviation bt). En revenant en arrière, il est
possible de vérifier que les paramètres d'appel de la
fonction sont corrects, par exemple. La commande frame permet de
sélectionner un niveau de la pile d'appel à visualiser,
on peut alors afficher la valeur des différentes variables (cf.
print). Les commandes up et down permettent de monter et de descendre d'un niveau dans la pile d'appel.
2.6 inspecter le source du programme
list
permet d'afficher le source du programme au point
sélectionné ou actuel, par exemple après
l'arrêt du programme. list + et list - permettent de visualiser les lignes suivantes ou précédentes.