Comment générer le symbole de débogage gcc en dehors de la cible de construction?
Question
Je sais que je peux générer symboles de débogage en utilisant l'option -g. Cependant, le symbole est embeded dans le fichier cible. Peut-gcc générer le symbole de débogage en dehors de l'exécutable résultat / bibliothèque? Comme pdb fichier du compilateur de fenêtres VC fait.
La solution
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 script bash ci-dessous pour séparer les informations de débogage dans les fichiers avec une extension .debug dans un répertoire .debug. De cette façon, je peux goudrons les bibliothèques et exécutables dans un fichier tar et les répertoires de .debug dans un autre. Si je veux ajouter les informations de débogage plus tard je utiliser le dossier de goudron de débogage et le tour est joué, j'ai des informations de débogage symbolique.
Ceci est le script bash:
#!/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}"
Autres conseils
Compiler des 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
informations de débogage bande à partir du fichier d'origine:
objcopy --strip-debug main
ou
strip --strip-debug --strip-unneeded main
débogage en mode debuglink:
objcopy --add-gnu-debuglink main.debug main
gdb main
Vous pouvez également utiliser le fichier exec et le fichier symbole séparemment:
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
Vérifiez l'option "--only-keep-debug" de la .
À partir du lien:
L'intention est que cette option sera utilisée conjointement avec --add-gnu-debuglink pour créer un exécutable en deux parties. Un binaire dépouillé qui occupera moins d'espace dans la mémoire vive et une distribution et le second un fichier d'informations de débogage qui est nécessaire que si les capacités de débogage sont nécessaires.
NOTE: Les programmes compilés avec des niveaux de haute optimisation (-O3, -O4) ne peut pas générer beaucoup de symboles de débogage pour les variables optimisés, doublées des fonctions et des boucles déroulées, quelles que soient les symboles étant intégrés (-G) ou extrait (objcopy ) dans un fichier '.debug'.
approches alternatives sont
- Intégrer la gestion des versions (VCS, git, svn) des données dans le programme, pour optimiser les exécutables du compilateur (O3, -O4).
- Construire une 2ème version non optimisée de l'exécutable.
La première option est un moyen de reconstruire le code de production avec le débogage complet et les symboles à une date ultérieure. Être capable de reconstruire le code de production originale sans optimisation est une aide précieuse pour le débogage. . (NOTE: Cela suppose essais ont été effectués avec la version optimisée du programme)
Votre système de construction peut créer un fichier .c chargé de la date de compilation, validation, et d'autres détails de VCS. Voici un exemple «faire + 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 trouver l'original « commit » pour 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
Tout ce qui reste est de départ le code d'origine, re-compiler sans optimisation, et démarrer le débogage.