{{tag>compilation programmation}}
----
====== Débuggage avec gdb ======
===== Description =====
gdb, acronyme de GNU DeBugger, est un programme qui, comme son nom l'indique, permet de débugger un programme (langages C et C++ principalement, ainsi que d'autres : fortran 77, etc..). Il permet donc de traquer les bugs/erreurs se trouvant dans tout programme.
Cet outil, indispensable à tout programmeur, bien que très performant n'est disponible qu'avec une interface en ligne de commande. Heureusement, il existe des interfaces graphiques qui facilitent le débuggage.
===== Installation =====
[[:tutoriel:comment_installer_un_paquet|Installez les paquets]] **[[apt>build-essential,gdb]]**
Si vous développez en utilisant une bibliothèque particulière, vous pouvez éventuellement installer le paquet de débuggage, dont le nom finit par **-dbg**, en plus du paquet de développement (dont le nom finit par **-dev**).
===== Utilisation basique =====
==== Compilation du programme pour le débuggage ====
Pour que gdb puisse débugger un programme, il a besoin des informations de débuggage, qui peuvent être ajoutées en ajoutant l'option **-g** au compilateur.
Exemple :
gcc -g toto.c -o toto
==== Lancement de gdb ====
Un fois le programme compilé, invoquez gdb comme ceci :
gdb toto
on peut lancer avec l'option //-tui//
gdb -tui toto
qui permet de visualiser le code, les points d'arrêt… bref plus visuel… mais semble buggé
Dans l'interface de gdb, vous pouvez lancer le programme avec **run** et quitter le débogueur avec **quit**.
À tout moment, vous pouvez interrompre le programme avec le raccourci clavier **Ctrl+C** dans le terminal. La commande **where** vous permettra alors de voir la pile des appels.
Pour reprendre l'exécution du programme, tapez **continue**.
Si vous souhaitez changer l'exécutable ciblé par gdb, **exec monexecutable** peut vous être utile.
La commande **start** lance le programme et s'arrête à la première ligne : la commande "n" permet ensuite de faire du pas-à-pas.
Si le programme a des paramètres d'entrée, il faut les ajouter à la suite de **run** (ou **start**) ou le mettre en ligne de commande (attention, taper **gdb --args monprogramme monoption mesoptions**).
==== Résumé des principales commandes ====
^commande ^raccourci ^effet ^
|run | r | lance le programme (s'arrête au prochain point d'arrêt) |
|continue | c | relance le programme (s'arrête au prochain point d'arrêt) |
|~~~ | ~~~ | ~~~ |
|break [yyy.c:]xx | b [yyy.c:]xx | place un point d'arrêt à la ligne xx du fichier yyy.c (si indiqué) |
|info breakpoints | info breakpoints | liste les points d'arrêts |
|delete [x] | d [x] | efface les points d'arrêts si pas d'argument, ou le point d'arrêt correspondant au n° x |
|~~~ | ~~~ | ~~~ |
|next | n | exécute une instruction (ne rentre pas dans les fonctions) peut-être suivi du nombre de ligne à exécuter |
|step | s | exécute une instruction (rentre potentiellement dans les fonctions) |
|finish | f | exécute les instructions jusqu'à la sortie de la fonction |
|list | l | affiche 10 lignes de code centrée sur la ligne à exécuter |
|until xx | u xx | exécute les instructions jusqu'à la ligne xx
|
|
|monitor reset halt | | reset la target, permet de recommencer l'execution et le debug depuis le debut du code
===== Utilisation avancée =====
==== Placer des points d'arrêt (breakpoints) ====
Si vous soupçonnez une fonction particulière de faire bugger votre programme, vous pouvez placer un //breakpoint// (point d'arrêt) avant le lancement de cette fonction. Pour ce faire, utilisez la commande **break mafonction** (sans les parenthèses).
Si la fonction désirée est située dans une classe ou un //namespace// (espace de noms) **niveau_englobant**, elle est accessible depuis **niveau_englobant::mafonction**.
Pour afficher la liste des points d'arrêt, utilisez **info breakpoints**. Vous remarquerez que chaque point d'arrêt est identifié par un numéro :
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x08049850 in thor::GameApp::catchEvents()
at src/gameapp.cpp:104
Ici, il a pour identifiant 1. S'il ne vous intéresse plus, vous pouvez le supprimer avec la commande **delete 1**.
Plus généralement, on peut placer un point d'arrêt à la ligne xx en écrivant ''break xx''
Pour aller au prochain point d'arrêt, écrire ''continue''.
==== Afficher la valeur d'une variable ====
Il est possible d'afficher la valeur d'une variable une fois que le programme a été interrompu, grâce à la commande print ma_variable
ou encore, en abbrégé et en spécifiant un type (x:hexa, d:decimal, f:float, c:char, s:string… help x pour les voir tous):
p/f ma_variable_reelle
La même remarque (§ précédent) sur la portée, concernant les classes et les espaces de nom s'applique ici.\\
et pour une variable qui est un tableau de char de 16 caractères:
p/c ma_char_chaine@16
===== Interfaces graphiques =====
Il existe de multiples interfaces graphiques pour gdb qui facilitent grandement le débuggage en affichant le code source, créant des schémas représentant les variables, etc. En voici quelques-unes :
* Nemiver: interface de gdb s'intégrant bien à Gnome
* [[http://kdbg.org|Kdbg]]: interface de gdb s'intégrant bien à KDE
* ddd: interface graphique très complète pour de nombreux debuggers dont gdb
* xxgdb: interface de gdb pour X
* [[https://github.com/cgdb/cgdb|cgdb]]: interface de type ncurses
* gdb-mode pour emacs
==== Pour Vim/GVim ====
* [[https://github.com/larrupingpig/vimgdb-for-vim7.4|VimGDB]]
* [[https://www.vim.org/scripts/script.php?script_id=4582|Conque GDB]]
* [[https://sourceforge.net/projects/clewn|Clewn]]
==== Pour IDE ====
Aussi, quelques environnements de développement incluent une interface graphique pour **gdb** ; c'est le cas d'[[:anjuta|Anjuta]], d'[[:eclipse|Eclipse]] ou encore de [[:kdevelop|KDevelop]].
===== Concurrents =====
Enfin signalons le concurrent **idb** (d'intel, non libre) qui a un mode "gdb" (même syntaxe) et qui affiche correctement les tableaux, ce qui n'est pas le cas de gdb pour le [[fortran]]. Il s'installe en même temps que le compilateur [[fortran#intel_fortran_compiler|ifort]].
Pas besoin de compiler avec ifort pour déboguer avec idb.
===== Liens =====
* (en) [[http://sourceware.org/gdb/documentation/|La documentation officielle]]
* (fr) [[http://www.linux-france.org/article/devl/gdb_howto.html|Un tutorial simple sur linux-france.org]]
* (fr) [[https://www.rocq.inria.fr/secret/Anne.Canteaut/COURS_C/gdb.html|tuto de Anne Canteaut de l'INRIA, bien documenté]]
* (fr) [[https://openclassrooms.com/courses/deboguer-son-programme-avec-gdb|tuto sur openclassrooms, bien documenté]]
* (fr) [[https://devarea.developpez.com/dix-choses-faisables-avec-GDB/|Dix choses qu'on ne peut faire qu'avec GDB]]
* (fr) [[http://www.linux-france.org/article/devl/gdb.html|Utilisation de gdb-mode sous Emacs sur linux-france.org]]
* (en) [[http://www.gnu.org/software/ddd/|Le site de ddd (interface graphique pour debuggers dont gdb)]]
* (en) [[http://cgdb.sourceforge.net/|Le site de cgdb]]