Déboguer un crash de processus (par GDB etc.)

Sources - outils utiles

Outils d'analyse de code source (décortiquer une arborescence de fichiers source)

Debug de crash de processus

Paquets à installer (avec l'option --nodeps si certains paquets manquent)
  • glibc-debuginfo-xxxxxxxxx.rpm

Outil pour installer les debuginfo

  • # debuginfo-install ... (gdb indique les noms des paquets des logiciels concernés)
Fichiers à consulter
  • $HOME/.xsession-errors
  • /var/log/messages
  • /var/crash - peut collecter lors d'un crash des logs, traces et core dumps
Outil Apport
  • Collecte automatiquement des données et crée un rapport dans /var/crash, un rapport de bug pré-formatté peut être soumis à Launchpad
  • Infos : Apport wiki, DebuggingProgramCrash, /usr/share/doc/apport, man apport-unpack
  • Exemple de génération de rapport dans /tmp/rapport :
    • # apport-unpack /var/crash/virtualbox-4.1.0.crash /tmp/rapport
  • Paquets : apport, apport-gtk, apport-kde, apport-retrace, python-apport
  • apport-gtk et apport-kde sont des interfaces GUI qui permettent de gérer et de parcourir ces rapports
  • apport-retrace combines an Apport crash report (either a file or a Launchpad bug) and debug symbol (.ddebs packages) into fully symbolic stack traces. This can use a sandbox for installing debug symbol packages and doing the processing, so that entire process of retracing crashes can happen with normal user privileges without changing the system.

Autres outils

GDB (Gnu Debugger)

GDB est un débogueur pour C, C++, Java, Fortran, Perl, assembleur... qui permet de déboguer un fichier exécutable, un fichier core, ou un programme en cours d'exécution.

Liens

Utiles pour GDB

Interfaces pour GDB, permettant d'afficher le source du programme durant le déboguage

  • Interfaces en mode texte
    • gdbtui, ou : gdb --tui
      • ou, dans gdb : Ctrl-x suivi de Ctrl-a.
    • cgdb  (source en couleur, par ncurses)
      • existe en packages GNU/Linux et en exécutable Windows.
  • Vim & GDB
  • Interfaces graphiques multi-fenêtres (GUI)
    • ddd : GUI de Gnu pour gdb, pydb, etc.
      • $ info ddd
    • wdb GUI : GUI pour wdb (portage de gdb), sur HP-UX

Options gdb

A placer dans .gdbinit

Analyseur de backtrace

btparser, du projet ABRT (Automatic Bug Reporting Tool)
  • analyse les backtraces, générés par GDB de cette manière :
    • (gdb) set logging on
           Copying output to gdb.txt.
      (gdb) t a a bt full
  • ABRT : doc, abrt-cli : tuto, doc

Options de compilation utiles

  • gcc -g -O0 le_programme.c
    • évite l'affichage de "value optimized out" à la place de la valeur de la variable, lors d'un "print la_variable".

Préparation système (tuto)

Config dynamique

# mkdir -p /tmp/cores && chmod a+w /tmp/cores
# ulimit -c unlimited
# sysctl -w fs.suid_dumpable=1   (ou 2 si lisible slt par root, par sécurité)
# sysctl -w "kernel.core_pattern=/tmp/cores/%e-%s.%t"   (nom du programme et du signal, nb de sec. depuis le 1er janv. 1970 0h)
# kill -6 un_pid   (pour vérifier si cela fonctionne)

Config statique

Ajouter dans /etc/profile :
ulimit -c unlimited >/dev/null 2>&1

Ajouter dans /etc/sysctl.conf :
fs.suid_dumpable=1
kernel.core_pattern = /tmp/cores/%e-%s.%t

# sysctl -p
# echo "DAEMON_COREFILE_LIMIT='unlimited'" >> /etc/sysconfig/init   (RHEL, etc.)
Et reboot pour prendre en compte cette dernière.

Debug

$ gdb /le/path/du/binaire le_pid
$ gdb /le/path/du/binaire core

Commandes gdb
Raccourci
Infos
help


help lacommande





attach lepid

S'attache à un processus actif, dont le pid peut être trouvé par : ps aux.



Gestion des interruptions


handle all nostop


handle all pass


handle 11 stop





Infos


info


info sources

Indique où sont les sources, etc.
info proc
Infos sur le programme.
info functions

Infos sur les fonctions du programme.



quit
q
Sortir.
kill

Tuer le process.



list    
GDB affiche 10 lignes, ou les 10 suivantes.
list 3,8

GDB affiche les lignes 3 à 8.
list main





Backtrace


backtrace
bt
GDB affiche l'empilage des fonctions appelées (call stack, stack trace) ainsi que des infos sur chaque stack frame
where

De même.
backtrace full
bt full
De même, mais affiche également le contenu des variables.
backtrace 4
bt 4 full

set backtrace limit 8

Limite à 8 le nombre de frames affichées.
frame 4
Sélectionne la frame 4 et affiche ses infos.
info frame


info args

GDB affiche les arguments passés à la fonction.
info locals

GDB affiche les variables locales et leur contenu.



Threads


info thread

Affiche les infos concernant les threads.
where all
where lethread


thread lethread

Ce thread deviendra le thread courant.
thread apply all where
thread apply 7 where
thread apply lethread lacommande

Pour voir ce que font tous les threads.
Pour voir ce que fait le thread n°7.



Navigation


start

GDB s'arrêtera à la première ligne du main.
step
s
GDB exécute une ligne de code.
next
n
De même, mais si la ligne appelle une fonction, exécute la fonction.
finish

GDB exécute toute la fonction en cours et affiche la valeur retournée
(execute until selected stack frame returns).
run
GDB s'arrêtera au prochain breakpoint.
continue
c
GDB continuera jusqu'au prochain breakpoint/watchpoint.



Breakpoints


info breakpoints
info break Liste les breakpoints et leur n°.
break main

GDB positionne un breakpoint sur main.
break lafonction
GDB positionne un breakpoint à l'entrée de la fonction.
break
b 15
b vlc.c 2400
GDB positionne un breakpoint à la ligne 15.
Autre exemple : b 15 if i==4
condition

A utiliser si le breakpoint est déjà défini.
Exemple, condition sur le breakpoint n°1 : condition 1 i==4
rbreak

Breakpoint défini à partir d'une expression régulière.
delete 3

GDB enlève le breakpoint n°3.
commands 2

Permet de faire exécuter des commandes lorsqu'on atteint le breakpoint n°2.
asm("int $0x3\n");

Insertion d'un "breakpoint exception" dans le code source (architectures 64 et IA-32, systèmes x86).



Variables


print lavariable
print *lepointeur
print /x lavariable
p i
p env
p *env
GDB affiche le contenu de la variable, d'une expression C, ou affiche sur quoi pointe le pointeur.
display lavariable
display *lepointeur

De même, mais affichera les modifs au fur et à mesure.



Watchpoints

Breakpoints associés à une variable.
info watchpoints
info watch
watch lavariable
GDB s'arrêtera quand le contenu de cette variable sera modifié.
watch i if i==-1

GDB s'arrêtera quand le contenu de i sera égal à -1.
rwatch

GDB s'arrêtera quand la variable sera lue.



GDB avancé


x

Examiner la mémoire (voir : help x).
info proc mappings

Affiche le mapping mémoire, etc.
disass main
Désassemble les lignes de main.



Remote


maintenance

Voir : help maintenance.

Commands

Permet de faire exécuter des commandes lorsqu'on atteint le breakpoint.

Exemple - faire afficher par GDB des infos au niveau du breakpoint et continuer d'exécuter le programme :

(gdb) break 350           (ajoute un breakpoint à la ligne 350 du programme)
(gdb) break 361           (ajoute un breakpoint à la ligne 361 du programme)
(gdb) commands 2       (taper ensuite les commandes à éxécuter lorsqu'on atteindra le breakpoint n°2)
>print lavariable         (commande : afficher le contenu de la variable)
>continue                     (commande : continuer d'exécuter le programme)
>end

Générer un core à partir d'un processus

  • # gcore un_pid   (gcore fait partie du paquet gdb)
  • # kill -6 un_pid

Déboguer un fichier core

Tutos

Exemple de debug par gdb

  1. A faire, si ce n'est pas déjà configuré
    1. # sysctl -w kernel.core_uses_pid=1   (fera suivre le fichier core du numéro de PID du processus)
      1. ou, ajouter dans /etc/sysctl.conf : kernel.core_uses_pid=1
    2. # sysctl -w kernel.suid_dumpable=2
    3. # sysctl -w kernel.core_pattern=/tmp/core
    4. $ ulimit -c unlimited
    5. $ ulimit -v unlimited
  2. Relancer le programme qui plante
  3. Exécuter gdb
    1. $ gdb -c le_core le_binaire_du_programme
    1. $ gdb -d le_dossier_du_src_du_prog le_binaire_du_prog le_core_du_prog
      1. (gdb) list
      2. (gdb) bt
      3. (gdb) bt full
      4. (gdb) thread apply all bt
      5. (gdb) thread apply all bt full
      6. (gdb) frame 4   (par exemple, dans le cas où le main est en frame 4)
      7. etc.
Note : si tous les threads sont bloqués dans l'état pthread_cond_wait, il y a un deadlock.

Debug de programme Java

Complémentaire

Ajout dans les sources d'appels à la fonction printf, avec l'option -v ou avec des ifdef.




Vic
Page modifiée le 7 octobre 2013

Page d'accueil du site

Etre informé d'un changement de cette page

Fourni par ChangeDetection / Vie privé - Charte antispam