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

StackOverflow https://stackoverflow.com/questions/866721

  •  22-08-2019
  •  | 
  •  

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.

Était-ce utile?

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

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

  1. Intégrer la gestion des versions (VCS, git, svn) des données dans le programme, pour optimiser les exécutables du compilateur (O3, -O4).
  2. 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.

scroll top