GNU Debugger

Un article de Wikipédia, l'encyclopédie libre.
Sauter à la navigation Sauter à la recherche

Page d'aide sur l'homonymie Pour les articles homonymes, voir GDB.

GNU Debugger, également appelé GDB, est le débogueur standard du projet GNU. Il est portable sur de nombreux systèmes type Unix et fonctionne pour plusieurs langages de programmation, comme le C, C++,Fortran, Ada, Objective-C, et le Go. Il fut écrit par Richard Stallman en 1988. GDB est un logiciel libre, distribué sous la licence GNU GPL.

Histoire[modifier | modifier le code]

GDB a été écrit en premier par Richard Stallman en 1986 en parallèle de son système GNU, après que GNU Emacs ait été considéré comme "raisonnablement stable". GDB est un logiciel libre sorti sous Licence publique générale GNU (GPL). Il s'inspire du débogueur DBX, qui faisait partie de la distribution Unix de Berkeley.

De 1990 à 1993 il a été maintenu par John Gilmore. Maintenant, il est maintenu par le comité de direction GDB qui a été créé par la Free Software Foundation[2].

Caractéristiques[modifier | modifier le code]

GDB fonctionne sur de nombreuses architectures de processeur différentes, et permet le débogage distant (par l'intermédiaire d’une liaison série ou d’une connexion IP) d’applications tournant sur une plateforme cible distincte de la plateforme de développement. Ceci éventuellement sur deux types de processeurs différents.

GDB permet de déboguer un programme en cours d’exécution (en le déroulant instruction par instruction ou en examinant et modifiant ses données), mais il permet également un débogage post-mortem en analysant un fichier core qui représente le contenu d’un programme terminé anormalement.

Interfaces utilisateur[modifier | modifier le code]

L’interface de GDB est une simple ligne de commande, mais il existe des applications frontales qui lui offrent une interface graphique beaucoup plus conviviale. L’utilitaire ddd par exemple permet de cliquer sur une ligne de code directement dans le listing pour y placer un point d’arrêt alors que GDB seul nécessite la saisie du numéro de ligne. Notons également que GDB est souvent invoqué en arrière-plan par les environnements de développement intégré comme Eclipse[3].

Débogage à distance[modifier | modifier le code]

GDB offre un mode "distant" qui peut être souvent utilisé lors d'un débogage sur des systèmes intégrés. L’opération à distance correspond au moment où GDB s’exécute sur un ordinateur et que le programme en cours de débogage s’exécute sur un autre ordinateur. GDB peut également communiquer avec le "stub" distant qui comprend le protocole GDB via un périphérique série ou via le protocole TCP/IP. Un programme de remplacement peut être créé en liant aux fichiers de raccord appropriés fournis avec GDB, qui implémentent le côté cible du protocole de communication.implémentent le côté cible du protocole de communication. Il est également possible d'utiliser gdbserver pour déboguer le programme à distance sans avoir à le modifier.

KGDB utilise également le même mode pour déboguer un noyau Linux en cours d’exécution au niveau source avec gdb. Avec KGDB, les développeurs de noyau peuvent déboguer un noyau de la même manière qu’ils déboguent des programmes d’application. Il permet de placer des points d'arrêt dans le code du noyau, de parcourir le code et également d'observer des variables. Sur certaines architectures où les registres de débogage matériel sont disponibles, il est possible de définir des points de contrôle qui déclenchent des points d'arrêt lorsque des adresses de mémoire spécifiées sont exécutées. KGDB nécessite un ordinateur supplémentaire connecté à l’ordinateur pour être débogué à l’aide d’un câble série ou Ethernet. Sur le système d'exploitation FreeBSD, il est également possible de déboguer en utilisant l'accès direct à la mémoire Firewire.

Exemples de commandes[modifier | modifier le code]

gdb program lance gdb avec le programme "program"
run -v démarre le programme chargé avec le paramètre "-v"
bt affiche la trace d'appels (utile dans le cas où le programme crashe)
info registers affiche l'ensemble des registres
disas main désassemble la fonction main

Exemple d'utilisation[modifier | modifier le code]

Considérons le code source suivant écrit en C:

//Bibliothèques standard du C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

size_t foo_len( const char *s )
{
  return strlen( s );
}

int main( int argc, char *argv[] )
{
  const char *a = NULL;

  printf( "size of a = %lu\n", foo_len(a) );

  return 0;
}

Si on utilise le compilateur GCC sous Linux, le code ci-dessus doit être compilé avec l'indicateur -g afin d'inclure les informations de débogage appropriées sur le binaire généré, permettant ainsi de l'inspecter à l'aide de GDB. En supposant que le fichier contenant le code ci-dessus s'appelle exemple.c, la commande pour la compilation pourrait être :

$ gcc exemple.c -Og -g -o exemple

Et le binaire peut maintenant être exécuté :

$ ./exemple
Segmentation fault

Lorsque le binaire est exécuté, il génère une erreur de segmentation, GDB peut être utilisé pour inspecter le problème afin de le résoudre.

$ gdb ./exemple
GNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /path/exemple...done.
(gdb) run
Starting program: /path/exemple

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400527 in foo_len (s=0x0) at exemple.c:8
8	  return strlen (s);
(gdb) print s
$1 = 0x0

Le problème est présent à la ligne 8 et se produit lors de l'appel de la fonction strlen (car son argument, s, est NULL). En fonction de la mise en œuvre de strlen (en ligne ou non), le résultat peut être différent, par exemple:

GNU gdb (GDB) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/gdb/exemple...done.
(gdb) run
Starting program: /tmp/gdb/exemple

Program received signal SIGSEGV, Segmentation fault.
0xb7ee94f3 in strlen () from /lib/i686/cmov/libc.so.6
(gdb) bt
#0  0xb7ee94f3 in strlen () from /lib/i686/cmov/libc.so.6
#1  0x08048435 in foo_len (s=0x0) at exemple.c:8
#2  0x0804845a in main (argc=<optimized out>, argv=<optimized out>) at exemple.c:16

Pour résoudre ce problème, la variable a (dans la fonction main) doit contenir une chaîne valide. Par exemple :

//Bibliothèques standard du C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

size_t foo_len( const char *s )
{
  return strlen(s);
}

int main( int argc, char *argv[] )
{
  //correction ici
  const char *a = "Hello World!\n";

  printf( "size of a = %lu\n", foo_len(a) );

  return 0;
}

Maintenant si on recompile et exécute de nouveau le binaire avec GDB, le résultat est correct :

GNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /path/exemple...done.
(gdb) run
Starting program: /path/exemple
size of a = 21
[Inferior 1 (process 14290) exited normally]

GDB affiche sur la sortie standard que le programme s'est terminé normalement.

Bibliographie[modifier | modifier le code]

  • (en) Richard Stallman, Roland Pesch, Stan Shebs et al, Debugging with GDB : The GNU Source-Level Debugger, Free Software Foundation, , 10e éd., 616 p. (ISBN 978-0-9831592-3-0)
  • (en) Arnold Robbins, GDB Pocket Reference, O'Reilly Media, , 1re éd., 78 p. (ISBN 978-0-596-10027-8)

Sur les autres projets Wikimedia :

Voir aussi[modifier | modifier le code]

Notes et références[modifier | modifier le code]

  1. « GDB 8.3 released! » (consulté le 11 mai 2019)
  2. (en) « GDB Steering Committee » (consulté le 11 mai 2008)
  3. (en) Norman Matloff et Peter Jay Salzman, The Art of Debugging with GDB, DDD and Eclipse, No Starch Press, , 264 p. (ISBN 9781593271749).

Liens externes[modifier | modifier le code]