188 votes

Comment générer le symbole de débogage de gcc en dehors de la cible de construction ?

Je sais que je peux générer un symbole de débogage en utilisant l'option -g. Cependant, le symbole est intégré dans le fichier cible. Gcc peut-il générer un symbole de débogage en dehors de l'exécutable/de la bibliothèque ? Comme le fait le fichier .pdb du compilateur VC++ de Windows.

195voto

lothar Points 11904

Vous devez utiliser objcopy à séparer les informations de débogage :

objcopy --only-keep-debug "${tostripfile}" "${debugdir}/${debugfile}"
strip --strip-debug --strip-unneeded "${tostripfile}"
objcopy --add-gnu-debuglink="${debugdir}/${debugfile}" "${tostripfile}"

J'utilise le bash script ci-dessous pour séparer les informations de débogage dans des fichiers avec une extension .debug dans un répertoire .debug. De cette façon, je peux mettre les bibliothèques et les exécutables dans un fichier tar et les répertoires .debug dans un autre. Si je veux ajouter les informations de débogage plus tard, il suffit d'extraire le fichier tar de débogage et voilà, j'ai des informations de débogage symboliques.

C'est le bash script :

#!/bin/bash

scriptdir=`dirname ${0}`
scriptdir=`(cd ${scriptdir}; pwd)`
scriptname=`basename ${0}`

set -e

function errorexit()
{
  errorcode=${1}
  shift
  echo $@
  exit ${errorcode}
}

function usage()
{
  echo "USAGE ${scriptname} <tostrip>"
}

tostripdir=`dirname "$1"`
tostripfile=`basename "$1"`

if [ -z ${tostripfile} ] ; then
  usage
  errorexit 0 "tostrip must be specified"
fi

cd "${tostripdir}"

debugdir=.debug
debugfile="${tostripfile}.debug"

if [ ! -d "${debugdir}" ] ; then
  echo "creating dir ${tostripdir}/${debugdir}"
  mkdir -p "${debugdir}"
fi
echo "stripping ${tostripfile}, putting debug info into ${debugfile}"
objcopy --only-keep-debug "${tostripfile}" "${debugdir}/${debugfile}"
strip --strip-debug --strip-unneeded "${tostripfile}"
objcopy --add-gnu-debuglink="${debugdir}/${debugfile}" "${tostripfile}"
chmod -x "${debugdir}/${debugfile}"

8 votes

Si vous avez un problème en production et que vous devez attacher le processus avec gdb, pourrez-vous fournir le fichier de symboles de débogage à GDB ? Et comment, si oui ?

3 votes

@yves Baumes Ajoutez simplement le répertoire .debug avec les fichiers .debug à votre machine de production et GDB devrait les récupérer. Après la session de débogage, vous pouvez les supprimer à nouveau.

0 votes

Voir les commentaires de la réponse de @Lance Richardson pour un exemple.

130voto

herodot Points 131

Compiler avec les informations de débogage :

gcc -g -o main main.c

Séparer les informations de débogage :

objcopy --only-keep-debug main main.debug

ou

cp main main.debug
strip --only-keep-debug main.debug

Supprime les informations de débogage du fichier d'origine :

objcopy --strip-debug main

ou

strip --strip-debug --strip-unneeded main

debug par le mode debuglink :

objcopy --add-gnu-debuglink main.debug main
gdb main

Vous pouvez également utiliser séparément le fichier d'exécution et le fichier de symboles :

gdb -s main.debug -e main

ou

gdb
(gdb) exec-file main
(gdb) symbol-file main.debug

Pour plus de détails :

(gdb) help exec-file
(gdb) help symbol-file

Réf :
https://sourceware.org/gdb/onlinedocs/gdb/Files.html#Files https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html

2 votes

Et vous devriez utiliser objcopy --add-gnu-debuglink main main.debug pour intégrer le nom du fichier de débogage créé et une somme de contrôle. Dans ce cas, gdb essaiera de trouver le code de débogage lui-même dans quelques emplacements dépendant de la distribution, l'option -s n'est plus nécessaire.

9voto

Lance Richardson Points 3566

Vérifiez l'option "--only-keep-debug" de la commande strip commandement.

Du lien :

L'intention est que cette option soit utilisée en conjonction avec --add-gnu-debuglink pour créer un exécutable en deux parties. L'une est un binaire dépouillé qui occupera moins d'espace en RAM et dans une distribution et la seconde est un fichier d'information de débogage qui n'est nécessaire que si des capacités de débogage sont requises.

1 votes

Oui, j'ai essayé : gcc -ggdb -o test test.c ; cp test test.debug ; strip --only-keep-debug test.debug ; strip test ; objcopy --add-gnu-debuglink=test.debug test ; Alors c'est ok pour déboguer test

9voto

J Jorgenson Points 632

NOTE : Les programmes compilés avec des niveaux d'optimisation élevés (-O3, -O4) ne peuvent pas générer de nombreux symboles de débogage pour les variables optimisées, les fonctions in-lined et les boucles unrolled, que les symboles soient intégrés (-g) ou extraits (objcopy) dans un fichier '.debug'.

D'autres approches sont

  1. Intégrer les données de versionnement (VCS, git, svn) dans le programme, pour les exécutables optimisés pour le compilateur (-O3, -O4).
  2. Construire une 2ème version non optimisée de l'exécutable.

La première option permet de reconstruire le code de production avec un débogage complet et des symboles à une date ultérieure. La possibilité de reconstruire le code de production original sans optimisation est une aide précieuse pour le débogage. (NOTE : Ceci suppose que les tests ont été effectués avec la version optimisée du programme).

Votre système de construction peut créer un fichier .c chargé avec la date de compilation, le commit et d'autres détails VCS. Voici un exemple de "make + git" :

program: program.o version.o 

program.o: program.cpp program.h 

build_version.o: build_version.c    

build_version.c: 
    @echo "const char *build1=\"VCS: Commit: $(shell git log -1 --pretty=%H)\";" > "$@"
    @echo "const char *build2=\"VCS: Date: $(shell git log -1 --pretty=%cd)\";" >> "$@"
    @echo "const char *build3=\"VCS: Author: $(shell git log -1 --pretty="%an %ae")\";" >> "$@"
    @echo "const char *build4=\"VCS: Branch: $(shell git symbolic-ref HEAD)\";" >> "$@"
    # TODO: Add compiler options and other build details

.TEMPORARY: build_version.c

Une fois le programme compilé, vous pouvez localiser le 'commit' original de votre code en utilisant la commande : strings -a my_program | grep VCS

VCS: PROGRAM_NAME=my_program
VCS: Commit=190aa9cace3b12e2b58b692f068d4f5cf22b0145
VCS: BRANCH=refs/heads/PRJ123_feature_desc
VCS: AUTHOR=Joe Developer  joe.developer@somewhere.com
VCS: COMMIT_DATE=2013-12-19

Il ne reste plus qu'à vérifier le code original, à le recompiler sans les optimisations et à commencer le débogage.

4 votes

-O4 n'existe même pas.

3 votes

Oups, cela date peut-être de l'époque de 'suncc', où '-O5' était même une option. Voici un lien vers les options -O de gcc4.4.7 : gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/

5 votes

Cela ne répond pas au problème courant qui consiste à essayer d'interpréter un vidage de noyau qui peut ne pas être facilement reproductible. Les conseils donnés dans cette réponse sont judicieux, mais il ne répond pas à la question.

0voto

meghapunjani Points 9

L'utilitaire GNU nm peut être utilisé pour générer le fichier de symboles à partir du fichier objet/exécutable. Voir la page de manuel pour les différentes options disponibles.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X