GNU/Linux >> Tutoriels Linux >  >> Linux

Comment déboguer des programmes C sous Linux à l'aide de gdb

Quelle que soit votre expérience en tant que codeur, tout logiciel que vous développez ne peut pas être totalement exempt de bogues. Ainsi, identifier les bugs et les corriger est l'une des tâches les plus importantes du cycle de développement logiciel. Bien qu'il existe de nombreuses façons d'identifier les bogues (tests, auto-examen du code, etc.), il existe des logiciels dédiés - appelés débogueurs - qui vous aident à comprendre exactement où se situe le problème, afin que vous puissiez le résoudre facilement.

Si vous êtes un programmeur C/C++ ou que vous développez des logiciels à l'aide des langages de programmation Fortran et Modula-2, vous serez heureux d'apprendre qu'il existe un excellent débogueur - baptisé GDB - qui vous permet de déboguer facilement votre code pour les bogues et autres problèmes. Dans cet article, nous aborderons les bases de GDB, y compris certaines des fonctionnalités/options utiles qu'il propose.

Mais avant d'aller de l'avant, il convient de mentionner que toutes les instructions ainsi que les exemples présentés dans cet article ont été testés sur Ubuntu 14.04LTS. L'exemple de code utilisé dans le tutoriel est écrit en langage C; le shell de ligne de commande que nous avons utilisé est bash (version 4.3.11) ; et la version GDB que nous avons utilisée est 7.7.1.

Principes de base du débogueur GDB

En termes simples, GDB vous permet de jeter un coup d'œil à l'intérieur d'un programme pendant son exécution, ce qui vous permet d'identifier exactement où se situe le problème. Nous discuterons de l'utilisation du débogueur GDB à travers un exemple pratique dans la section suivante, mais avant cela, ici, nous discuterons de quelques points de base qui vous aideront plus tard.

Tout d'abord, pour utiliser avec succès des débogueurs comme GDB, vous devez compiler votre programme de manière à ce que le compilateur produise également les informations de débogage requises par les débogueurs. Par exemple, dans le cas du compilateur gcc, que nous utiliserons pour compiler l'exemple de programme C plus tard dans ce tutoriel, vous devez utiliser le -g option de ligne de commande lors de la compilation de votre code.

Pour savoir ce que dit la page de manuel du compilateur gcc à propos de cette option de ligne de commande, rendez-vous ici.

L'étape suivante consiste à vous assurer que GDB est installé sur votre système. Si ce n'est pas le cas et que vous êtes sur un système basé sur Debian comme Ubuntu, vous pouvez facilement installer l'outil à l'aide de la commande suivante :

sudo apt-get install gdb

Pour une installation sur n'importe quelle autre distribution, rendez-vous ici.

Maintenant, une fois que vous avez compilé votre programme de manière à ce qu'il soit prêt pour le débogage et que GDB soit présent sur votre système, vous pouvez exécuter votre programme en mode débogage à l'aide de la commande suivante :

gdb [prog-executable-name]

Bien que cela lance le débogueur GDB, l'exécutable de votre programme ne sera pas lancé à ce stade. C'est le moment où vous pouvez définir vos paramètres liés au débogage. Par exemple, vous pouvez définir un point d'arrêt qui indique à GDB de suspendre l'exécution du programme à un numéro de ligne ou à une fonction particulière.

Ensuite, pour lancer réellement votre programme, vous devrez exécuter la commande gdb suivante :

run

Il convient de mentionner ici que si votre programme nécessite que certains arguments de ligne de commande lui soient transmis, vous pouvez les spécifier ici. Par exemple :

run [arguments]

GDB fournit de nombreuses commandes utiles qui sont utiles lors du débogage. Nous aborderons certains d'entre eux dans l'exemple de la section suivante.

Exemple d'utilisation de GDB

Nous avons maintenant une idée de base sur GDB ainsi que sur son utilisation. Alors prenons un exemple et appliquons les connaissances là-bas. Voici un exemple de code :

#include <stdio.h>

int main()
{
int out = 0, tot = 0, cnt = 0;
int val[] = {5, 54, 76, 91, 35, 27, 45, 15, 99, 0};

while(cnt < 10)
{
out = val[cnt];
tot = tot + 0xffffffff/out;
cnt++;
}

printf("\n Total = [%d]\n", tot);
return 0;
}

