Débogage avec gdb

Le débogueur GNU (gdb) vous permet d'examiner les éléments internes d'un autre programme pendant l'exécution de ce dernier, ou rétrospectivement, pour voir ce que le programme effectuait au moment où il s'est planté.

gdb vous permet d'examiner et de contrôler l'exécution du code et est très utile pour évaluer les causes des plantages ou un comportement incorrect général. gdb ne gère pas les processus Java™ , de sorte qu'il est d'une utilisation limitée sur un programme Java pur. Il est utile pour le débogage de bibliothèques natives et de la machine virtuelle Java elle-même.

En cours d'exécution gdb

Vous pouvez exécuter gdb de trois façons :

Démarrage d'un programme
En général, la commande gdb <application> permet de démarrer un programme sous le contrôle de gdb. Toutefois, en raison de la façon dont Java est lancé, vous devez démarrer gdb en définissant une variable d'environnement, puis en appelant Java:
export IBM_JVM_DEBUG_PROG=gdb
java
Vous recevez ensuite une invite gdb et vous fournissez la commande d'exécution et les arguments Java:
r <java_arguments>
Attachement à un programme en cours d'exécution
Si un programme Java est déjà en cours d'exécution, vous pouvez le contrôler sous gdb. L'ID de processus du programme en cours d'exécution est requis, puis gdb est démarré avec l'application Java comme premier argument et l'ID de processus comme deuxième argument:
gdb <Java Executable> <PID>

Lorsque gdb est attaché à un programme en cours d'exécution, ce programme est arrêté et sa position dans le code est affichée. Le programme est alors sous le contrôle de gdb et vous pouvez commencer à lancer des commandes afin de définir et afficher les variables et contrôler en général l'exécution du code.

Exécution sur un vidage système (fichier core)
Un vidage système est en général généré en cas de plantage d'un programme. gdb peut être exécuté sur un vidage système. Le vidage système contient l'état du programme au moment où le plantage est survenu. Utilisez gdb pour examiner les valeurs de toutes les variables et registres avant un plantage. Ces informations facilitent la recherche des causes du plantage. Pour déboguer un vidage système, démarrez gdb avec le fichier d'application Java comme premier argument et le nom du vidage système comme second argument:
gdb <Java Executable> <system dump>

Lorsque vous exécutez gdb sur un vidage système, il affiche au départ des informations telles que le signal de fin reçu par le programme, la fonction qui s'exécutait à ce moment-là, et même la ligne de code qui a généré l'erreur.

Lorsqu'un programme passe sous le contrôle de gdb, un message de bienvenue s'affiche, suivi d'une invite (gdb). Le programme attend maintenant que vous ayez entré des instructions. Pour chaque instruction, le programme se poursuit de la façon que vous avez choisie.

Définition de points d'arrêt et de points de surveillance

Des points d'arrêt peuvent être définis pour une ligne ou une fonction particulière avec la commande suivante :

break linenumber

ou

break functionName

Lorsque vous avez défini un point d'arrêt, utilisez la commande continue pour permettre au programme de s'exécuter jusqu'à ce qu'il atteigne un point d'arrêt.

Définissez des points d'arrêt à l'aide de conditions afin que le programme s'arrête uniquement lorsque la condition indiquée est atteinte. Par exemple, l'utilisation de breakpoint 39 if var == value provoque l'arrêt du programme lorsqu'il atteint la ligne 39, mais seulement si la variable est égale à la valeur indiquée.

Si vous souhaitez savoir et quand une variable est devenue une certaine valeur, vous pouvez utiliser un point de surveillance. Définissez le point de surveillance lorsque la variable en question est dans la portée. Vous serez ensuite alerté chaque fois que cette variable atteint la valeur indiquée. La syntaxe de la commande est la suivante : watch var == value.

Pour voir quels sont les points d'arrêt et les points de surveillance définis, utilisez la commande info :

info break
info watch
Lorsque gdb atteint un point d'arrêt ou un point de surveillance, il imprime la ligne de code qu'il est défini pour exécuter. Si vous définissez un point d'arrêt à la ligne 8, le programme s'arrête après l'exécution de la ligne 7, mais avant l'exécution de la ligne 8. Le programme s'arrête non seulement aux points d'arrêt et aux points de surveillance, mais aussi lorsqu'il reçoit certains signaux système. A l'aide de la commande suivante, vous pouvez arrêter l'outil de débogage chaque fois qu'il reçoit ces signaux système :
handle sig32 pass nostop noprint 
handle sigusr2 pass nostop noprint 

Examen du code

Lorsque la position correcte du code est atteinte, il existe plusieurs façons d'examiner le code. La plus utile est backtrace (abrégé en bt), qui montre la pile d'appels. La pile d'appels est la collection des cadres de fonction, où chaque cadre de fonction contient des informations telles que les paramètres de fonction et les variables locales. Ces cadres de fonction sont placés dans la pile d'appels dans l'ordre dans lequel ils sont exécutés. La dernière fonction appelée est donc affichée en haut de la pile d'appels. Vous pouvez suivre la trace d'exécution d'un programme en examinant la pile d'appels. Lorsque la pile d'appels est affichée, elle indique un numéro de cadre en début de ligne, suivi de l'adresse de la fonction appelante, puis du nom de la fonction et de son fichier source. Par exemple :
#6 0x804c4d8 in myFunction () at myApplication.c

Pour voir des informations plus détaillés sur un cadre de fonction, utilisez la commande frame avec un paramètre indiquant le numéro de cadre. Après avoir sélectionné un cadre, vous pouvez afficher ses variables avec la commande print var.

Utilisez la commande print pour changer la valeur d'une variable ; par exemple, print var = newValue.

La commande info locals affiche les valeurs de toutes les variables locales de la fonction sélectionnée.

Pour suivre la séquence d'exécution exacte de votre programme, utilisez les commandes step et next. Les deux commandes prennent un paramètre facultatif qui indique le nombre de lignes à exécuter. Cependant, next traite les appels de fonction comme une seule ligne d'exécution, tandis que step progresse ligne par ligne dans la fonction appelée, étape après étape.

Commandes utiles

Lorsque vous avez terminé le débogage de votre code, la commande run permet au programme de s'exécuter jusqu'à la fin ou jusqu'au point où le plantage se produit. la commande quit permet de quitter gdb.

Autres commandes utiles :

ptype
Imprime le type de données des variables.
info share
Imprime les noms des bibliothèques partagées qui sont chargées actuellement.
info functions
Imprime tous les prototypes de fonction.
list
Affiche les 10 lignes de code source autour de la ligne en cours.
help
Affiche la liste des sujets pour lesquels vous pouvez appeler la commande help, afin d'afficher une aide détaillée sur cette rubrique.