| home page elc | page cours | dept. infres | enst |
xxgdb est une interface graphique qui facilite l'utilisation de gdb sous X-Window. C'est l'utilitaire que nous allons utiliser dans ce TP. L'interface mxgdb est également parfois disponible SGDG.
D'autres debuggers sont également disponibles à l'Ecole, suivant les salles et les machines. Leur syntaxe est légèrement différente, mais le principe général reste le même. Le plus courrant est dbx qui peut également être appelé via une interface graphique sous X-Window à l'aide des commandes debugger ou dbxtool (suivant la version du système d'exploitation).
Attention: le debugger n'est pas toujours independant du compilateur. Ainsi, seules les combinations suivantes sont toujours valides sur toutes les stations Sun :
Enfin, certains debuggers (et en particulier gdb) peuvent être directement appelé depuis les éditeurs de texte emacs et xemacs. Ceci permet de bénéficier d'un environnement de développement intégré (plus ou moins) similaire à ce que l'on peut aujourd'hui trouver dans le "monde PC". Cette possibité sera expliquée à la fin du TP.
Si l'on utilise un Makefile (comme c'est le cas ici),
il faut que la variable CFLAGS
contienne l'option -g.
D'autre part, la ligne:
Compiler les fichiers et créer l'exécutable en tapant la
commande : make
dans une fenêtre shell (par exemple une fenêtre "xterm").
Après quelques secondes nécessaires à l'initialisation et à
la lecture des fichiers à débugger, gdb entre en mode commande
et attend les instructions de l'utilisateur.
On doit alors voir apparaître sur l'écran une
fenêtre xxgdb
qui comprend deux ou trois zones de texte:
On peut alors utiliser xxgdb de deux manières:
gdb exécute alors le programme comme s'il avait été lancé
normalement. L'exécution se poursuit jusqu'à la fin du programme sauf:
Tant que le programme "tourne", il n'est pas possible
d'entrer de nouvelles commandes gdb (celles-ci ne seront
effectuées que lorsque le programme s'arrêtera). gdb est
alors en mode exécution. La seule façon de revenir en mode
commande pendant l'exécution d'un programme est de taper ^C.
Pour s'arrêter au debut d'une fonction, faire :
Pour s'arrêter dans le corps d'une fonction faire:
L'exécution sera alors interrompue juste avant cette ligne.
On peut :
Dans les deux cas un marqueur s'affiche alors dans la
fenêtre source pour signaler la présence d'un point d'arrêt.
La différence entre step et next est que step permet
d'"entrer" dans les fonctions pour les exécuter pas à pas
alors que next les exécute sans s'arrêter.
Relancer le programme en cliquant sur run et re-entrer les
données. Le programme s'arrêtera à la même ligne que
précédemment. Continuer l'exécution en utilisant cette fois
la commande step. Que constate-t'on ?
Rajouter un point d'arrêt au debut de la fonction Trier et
juste avant la deuxième boucle for de cette même fonction.
Relancer l'exécution et faire de même que pécédemment mais
en utilisant cette fois la commande cont.
Conclusions ?
Mettre un point d'arrêt dans les fonctions Lire et Afficher.
On peut soit taper en toutes lettres :
Relancer le programme avec les mêmes points d'arrêt que précédemment
et afficher le contenu des variables à chaque point d'arrêt.
De manière plus générale, on peut afficher la valeur de
n'importe quelle expression valide en C
Dans la fonction Trier, afficher la valeur de:
Attention : ces expressions n'ont de sens que si elles sont
définies (par exemple la variable i n'est correctement
initialisée qu'après la première boucle for).
Pour afficher la valeur pointée par un pointeur faire :
Enfin, le bouton locals permet d'afficher toutes les variables
locales d'une fonction et le bouton args, ses arguments.
Cliquer sur le bouton where pour afficher la pile, puis
utiliser les commandes up et down pour se déplacer dans la pile.
Afficher les variables de la fonction Trier, puis celles de
la fonction Choix, et enfin celles de la fonction main.
Dans les deux cas, il est possible de voir où le programme
s'est arrêté et de visualiser l'état de ses variables.
Ce qui est évidemment très pratique pour trouver les "bugs".
Remarque: la commande cont permet alors de poursuivre
l'exécution normalement.
De plus, "retour-chariot" (sans rien taper d'autre) réexécute
la dernière commande entrée.
Noter que l'On peut également lancer la compilation depuis emacs au
moyen de la commande :
permettent d'appeler interactivement les fonctions contenues
dans le programme ainsi que la plupart des fonctions C des bibliothèques
standard (comme par exemple "printf" etc...).
Ceci peut-être très utile pour tester rapidement le comportement d'une
fonction dans la mesure où l'on peut changer interactivement les arguments
passés à cette fonction sans avoir à recompiler
(surtout si l'on rajoute des points d'arrets dans cette fonction avant de
l'appeler)
Pour plus d'informations faire : help commande
1.1 Préliminaires
Créer un nouveau répertoire "tp-gdb" (sous votre compte)
et y copier
les fichiers sources (sans oublier les ".h" et le
"Makefile" !) qui se trouvent dans :
~domeo/TP-gdb
Votre répertoire devra alors contenir :
Tous ces fichiers sont nécessaires pour compiler correctement
le programme.
1.2 Compilation des programmes
Les programmes C doivent être compilés avec le compilateur gcc
avec l'option -g pour pouvoir être débuggés par gdb.
Ainsi la ligne :
CFLAGS = -g
du Makefile indique que les fichiers C seront compilées
avec l'option -g afin de pouvoir être débuggés.
.KEEP_STATE:
placée en début de Makefile provoque à chaque appel de la
commande make :
1.3. Lancement de xxgdb
pour lancer le débugger, tapez :
xxgdb nom-du-programme-à-debugger
2. Utilisation de xxgdb
2.1. Lancer l'exécution
Pour lancer l'exécution du programme taper:
run arguments-du-programme
ou cliquer sur le bouton run (si le programme n'a pas
d'argument)
Exemple:
Après avoir compilé le programme tri, lancer xxgdb
et exécuter le programme. Entrer les données demandées (2 ou 3
noms suffisent) et terminer la saisie en entrant un point
suivi d'un "retour-chariot". Attention: le programme n'est
pas complet (ce sera a vous de le compléter), seule la
première option de tri (par age croissant) est implémentée.
2.2. Points d'arrêt
Les points d'arrêt servent à interrompre l'exécution et à
revenir au mode commande à un endroit donné du programme.
break nom-de-la-fonction
break numéro-de-ligne
Exemple:
Mettre un point d'arrêt au début de la fonction Choix puis
relancer l'exécution du programme depuis le debut en cliquant sur
le bouton run. Entrer de nouveau les données.
Lorsque l'exécution s'interrompt, le fichier contenant le point d'arrêt
correspondant s'affiche dans la fenêtre source et une flèche horizontale
indique la ligne courante (le programme s'arrête juste avant cette ligne).
2.3. Contrôle de l'exécution
La commande:
Exemple:
Le programme étant toujours arrété dans la fonction Choix,
continuer l'exécution pas pas au moyen de la commande next
(ne pas oublier d'entrer une valeur quand vous arriverez au
"scanf").
2.4. Compléments sur les points d'arrêt
Pour afficher la liste des points d'arrêt faire:
info breakpoints
ou plus simplement:
info b
Pour effacer un point d'arrêt faire:
clear numéro-de-ligne
à l'aide du bouton clear (apres avoir sélectionné cette ligne
à la souris) ou en tapant directement la commande.
Pour mettre un point d'arrêt dans une fonction qui est dans
un autre fichier que celui qui est affiché l'écran:
Exemple:
- sélectionner et visualiser ce fichier en cliquant sur le bouton file
et en choisissant dans une liste.
- puis faire comme précédemment
taper la commande :
break nom-du-fichier.c:nom-de-la-fonction
(ne pas oublier le ".c" et le ":")
2.5. Visualisation des variables
Lorsque le programme est arrêté dans une fonction, on peut visualiser
ses variables au moyen de la commande ou du bouton print.
print nom-de-la-variable
ou bien cliquer sur le bouton print après avoir sélectionné la variable
avec la souris dans la fenêtre contenant le texte source.
Exemple:
Exemples:
swap, items[1], i + j, items[i].nom, items[i].age, etc...
Compléments:
print* nom-de-la-variable
Pour afficher de manière permanente le contenu d'une variable
ou d'une expression, faire:
display expression
Le contenu de cette variable est alors affiché dans la
fenêtre "de visualisation" . Cet affichage sera réactualisé
jusqu'à ce que l'on fasse:
undisplay expression
2.6. Visualiser (et se déplacer dans) la pile
La commande:
Exemple:
On doit théoriquement se trouver dans la fonction Trier.
Si ce n'est pas le cas, relancer l'exécution jusqu'a cette fonction.
3. Interruptions
De même que les points d'arrêts, les interruptions arrêtent
le déroulement du programme. Dans le cas qui nous interesse,
celles-ci sont principalement de deux types :
Exemple:
Relancer le programme et faire ^C au moment où le programme
demande le premier nom. Afficher où l'on se trouve dans la
pile à l'aide de la commande where ou du bouton stack.
4. Divers
Faire :
Aide en ligne
help nom-de-commande
pour obtenir de l'aide sur cette commande.
De nombreuses commandes peuvent être abrégées. Par exemple:
Abréviations
r pour run
b pour break
s pour step
n pour next
c pour cont
p pour print
etc ....
On peut recompiler le programme sans sortir de gdb en tapant
directement sous gdb la commande:
Recompilation
make
(make est une commande propre à gdb qui active la commande
make habituelle d'Unix).
Il est possible d'appeler gdb depuis l'éditeur de texte emacs
en tapant sous emacs la commande suivante:
Appel de gdb depuis emacs ou xemacs
ESC-X gdb
xemacs possède également un bouton qui permet de lancer direcment gdb.
ESC-X compile
Les commandes :
Appel interactif des fonctions
print expression
call fonction(arguments)
Exemple:
Relancer le programme en tapant la commande :
call main()
Autres commandes utiles
5. Exercice
Le but de l'exercice est de compléter le programme tri.
5.1. Tri décroissant et alphabétique
compléter le programme afin de permettre un tri alphabétique
ou décroissant. (plusieurs solutions possibles) Comment
faire pour n'avoir à définir qu'une seule fonction de tri ?
(on pourra par exemple s'inspirer de la technique utilisée
par la fonction standard qsort en regardant le manuel
interactif de cette fonction).
5.2. Vérification des entrées
5.3. Mémoire dynamique
Généraliser le programme pour un nombre quelconque d'items :
utiliser des pointeurs et les fonctions `malloc' et `realloc'.
5.4. Sauvegarde et relecture
permettre de sauvergarder les données et de les relire dans
un fichier.
| home page elc | page cours | dept. infres | enst |