1. Introduction
gdb est un debugger symbolique, c'est-à-dire un utilitaire Unix 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. Nous allons utiliser gdb dans ce TP. L'interface mxgdb est également parfois disponible. 
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 courant 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 : 
•	compilateur gcc + debugger gdb (ou xxgdb ou mxgdb) 
•	compilateur cc + debugger dbx (ou debugger ou dbxtool) 
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. 
1.1 Préliminaires
Créer un nouveau répertoire (sous votre compte) et y copier les fichiers sources (sans oublier les ".h" et le "Makefile" !) qui se trouvent dans : 
	/tmp/tpgdb
Votre répertoire devra alors contenir : 
•	deux fichiers contenant du code source en C : tri.c et donnees.c 
•	deux fichiers en-têtes (ou "headers") contenant les déclarations correspondantes : tri.h et donnees.h 
•	un fichier Makefile contenant les règles nécessaires à la compilation des deux fichiers C et à la production de l'exécutable. 
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. 
Si l'on utilise un Makefile (comme c'est le cas ici), il faut que la variable CFLAGS contienne l'option -g. 
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. 
D'autre part, la ligne: 
	..KEEP_STATE:
placée en début de Makefile provoque à chaque appel de la commande make : 
•	la détermination automatique des dépendances 
•	la recompilation automatique des fichiers concernés chaque fois qu'une option de compilation ou qu'une dépendance a été modifiée. 
Compiler les fichiers et créer l'exécutable en tapant la commande : make 
1.3. Lancement de gdb
pour lancer le débugger, tapez : 
	gdb  nom-du-programme-à-debugger
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. 
2. Utilisation de gdb
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) 
gdb exécute alors le programme comme s'il avait été lancé normalement. L'exécution se poursuit jusqu'à la fin du programme sauf: 
•	si l'on a mis des points d'arrêt (voir paragraphe suivant) 
•	s'il y a une erreur (un "bug") et que le programme plante 
•	si l'utilisateur tape ^C (touches CONTROL et C appuyées simultanément) 
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. 
Visualiser le source du programme :
Pendant l’éxécution de gdb, on peut à tout moment visualiser le source du programme à l’aide de la commande list.
Exemple : list (liste de 10 lignes autour de la ligne courante), list nom_fonction (affiche le source de la fonction demandée), list 10,36 affiche les lignes de 10 à 36.
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. 
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. 
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, la ligne courante (le programme s'arrête juste avant cette ligne). 
2.3. Contrôle de l'exécution
La commande: 
•	step exécute une ligne de code (la ligne courante affichée)
•	next fait de même mais en sautant les procédures ou fonctions 
•	cont continue jusqu'au prochain 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. 
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 ? 
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
•	Pour mettre un point d'arrêt dans une fonction qui est dans un autre fichier que celui qui est en cours de traitement: 
•	taper la commande : 
•	      break  nom-du-fichier.c:nom-de-la-fonction
(ne pas oublier le ".c" et le ":") 
Exemple: 
Mettre un point d'arrêt dans les fonctions Lire et Afficher. 
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. 
On peut soit taper en toutes lettres : 
	print  nom-de-la-variable
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 
Exemples:
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:
Pour afficher la valeur pointée par un pointeur faire : 
      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é après chaque commande gdb. Cet affichage sera réalisé jusqu'à ce que l'on fasse: 
      undisplay  expression
2.6. Visualiser (et se déplacer dans) la pile
La commande: 
•	where  visualise la pile d'exécution, c'est-à-dire la liste des fonctions ou procédures empilées jusqu'à celle où l'on est momentanément arrêté. where affiche également les numéros de lignes correspondants. 
•	up permet de remonter dans la liste 
•	down permet de redescendre dans la liste 
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 : 
•	interruption utilisateur, provoquée lorsque l'on tape ^C 
•	interruptions système dues à une erreur dans le programme (Segmentation Fault, Bus Error, etc...) 
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. 
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 de gdb depuis emacs ou xemacs
Il est possible d'appeler gdb depuis l'éditeur de texte emacs en tapant sous emacs la commande suivante: 
	ESC-X gdb
xemacs possède également un bouton qui permet de lancer direcment gdb. 
Noter que l'On peut également lancer la compilation depuis emacs au moyen de la commande : 
	ESC-X compile
•	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
•	quit : sort de gdb 
•	list fonction : affiche cette fonction 
•	whatis : informations sur une variable ou une fonction 
•	tbreak : point d'arrêt temporaire 
•	delete no : enlève le point d'arrêt numéro no 
•	condition no condition : stop conditionnel: s'arrête quand la condition devient vraie 
•	ignore : "attrappe" (ignore) les signaux donnés en argument 
•	set var = expression : affectation de variable 
•	cd, pwd : comme sous Unix 
Pour plus d'informations faire : help commande