GDB - Guide rapide

Un débogueur est un programme qui exécute d'autres programmes, permettant à l'utilisateur d'exercer un contrôle sur ces programmes et d'examiner des variables lorsque des problèmes surviennent.

Débogueur GNU, également appelé gdb, est le débogueur le plus populaire pour les systèmes UNIX pour déboguer les programmes C et C ++.

GNU Debugger vous aide à obtenir des informations sur les éléments suivants:

  • Si un vidage de mémoire s'est produit, alors sur quelle instruction ou expression le programme s'est-il arrêté?

  • Si une erreur se produit lors de l'exécution d'une fonction, quelle ligne du programme contient l'appel à cette fonction et quels sont les paramètres?

  • Quelles sont les valeurs des variables du programme à un moment donné pendant l'exécution du programme?

  • Quel est le résultat d'une expression particulière dans un programme?

Comment GDB débogue-il?

GDB vous permet d'exécuter le programme jusqu'à un certain point, puis d'arrêter et d'imprimer les valeurs de certaines variables à ce stade, ou de parcourir le programme une ligne à la fois et d'imprimer les valeurs de chaque variable après avoir exécuté chaque ligne.

GDB utilise une interface de ligne de commande simple.

Points à noter

  • Même si GDB peut vous aider à découvrir les bogues liés aux fuites de mémoire, mais ce n'est pas un outil pour détecter les fuites de mémoire.

  • GDB ne peut pas être utilisé pour les programmes qui compilent avec des erreurs et il n'aide pas à corriger ces erreurs.

Avant de procéder à l'installation, vérifiez si gdb est déjà installé sur votre système Unix en exécutant la commande suivante:

$gdb -help

Si GDB est installé, il affichera toutes les options disponibles dans votre GDB. Si GDB n'est pas installé, procédez à une nouvelle installation.

Vous pouvez installer GDB sur votre système en suivant les étapes simples décrites ci-dessous.

