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.


    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.