Le débogueur GNU ( GDB ) est un débogueur portable fonctionnant sur de nombreux systèmes de type Unix et compatible avec de nombreux langages de programmation , notamment Ada , Assembleur , C , C++ , D , Fortran , Haskell , Go , Objective-C , OpenCL C , Modula-2 , Pascal , Rust , et partiellement d'autres. Il détecte les problèmes d'un programme tout en le laissant s'exécuter et permet aux utilisateurs d'examiner les variables du programme et les registres de la machine.
Histoire
GDB a été initialement écrit par Richard Stallman en 1986 dans le cadre de son système GNU , après que son GNU Emacs soit devenu « relativement stable ». GDB est un logiciel libre distribué sous la licence publique générale GNU (GPL). Il a été conçu sur le modèle du débogueur DBX , fourni avec les distributions Berkeley Unix .
De 1990 à 1993, il était maintenu par John Gilmore . Il est maintenant maintenu par le comité directeur de GDB, nommé par la Free Software Foundation .
Caractéristiques techniques
GDB offre des fonctionnalités étendues pour le suivi, l'examen et la modification de l'exécution des programmes informatiques . L'utilisateur peut surveiller et modifier les valeurs des variables internes des programmes , et même appeler des fonctions indépendamment du comportement normal du programme.
Plateformes prises en charge
Processeurs cibles de GDB ( )Les architectures prises en charge incluent : Alpha , ARM , AVR , H8/300 , Altera Nios / Nios II , System/370 , System/390 , x86 ( 32 bits et 64 bits ), IA-64 « Itanium », Motorola 68k , MIPS , PA-RISC , PowerPC , RISC-V , SuperH , SPARC et VAX . Parmi les processeurs cibles moins connus pris en charge par la version standard, on peut citer : A29K , ARC , ETRAX CRIS , D10V, D30V, FR-30, FR-V , Intel i960 , 68HC11 , Motorola 88000 , MCORE , MN10200, MN10300 , NS32k , Stormy16 et Z8000 (certains de ces processeurs ne seront probablement pas pris en charge dans les versions ultérieures).
GDB intègre des simulateurs pour la plupart des cibles.
Exécution du code pas à pas
Les deux commandes `step` et `next` permettent de faire avancer l'exécution de n instructions. Si step` suit le flux d'exécution jusqu'aux éléments internes de tout appel de fonction, tandis que `next` exécute la fonction entière et passe à l'instruction suivante dans la routine courante. next nstep n
Cette commande permet soit d'ignorer une section de code problématique, soit de revenir à une instruction précédente afin d'en examiner à nouveau l'exécution. L'emplacement spécifié peut correspondre à différentes parties du programme en cours d'exécution, mais des résultats inattendus peuvent se produire pour les personnes non familiarisées avec le code machine . jump location
Valeurs et expressions d'impression
Lorsqu'un programme est interrompu en cours d'exécution, la commande `print` (abrégée ` p` ) permet d'afficher la valeur d'une variable ou d'une expression en utilisant la syntaxe C ou C++. La commande `x` (qui signifie « examiner ») est similaire, mais son argument est une adresse mémoire, y compris les expressions d'adresse. Ces deux commandes utilisent des options pour indiquer le format d'affichage de la sortie, bien que ` x` permette de spécifier le nombre d'octets.
par exemple :
De plus, la commande d'appel invoque à la fois les fonctions de la bibliothèque et les fonctions écrites par l'utilisateur, et la valeur renvoyée sera affichée.Les valeurs affichées sont automatiquement affectées à des variables d'historique de valeurs spéciales qui commencent par un signe $ suivi d'un numéro de séquence qui peut ensuite être réaffiché à l'aide de print .
c'est-à-dire :
On peut également utiliser la commande set pour créer des variables pratiques à utiliser pendant une session gdb.
par exemple :
Si l'argument de `print` est un tableau ou une structure, tous ses éléments seront affichés. La syntaxe suivante permet d'afficher une sous-partie du tableau :
c'est-à-dire :
{{rp|546}} "}},"i":0}}]Points de rupture et points de surveillance
Les points d'arrêt et les points de surveillance permettent d'examiner un programme avant une situation connue susceptible de provoquer une erreur. Chaque point d'arrêt et chaque point de surveillance se voit attribuer un numéro d'identification numérique (1, 2, 3…) qui permet de les activer, de les désactiver ou de les supprimer . La commande affiche tous les points d'arrêt et leur état actuel.info break|watch
Les points d'arrêt permettent de suspendre l'exécution du code à des numéros de ligne précis ou à l'entrée d'une fonction lors de son exécution dans le débogueur (par exemple : l' exécution s'arrêtera à la ligne 42 du fichier spécifié). Si le nom du fichier est omis, la référence est le fichier courant.breaksourcefile:42
Un point d'arrêt conditionnel s'arrête sur une ligne spécifiée lorsqu'une expression spécifiée est vraie, c'est-à-dire :
sourcefile:275 '''if''' productNum=1275" interrompre le fichier source :275 si productNum =1275Cette commande permet d'ajouter des conditions à un point d'arrêt établi. conditionbreakNumexpression
Les points d'observation interrompent l'exécution lorsqu'une variable ou une expression change de valeur, quel que soit l'endroit du programme où cela se produit. Par défaut, gdb surveille, lorsque cela est possible, l'emplacement mémoire où la modification a lieu ; une fonctionnalité utile étant donné que plusieurs pointeurs peuvent pointer vers la même adresse. À l'inverse, un point d'observation logiciel, plus lent, ne surveille que les variables.
Les commandes rwatch et awatch interrompent le programme chaque fois que l'emplacement mémoire ou la variable est lue.
Une autre caractéristique conditionnelle des watchs et des breakpoints est la commande qui ignore les critères d'arrêt jusqu'à ce que le nombre d'exécutions soit atteint. ignorebreakNumcount
La commande display configure gdb pour qu'il affiche automatiquement la valeur d'une expression à chaque arrêt. Les résultats de plusieurs commandes display sont cumulatifs et la sortie peut être formatée à l'aide des mêmes options que celles disponibles pour la commande x .
Piles d'images
Lorsqu'un programme est interrompu, il peut se trouver à plusieurs niveaux d'appels de fonctions. Chaque niveau d'appel de fonction est appelé un cadre et l'ensemble des cadres est appelé une pile de cadres. Lorsque l'exécution est interrompue, il est possible de naviguer vers le haut ou vers le bas jusqu'à un cadre spécifique afin d'examiner la valeur des variables ou des expressions à un niveau particulier, ce qui est utile pour le débogage des programmes. La commande `backtrace` fournit la liste de tous les cadres de la pile. La commande `info args` affiche tous les arguments passés au cadre courant et la commande `info local` affiche la liste des variables disponibles pour ce cadre, ainsi que leurs valeurs.
Assistance à la programmation
GDB permet de définir des routines de commandes pour automatiser les ensembles d'instructions gdb fréquemment répétés. Ces routines sont composées de commandes gdb placées entre…définir etLes paramètres de ces routines ne sont pas déclarés par leur nom, mais ils sont passés dans des variables spéciales $ arg1, $arg2, $arg3 … la variable spéciale $ argc représentant le nombre d'arguments de la ligne de commande.
De plus, gdb inclutsi /sinon etLes blocs while se terminent parendainsi queboucle_break etLes instructions loop_continue permettent de gérer le flux de contrôle.
par exemple :
\" set print pretty ''# display structures on multiple lines'' '''[[#if|if]]''' $argc==0 print \"There are no arguments to the command\" '''[[#else|else]]''' '''[[#break|break]]''' $arg0 '''end''' '''[[#define-end|end]]'''"}},"i":0}}]# Script pour définir l'invite gdb et un point d'arrêt define cmd définir l'invite "Mon débogueur> " définir print pretty # afficher les structures sur plusieurs lignes si $argc==0 print "Il n'y a pas d'arguments pour cette commande" sinon, interrompre $arg0 fin fin
Supposons que l'on débogue un programme C avec une liste chaînée générique , une valeur initiale etLe champ suivant pointant vers l'élément suivant, la commande suivante utiliserait unboucle while pour afficher tous les éléments :
next '''end''' '''end'''"}},"i":0}}]définir p_generic_list définir la variable $n = $arg0 tandis que $n imprimer *($n) définir la variable $n = $n->next fin fin
Les définitions de commandes placées dans le fichier local .gdbinit sont automatiquement chargées au début de la session gdb. Elles peuvent également être enregistrées dans des fichiers ordinaires et chargées à l'aide de la commande source .
À partir de la version 7.0, les nouvelles fonctionnalités incluent la prise en charge du script Python et à partir de la version 7.8, le script GNU Guile également, basé sur le langage de programmation Scheme .
Débogage réversible
Depuis la version 7.0, la prise en charge du « débogage réversible » est disponible. Cette fonctionnalité permet de revenir en arrière dans une session de débogage, un peu comme lorsqu'on rembobine un programme ayant planté pour en comprendre le déroulement. Elle est très gourmande en mémoire et ralentit l'exécution, avec une limite par défaut de 20 000 instructions. La procédure recommandée consiste à définir des points d'arrêt avant et après le problème suspecté, puis à exécuter la commande `record` lorsque le programme s'arrête au premier point d'arrêt. Poursuivez l'exécution jusqu'au second point d'arrêt. Les commandes `reverse-step` , `reverse-next` et `reverse-continue` permettent ensuite de revenir en arrière dans l'exécution, en annulant progressivement les modifications de variables. Toutefois, le débogage réversible n'annule pas les actions telles que les sorties console et ne réémet pas les événements externes comme les interruptions ou les paquets réseau entrants.
Débogage à distance
GDB propose un mode « distant » souvent utilisé pour le débogage de systèmes embarqués. En mode distant, GDB s'exécute sur une machine tandis que le programme à déboguer s'exécute sur une autre. GDB peut communiquer avec le « stub » distant, compatible avec le protocole GDB, via un périphérique série ou TCP/IP. Un programme stub peut être créé en liant les fichiers stub appropriés fournis avec GDB, qui implémentent la partie cible du protocole de communication. Il est également possible d'utiliser gdbserver pour déboguer le programme à distance sans avoir à le modifier.
Le même mode est également utilisé par KGDB pour déboguer un noyau Linux en cours d'exécution au niveau du code source avec gdb. Grâce à KGDB, les développeurs de noyau peuvent déboguer un noyau de manière similaire à celle utilisée pour les applications. Il est possible de placer des points d'arrêt dans le code du noyau, de parcourir le code pas à pas et d'observer les variables. Sur les architectures disposant de registres de débogage matériels, des points de surveillance peuvent être définis pour déclencher des points d'arrêt lors de l'exécution ou de l'accès à des adresses mémoire spécifiques. KGDB nécessite une machine supplémentaire connectée à la machine à déboguer via un câble série ou Ethernet . Sous FreeBSD , le débogage est également possible via l'accès direct à la mémoire (DMA) FireWire .
Interface utilisateur graphique
Le débogueur ne possède pas d'interface graphique et utilise par défaut une interface en ligne de commande , bien qu'il dispose d'une interface en mode texte . Plusieurs interfaces graphiques ont été développées pour GDB, telles que UltraGDB, Xxgdb, Data Display Debugger (DDD), Nemiver, KDbg, le débogueur Xcode , GDBtk/Insight, Gede, Seer, et HP Wildebeest Debugger GUI (WDB GUI). Les environnements de développement intégrés ( IDE) comme Codelite , Code::Blocks , Dev-C++ , Geany , GNAT Programming Studio (GPS), KDevelop , Qt Creator , Lazarus , MonoDevelop , Eclipse , NetBeans et Visual Studio peuvent interagir avec GDB. GNU Emacs propose un « mode GUD » et des outils existent pour Vim (par exemple, clewn). Ces outils offrent des fonctionnalités similaires aux débogueurs intégrés aux IDE.
D'autres outils de débogage ont été conçus pour fonctionner avec GDB, tels que les détecteurs de fuites de mémoire .
Internes
GDB utilise un appel système nommé ptrace (le nom est une abréviation de « process trace ») pour observer et contrôler l'exécution d'un autre processus, et examiner et modifier la mémoire et les registres du processus.
Un point d'arrêt est implémenté en remplaçant une instruction à une adresse mémoire donnée par une autre instruction spéciale. L'exécution de cette instruction d'arrêt provoque un signal SIGTRAP.