step 1: Assurez-vous que vous disposez des conditions préalables à l'installation de gdb:

  • Un compilateur C conforme ANSI (gcc est recommandé - notez que gdb peut déboguer les codes générés par d'autres compilateurs)

  • 115 Mo d'espace disque libre sont requis sur la partition sur laquelle vous allez créer gdb.

  • 20 Mo d'espace disque libre sont requis sur la partition sur laquelle vous allez installer gdb.

  • Le programme de décompression de GNU, gzip

  • le make utilitaire - la version GNU est connue pour fonctionner sans problème, d'autres le font probablement aussi.

step 2: Téléchargez la distribution source gdb depuis ftp.gnu.org/gnu/gdb. (Nous avons utilisé gdb-6.6.tar.gz pour ces instructions.) Placez les fichiers de distribution dans votre répertoire de construction.

step 3:Dans votre répertoire de construction, décompressez gdb-6.6.tar.gz et extrayez les fichiers source de l'archive. Une fois l'extraction des fichiers terminée, remplacez votre répertoire de travail par le répertoire gdb-6.6 qui a été automatiquement créé dans votre répertoire de construction.

$ build> gzip -d gdb-6.6.tar.gz 
$ build> tar xfv gdb-6.6.tar 
$ build> cd gdb-6.6

step 4: Exécutez le script de configuration pour configurer l'arborescence source de votre plate-forme.

$ gdb-6.6> .⁄configure

step 5: Construisez gdb en utilisant le make utilitaire.

$ gdb-6.6> make

step 6: Connectez-vous en tant que root et installez gdb à l'aide de la commande suivante.

$ gdb-6.6> make install

step 7: Si nécessaire, l'espace disque peut être récupéré en supprimant le répertoire de construction gdb et le fichier d'archive une fois l'installation terminée.

$ gdb-6.6> cd .. 
$ build> rm -r gdb-6.6 
$ build> rm gdb-6.6.tar

Vous avez maintenant installé gdb sur votre système et il est prêt à être utilisé.

UNE Debugging Symbol Tablemappe les instructions du programme binaire compilé à leur variable, fonction ou ligne correspondante dans le code source. Ce mappage pourrait être quelque chose comme:

  • Instruction du programme ⇒ nom de l'élément, type d'élément, fichier d'origine, numéro de ligne défini.

Les tables de symboles peuvent être intégrées au programme ou stockées dans un fichier séparé. Donc, si vous prévoyez de déboguer votre programme, il est alors nécessaire de créer une table de symboles qui contiendra les informations requises pour déboguer le programme.

Nous pouvons déduire les faits suivants concernant les tables de symboles:

  • Une table de symboles fonctionne pour une version particulière du programme - si le programme change, une nouvelle table doit être créée.

  • Les versions de débogage sont souvent plus volumineuses et plus lentes que les versions de détail (sans débogage); les builds de débogage contiennent la table des symboles et d'autres informations auxiliaires.

  • Si vous souhaitez déboguer un programme binaire que vous n'avez pas compilé vous-même, vous devez obtenir les tables de symboles auprès de l'auteur.

Pour permettre à GDB de lire toutes ces informations ligne par ligne de la table des symboles, nous devons la compiler un peu différemment. Normalement, nous compilons nos programmes comme:

gcc hello.cc -o hello

Au lieu de faire cela, nous devons compiler avec l'indicateur -g comme indiqué ci-dessous:

gcc -g hello.cc -o hello

GDB propose une grande liste de commandes, mais les commandes suivantes sont celles les plus fréquemment utilisées:

  • b main - Met un point d'arrêt au début du programme

  • b - Place un point d'arrêt sur la ligne actuelle

  • b N - Place un point d'arrêt sur la ligne N

  • b +N - Met un point d'arrêt N lignes vers le bas de la ligne courante

  • b fn - Place un point d'arrêt au début de la fonction "fn"

  • d N - Supprime le numéro de point d'arrêt N

  • info break - lister les points d'arrêt

  • r - Exécute le programme jusqu'à un point d'arrêt ou une erreur

  • c - Continue d'exécuter le programme jusqu'au prochain point d'arrêt ou erreur

  • f - Fonctionne jusqu'à ce que la fonction en cours soit terminée

  • s - Exécute la ligne suivante du programme

  • s N - Exécute les N lignes suivantes du programme

  • n - Comme s, mais il n'entre pas dans les fonctions

  • u N - Fonctionne jusqu'à ce que vous obteniez N lignes devant la ligne actuelle

  • p var - Imprime la valeur actuelle de la variable "var"

  • bt - Imprime une trace de pile

  • u - Remonte d'un niveau dans la pile

  • d - Descend d'un niveau dans la pile

  • q - Quitte gdb

Mise en route: démarrage et arrêt

  • gcc -g monprogramme.c

    • Compile myprogram.c avec l'option de débogage (-g). Vous obtenez toujours un a.out, mais il contient des informations de débogage qui vous permettent d'utiliser des variables et des noms de fonctions dans GDB, plutôt que des emplacements de mémoire brute (pas amusant).

  • gdb a.out

    • Ouvre GDB avec le fichier a.out, mais n'exécute pas le programme. Vous verrez une invite (gdb) - tous les exemples proviennent de cette invite.

  • r

  • r arg1 arg2

  • r <fichier1

    • Trois façons d'exécuter «a.out», chargé précédemment. Vous pouvez l'exécuter directement (r), passer des arguments (r arg1 arg2) ou alimenter un fichier. Vous définissez généralement des points d'arrêt avant d'exécuter.

  • help

  • h points d'arrêt

    • Répertorie les rubriques d'aide (aide) ou obtient de l'aide sur un sujet spécifique (h points d'arrêt). GDB est bien documenté.

  • q - Quitter GDB

Parcourir le code

La procédure pas à pas vous permet de tracer le chemin de votre programme et de vous concentrer sur le code qui plante ou renvoie une entrée non valide.

  • l

  • l 50

  • ma fonction

    • Liste 10 lignes de code source pour la ligne courante (l), une ligne spécifique (l 50) ou pour une fonction (l mafonction).

  • prochain

    • Exécute le programme jusqu'à la ligne suivante, puis s'arrête. Si la ligne courante est une fonction, elle exécute toute la fonction, puis s'arrête.next est bon pour parcourir rapidement votre code.

  • étape

    • Exécute l'instruction suivante, pas la ligne. Si l'instruction actuelle définit une variable, c'est la même chose quenext. S'il s'agit d'une fonction, elle sautera dans la fonction, exécutera la première instruction, puis s'arrêtera.step est bon pour plonger dans les détails de votre code.

  • terminer

    • Termine l'exécution de la fonction en cours, puis pause (également appelée étape de sortie). Utile si vous êtes accidentellement entré dans une fonction.

Points d'arrêt ou points de surveillance

Les points d'arrêt jouent un rôle important dans le débogage. Ils mettent en pause (interrompent) un programme lorsqu'il atteint un certain point. Vous pouvez examiner et modifier les variables et reprendre l'exécution. Ceci est utile lorsqu'une défaillance d'entrée se produit ou que les entrées doivent être testées.

  • pause 45

  • casser ma fonction

    • Définit un point d'arrêt à la ligne 45 ou à ma fonction. Le programme se mettra en pause lorsqu'il atteindra le point d'arrêt.
  • regarder x == 3

    • Définit un point de surveillance, qui met le programme en pause lorsqu'une condition change (lorsque x == 3 change). Les points de surveillance sont parfaits pour certaines entrées (myPtr! = NULL) sans avoir à interrompre à chaque appel de fonction.

  • continuer

    • Reprend l'exécution après avoir été interrompu par un point d'arrêt / point de surveillance. Le programme continuera jusqu'à ce qu'il atteigne le prochain point d'arrêt / point de surveillance.

  • supprimer N

    • Supprime le point d'arrêt N (les points d'arrêt sont numérotés lors de leur création).

Définition des variables

L'affichage et la modification des variables au moment de l'exécution sont une partie essentielle du débogage. Essayez de fournir des entrées non valides aux fonctions ou d'exécuter d'autres cas de test pour trouver la cause première des problèmes. En règle générale, vous afficherez / définissez les variables lorsque le programme est en pause.

  • imprimer x

    • Imprime la valeur actuelle de la variable x. Être capable d'utiliser les noms de variables d'origine est la raison pour laquelle l'indicateur (-g) est nécessaire; les programmes compilés régulièrement font supprimer ces informations.

  • définir x = 3

  • définir x = y

    • Définit x sur une valeur définie (3) ou sur une autre variable (y)
  • appeler ma fonction ()

  • appeler mon autre fonction (x)

  • appel strlen (mystring)

    • Appelle les fonctions définies par l'utilisateur ou système. Ceci est extrêmement utile, mais méfiez-vous des appels de fonctions boguées.

  • afficher x

    • Affiche en permanence la valeur de la variable x, qui est affichée après chaque étape ou pause. Utile si vous recherchez constamment une certaine valeur.

  • non affiché x

    • Supprime l'affichage constant d'une variable affichée par la commande d'affichage.

Backtrace et changement de trames

Une pile est une liste des appels de fonction en cours - elle vous montre où vous vous trouvez dans le programme. Un cadre stocke les détails d'un seul appel de fonction, tels que les arguments.

  • bt

    • Backtracesou imprime la pile de fonctions actuelle pour montrer où vous vous trouvez dans le programme en cours. Si main appelle la fonction a (), qui appelle b (), qui appelle c (), le backtrace est

  • c <= current location 
    b 
    a 
    main
  • up

  • vers le bas

    • Passez à l'image suivante vers le haut ou vers le bas dans la pile de fonctions. Si vous êtesc, vous pouvez vous déplacer vers b ou a pour examiner les variables locales.

  • revenir

    • Retourne de la fonction actuelle.

Gestion des signaux

Les signaux sont des messages lancés après certains événements, tels qu'un minuteur ou une erreur. GDB peut faire une pause lorsqu'il rencontre un signal; vous voudrez peut-être les ignorer à la place.

  • handle [signalname] [action]

  • poignée SIGUSR1 nostop

  • poignée SIGUSR1 noprint

  • handle SIGUSR1 ignorer

    • Demandez à GDB d'ignorer un certain signal (SIGUSR1) lorsqu'il se produit. Il existe différents niveaux d'ignorance.

Parcourez les exemples suivants pour comprendre la procédure de débogage d'un programme et d'un core dump.

  • Exemple de débogage 1

    Cet exemple montre comment capturer une erreur qui se produit en raison d'une exception déclenchée lors de la division par zéro.

  • Exemple de débogage 2

    Cet exemple illustre un programme qui peut vider un cœur en raison d'une mémoire non initialisée.

Les deux programmes sont écrits en C ++ et génèrent un vidage de mémoire pour différentes raisons. Après avoir parcouru ces deux exemples, vous devriez être en mesure de déboguer vos programmes C ou C ++ générant des vidages de mémoire.

Après avoir parcouru ce tutoriel, vous devez avoir acquis une bonne compréhension du débogage d'un programme C ou C ++ à l'aide de GNU Debugger. Maintenant, il devrait être très facile pour vous d'apprendre les fonctionnalités des autres débogueurs car ils sont très similaires à GDB. Il est fortement recommandé de passer par d'autres débogueurs pour vous familiariser avec leurs fonctionnalités.

Il existe de nombreux bons débogueurs disponibles sur le marché:

  • DBX Debugger- Ce débogueur est livré avec Sun Solaris et vous pouvez obtenir des informations complètes sur ce débogueur en utilisant la page de manuel de dbx, c'est-à-dire man dbx .

  • DDD Debugger- Ceci est une version graphique de dbx et disponible gratuitement sur Linux. Pour avoir un détail complet, utilisez la page de manuel de ddd, c'est-à-dire man ddd .

Vous pouvez obtenir des détails complets sur le débogueur GNU à partir du lien suivant: Débogage avec GDB