web-dev-qa-db-fra.com

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

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

165
kcwu

Vous devez utiliser objcopy pour 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 en fichiers avec une extension .debug dans un répertoire .debug. De cette façon, je peux tarifier 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, j'extrais simplement le fichier tar de débogage et voilà, j'ai des informations de débogage symboliques.

C'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}"
172
lothar

Compiler avec les informations de débogage:

gcc -g -o main main.c

Séparez les informations de débogage:

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

ou

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

Supprimer les informations de débogage du fichier Origin:

objcopy --strip-debug main

ou

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

déboguer en mode debuglink:

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

Vous pouvez également utiliser le fichier exec et le fichier de symboles séparément:

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

Ref:
https://sourceware.org/gdb/onlinedocs/gdb/Files.html#Fileshttps://sourceware.org/gdb/onlinedocs/gdb/Separate -Debug-Files.html

102
herodot

REMARQUE: 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 alignées et les boucles déroulées, quels que soient les symboles incorporés (-g) ou extraits (objcopy) dans un fichier. Fichier '.debug'.

Des approches alternatives sont

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

La première option fournit un moyen de reconstruire le code de production avec un débogage complet et des symboles à une date ultérieure. Le fait de pouvoir reconstruire le code de production d'origine sans optimisation est une aide précieuse pour le débogage. (REMARQUE: cela 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, la validation et d’autres détails relatifs à VCS. Voici un exemple '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" d'origine de votre code à l'aide de 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  [email protected]
VCS: COMMIT_DATE=2013-12-19

Tout ce qui reste à faire est d'extraire le code d'origine, de le recompiler sans optimisations et de lancer le débogage.

8
J Jorgenson

Découvrez l'option "--only-keep-debug" de la commande strip .

Du lien:

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

8
Lance Richardson