TP gdb

Eric Lecolinet - Télécom ParisTech - Dept. INFRES

1. Introduction

gdb est un debugger symbolique, c'est-à-dire un utilitaire permettant de contrôler le déroulement de programmes C, C++, Pascal ou Fortran. gdb permet (entre autres) de mettre des points d'arrêt dans un programme, de visualiser l'état de sa pile d'exécution ou de ses variables, de calculer des expressions, d'appeler interactivement des fonctions, etc.

xxgdb est une interface graphique qui facilite l'utilisation de gdb sous X-Window. ddd est une autre variante, plus évoluée.

Enfin gdb peut être lancé depuis Emacs via le menu "Tools" ou en tapant sous emacs la commande suivante :

	ESC-X gdb
De même, on peut lancer la compilation via le menu "Tools" ou au moyen de la commande :
	ESC-X compile

Tout d'abord

Créer un nouveau répertoire et y copier les fichiers suivants :

Tous ces fichiers sont nécessaires pour compiler correctement le programme.

Compilation

Les programmes C doivent être compilés avec le compilateur gcc avec l'option -g pour pouvoir être débuggés par gdb. Si on utilise un Makefile (comme c'est le cas ici), il faut que la macro CFLAGS contienne l'option -g.

Compiler les fichiers et créer l'exécutable en tapant la commande : make

Lancement de gdb

pour lancer le débogueur tapez dans le Terminal :

	xxgdb  nom-du-programme-à-debugger
   ou, sinon
	gdb  nom-du-programme-à-debugger

Si vous avez lancé xxgdb vous verrez 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:


2. Utilisation de gdb

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)

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.

Exemple:

Après avoir compilé le programme tri, lancer gdb 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.

Points d'arrêt

Les points d'arrêt servent à interrompre l'exécution et à revenir au mode commande à un endroit donné du programme.

Pour s'arrêter au debut d'une fonction, faire :

         break  nom-de-la-fonction

Pour s'arrêter dans le corps d'une fonction faire:

         break  numéro-de-ligne

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.

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).

Contrôle de l'exécution

La commande:

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.

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").

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 ?

Compléments sur les points d'arrêt

Exemple : Mettre un point d'arrêt dans les fonctions Lire et Afficher.

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.

On peut soit taper en toutes lettres :

	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 : 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
Exemple : Dans la fonction Trier, afficher la valeur de:

     swap, items[1], i + j, items[i].nom, items[i].age, etc...

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).

Compléments:

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. 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.


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 :

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".

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.

Remarque: la commande cont permet alors de poursuivre l'exécution normalement.


4. Divers

Aide en ligne

Faire :

	help  nom-de-commande
pour obtenir de l'aide sur cette commande.

Abréviations

De nombreuses commandes peuvent être abrégées. Par exemple:

        r  pour run
        b  pour break
        s  pour step
        n  pour next
        c  pour cont
        p  pour print
	etc ....
De plus, "retour-chariot" (sans rien taper d'autre) réexécute la dernière commande entrée.

Recompilation

On peut recompiler le programme sans sortir de gdb en tapant directement sous gdb la commande:

	make
(make est une commande propre à gdb qui active la commande make habituelle d'Unix).

Appel interactif des fonctions

Les commandes :

	print  expression
	call  fonction(arguments)

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)

Exemple: Relancer le programme en tapant la commande :

	call  main()

Autres commandes utiles

Pour plus d'informations faire : help commande


5. Exercice

Le but de l'exercice est de compléter le programme tri.

a) 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).

b) Vérification des entrées

c) Mémoire dynamique

Généraliser le programme pour un nombre quelconque d'items : utiliser des pointeurs et les fonctions malloc(), realloc() et free().

d) Sauvegarde et relecture

Permettre de sauvergarder les données et de les relire dans un fichier.



Eric Lecolinet - http://www.telecom-paristech.fr/~elc - Telecom ParisTech