Donc, fondamentalement, ce que fait ce code est qu'il sélectionne chaque valeur contenue dans le tableau 'val', l'attribue à l'entier 'out', puis calcule 'tot' en additionnant la valeur précédente de la variable et le résultat de '0xffffffff/ out.'

Le problème ici est que lorsque le code est exécuté, il produit l'erreur suivante :

$ ./gdb-test 
Floating point exception (core dumped)

Ainsi, pour déboguer le code, la première étape serait de compiler le programme avec -g. Voici la commande :

gcc -g -Wall gdb-test.c -o gdb-test

Ensuite, lançons GDB et faisons-lui savoir quel exécutable nous voulons déboguer. Voici la commande pour cela :

gdb ./gdb-test 

Maintenant, l'erreur que j'obtiens est une "exception de virgule flottante", et comme la plupart d'entre vous le savent peut-être déjà, elle est causée par n % x, lorsque x vaut 0. Donc, dans cet esprit, j'ai mis un point d'arrêt au numéro de ligne 11, où la division a lieu. Cela a été fait de la manière suivante :

(gdb) break 11

Notez que '(gdb)' est l'invite du débogueur, je viens d'écrire la commande 'break'.

Maintenant, j'ai demandé à GDB de lancer l'exécution du programme :

run

Ainsi, lorsque le point d'arrêt a été atteint pour la première fois, voici ce que GDB a montré dans la sortie :

Breakpoint 1, main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;
(gdb)

Comme vous pouvez le voir dans la sortie ci-dessus, le débogueur a montré la ligne où le point d'arrêt a été placé. Maintenant, affichons la valeur actuelle de 'out.' Cela peut être fait de la manière suivante :

(gdb) print out
$1 = 5
(gdb)

Comme vous pouvez voir que la valeur "5" a été imprimée. Donc, tout va bien pour le moment. J'ai demandé au débogueur de continuer l'exécution du programme jusqu'au prochain point d'arrêt, ce qui peut être fait en utilisant la commande 'c'.

c  

J'ai continué à faire ce travail, jusqu'à ce que j'ai vu que la valeur de 'out' était zéro.

...
...
...
Breakpoint 1, main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;
(gdb) print out
$2 = 99
(gdb) c
Continuing.

Breakpoint 1, main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;
(gdb) print out
$3 = 0
(gdb)

Maintenant, pour confirmer que c'est bien le problème, j'ai utilisé la commande 's' (ou 'step') de GDB au lieu de 'c' cette fois. La raison étant que je voulais juste que la ligne 11, où l'exécution du programme est actuellement en pause, s'exécute et voit si un plantage se produit à ce stade.

Voici ce qui s'est passé :

(gdb) s

Program received signal SIGFPE, Arithmetic exception.
0x080484aa in main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;

Oui, comme le confirme la sortie en surbrillance ci-dessus, c'est là que l'exception a été levée. La confirmation finale est venue lorsque j'ai essayé d'exécuter à nouveau la commande 's' :

(gdb) s 

Program terminated with signal SIGFPE, Arithmetic exception.
The program no longer exists.

Ainsi, vous pouvez déboguer vos programmes à l'aide de GDB.

Conclusion

Nous n'avons fait qu'effleurer la surface ici, car GDB offre de nombreuses fonctionnalités à explorer et à utiliser pour les utilisateurs. Parcourez la page de manuel de GDB pour en savoir plus sur l'outil et essayez de l'utiliser chaque fois que vous déboguez quelque chose dans votre code. Le débogueur a un peu de courbe d'apprentissage qui lui est associé, mais cela en vaut la peine.


Linux
  1. Déboguer Linux avec ProcDump

  2. Linux - Comment déboguer un problème de suspension en RAM sous Linux ?

  3. Comment redémarrer Linux en utilisant la ligne de commande

  4. Comment tuer un processus sous Linux en utilisant la commande ?

  5. Comment déboguer le programme C en utilisant gdb en 6 étapes simples

Comment faire des captures d'écran sous Linux avec Scrot

Comment renommer des fichiers en utilisant la ligne de commande sous Linux

Comment supprimer des programmes installés à partir de la source à l'aide de GNU Stow sous Linux

Comment lister les systèmes de fichiers sous Linux à l'aide de Lfs

Comment formater des programmes Shell à l'aide de Shfmt sous Linux

Comment utiliser GDB pour déboguer des programmes dans Ubuntu 20.04