Bagaimana cara menghasilkan simbol debug gcc di luar target build?

176

Saya tahu saya bisa membuat simbol debug menggunakan opsi -g. Namun simbol tertanam dalam file target. Bisakah gcc membuat simbol debug di luar hasil executable / library? Seperti file .pdb dari kompiler windows VC ++ lakukan.

kcwu
sumber

Jawaban:

184

Anda perlu menggunakan keberatan untuk memisahkan informasi debug :

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

Saya menggunakan skrip bash di bawah ini untuk memisahkan informasi debug ke dalam file dengan ekstensi .debug di direktori .debug. Dengan cara ini saya bisa tar pustaka dan executables dalam satu file tar dan direktori .debug di yang lain. Jika saya ingin menambahkan info debug nanti saya cukup mengekstrak file tar debug dan voila saya memiliki informasi debug simbolis.

Ini skrip 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}"
lothar
sumber
8
Jika Anda memiliki masalah dalam produksi dan perlu melampirkan proses dengan gdb, apakah Anda dapat memberikan file simbol debug ke GDB? Dan bagaimana, jika demikian? thnx
yves Baumes
3
@Yves Baumes Cukup tambahkan direktori .debug dengan file .debug ke kotak produksi Anda dan GDB harus mengambilnya. Setelah sesi debug Anda dapat menghapusnya lagi.
lothar
Lihat @Lance Richardson untuk menjawab komentar.
GuruM
7
Apakah mungkin untuk mengembalikan biner asli (mis. File biner + .debug yang dilucuti = biner asli)?
Paul Praet
1
Apakah Anda menemukan masalah dengan menghilangkan --build-idopsi tautan ?
jww
110

Kompilasi dengan informasi debug:

gcc -g -o main main.c

Pisahkan informasi debug:

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

atau

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

Hapus informasi debug dari file asal:

objcopy --strip-debug main

atau

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

debug dengan mode debuglink:

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

Anda juga dapat menggunakan file exec dan file simbol secara terpisah:

gdb -s main.debug -e main

atau

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

Untuk detail:

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

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

herodot
sumber
2
Dan Anda harus menggunakan objcopy --add-gnu-debuglink main main.debuguntuk menanamkan nama file debug yang dibuat dan checksum. Dalam hal ini gdb akan mencoba menemukan kode debug itu sendiri di beberapa lokasi tergantung distribusi, opsi no -s diperlukan lagi.
Lothar
9

Periksa opsi "--only-keep-debug" dari perintah strip .

Dari tautan:

Tujuannya adalah bahwa opsi ini akan digunakan bersama dengan --add-gnu-debuglink untuk membuat dua bagian yang dapat dieksekusi. Satu biner yang dilucuti yang akan menempati lebih sedikit ruang dalam RAM dan dalam distribusi dan yang kedua file informasi debugging yang hanya diperlukan jika kemampuan debugging diperlukan.

Lance Richardson
sumber
1
Ya, saya sudah mencobanya: gcc -ggdb -o test test.c; cp test test.debug; strip --only-keep-debug test.debug; tes strip; objcopy --add-gnu-debuglink = test.debug test; Maka tidak apa-apa untuk menguji debug
zhaorufei
8

CATATAN: Program yang dikompilasi dengan level optimisasi tinggi (-O3, -O4) tidak dapat menghasilkan banyak simbol debug untuk variabel yang dioptimalkan, fungsi in-lined dan loop yang tidak dikontrol, terlepas dari simbol yang tertanam (-g) atau diekstraksi (keberatan) ke dalam File '.debug'.

Pendekatan alternatif adalah

  1. Cantumkan data versi (VCS, git, svn) ke dalam program, untuk kompiler yang dapat dieksekusi yang dapat dieksekusi (-O3, -O4).
  2. Bangun versi ke-2 yang tidak dioptimalkan yang dapat dieksekusi.

Opsi pertama menyediakan sarana untuk membangun kembali kode produksi dengan debugging penuh dan simbol di kemudian hari. Mampu membangun kembali kode produksi asli tanpa optimasi adalah bantuan luar biasa untuk debugging. (CATATAN: Ini mengasumsikan pengujian dilakukan dengan versi program yang dioptimalkan).

Sistem build Anda dapat membuat file .c yang dimuat dengan tanggal kompilasi, komit, dan detail VCS lainnya. Berikut ini contoh '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

Setelah program dikompilasi, Anda dapat menemukan 'komit' asli untuk kode Anda dengan menggunakan perintah: 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

Yang tersisa hanyalah memeriksa kode asli, mengkompilasi ulang tanpa optimisasi, dan mulai debugging.

J Jorgenson
sumber
3
-O4bahkan tidak ada.
Hi-Angel
3
Ups, itu mungkin mulai dari hari 'suncc', di mana '-O5' bahkan merupakan opsi. Berikut tautan ke opsi gcc4.4.7 -O: gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/…
J Jorgenson
3
Ini tidak membahas masalah umum dalam mencoba menafsirkan dump inti yang mungkin tidak mudah direproduksi. Saran dalam jawaban ini masuk akal, tetapi tidak menjawab pertanyaan.
David Rodríguez - dribeas
4

Tidak ada jawaban yang disebutkan sejauh ini eu-strip --strip-debug -f <out.debug> <input>.

  • Ini disediakan oleh elfutilspaket.
  • Hasilnya adalah <input>file tersebut telah dilucuti dari simbol debug yang sekarang semuanya ada <out.debug>.
Unapiedra
sumber