İnşa hedefi dışında gcc hata ayıklama sembolü nasıl oluşturulur?


176

-G seçeneğini kullanarak hata ayıklama simgesi oluşturabileceğimi biliyorum. Ancak sembol hedef dosyaya gömülür. Gcc, sonuç yürütülebilir / kitaplığının dışında hata ayıklama simgesi oluşturabilir mi? Windows VC ++ derleyicisinin .pdb dosyası gibi yaptım.

Yanıtlar:


184

Sen kullanmak gerekir objcopy için hata ayıklama bilgilerini ayırmak :

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

Hata ayıklama bilgilerini bir .debug dizininde bir .debug uzantılı dosyalara ayırmak için aşağıdaki bash komut dosyasını kullanın. Bu şekilde bir tar dosyasındaki kütüphaneleri ve yürütülebilir dosyaları, başka bir dosyadaki .debug dizinlerini tarlayabilirim. Hata ayıklama bilgilerini daha sonra eklemek isterseniz, sadece hata ayıklama tar dosyasını ayıklayın ve sembolik hata ayıklama bilgim var.

Bu bash betiği:

#!/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
Üretimde bir sorununuz varsa ve işlemi gdb ile eklemeniz gerekiyorsa, hata ayıklama sembolü dosyasını GDB'ye sağlayabilir misiniz? Ve nasıl, eğer öyleyse? thnx
yves Baumes

3
@ yves Baumes Üretim kutunuza .debug dosyaları içeren .debug dizinini eklemeniz yeterlidir; GDB bunları almalıdır. Hata ayıklama oturumundan sonra bunları tekrar kaldırabilirsiniz.
lothar

Örnek için @Lance Richardson cevap yorumlarına bakınız.
GuruM

7
Orijinal ikili dosyayı geri yüklemek de mümkün mü (örn. Soyulmuş ikili + .debug dosyası = orijinal ikili)?
Paul Praet

1
--build-idBağlayıcı seçeneğini atlamakla ilgili herhangi bir sorun buluyor musunuz ?
jww

110

Hata ayıklama bilgileriyle derleyin:

gcc -g -o main main.c

Hata ayıklama bilgilerini ayırın:

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

veya

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

Kaynak dosyadaki hata ayıklama bilgilerini şeritle:

objcopy --strip-debug main

veya

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

hata ayıklama modu ile hata ayıklama:

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

Ayrıca exec ve sembol dosyalarını ayrı ayrı kullanabilirsiniz:

gdb -s main.debug -e main

veya

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

Detaylar için:

(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


2
Ve objcopy --add-gnu-debuglink main main.debugoluşturulan hata ayıklama dosyasının adını ve bir sağlama toplamı eklemek için kullanmalısınız . Bu durumda gdb hata ayıklama kodunu birkaç dağıtıma bağlı konumda bulmaya çalışacaktır, artık -s seçeneğine gerek yoktur.
Lothar

9

Strip komutunun "--only-keep-debug" seçeneğini işaretleyin .

Bağlantıdan:

Amaç, bu seçeneğin iki bölümlü yürütülebilir dosya oluşturmak için --add-gnu-debuglink ile birlikte kullanılmasıdır. Biri RAM'de ve bir dağıtımda daha az yer kaplayacak soyulmuş bir ikilik ve ikincisi sadece hata ayıklama yetenekleri gerektiğinde gerekli olan bir hata ayıklama bilgi dosyası.


1
Evet, denedim: gcc -ggdb -o test test.c; cp testi test.debug; şerit - sadece-tutmak-hata ayıklama test.debug; şerit testi; objcopy - add-gnu-debuglink = test.debug testi; Sonra test hata ayıklamak için sorun yok
zhaorufei

8

NOT: Yüksek optimizasyon düzeyleriyle (-O3, -O4) derlenen programlar, gömülü (-g) veya ayıklanan (objkopi) sembollerden bağımsız olarak, '.debug' dosyası.

Alternatif yaklaşımlar

  1. Derleyici için optimize edilmiş yürütülebilir dosyalar (-O3, -O4) için sürüm oluşturma (VCS, git, svn) verilerini programa gömün.
  2. Yürütülebilir dosyanın optimize edilmemiş ikinci bir sürümünü oluşturun.

İlk seçenek, daha sonraki bir tarihte tam hata ayıklama ve sembollerle üretim kodunu yeniden oluşturmak için bir yol sağlar. Herhangi bir optimizasyon olmadan orijinal üretim kodunu yeniden oluşturabilmek hata ayıklama için muazzam bir yardımcıdır. (NOT: Bu, testin programın optimize edilmiş sürümü ile yapıldığını varsayar).

Derleme sisteminiz, derleme tarihi, işleme ve diğer VCS ayrıntılarıyla dolu bir .c dosyası oluşturabilir. İşte bir 'make + git' örneği:

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

Program derlendikten sonra, şu komutu kullanarak kodunuz için orijinal 'commit' kodunu bulabilirsiniz: 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

Geriye kalan tek şey orijinal kodu teslim almak, optimizasyon olmadan yeniden derlemek ve hata ayıklamaya başlamaktır.


3
-O4bile yok.
Hi-Angel

3
Hata! '-O5' bile bir seçenek olan 'suncc' günlerinden olabilir. İşte gcc4.4.7 -O seçeneklerine bir bağlantı: gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/…
J Jorgenson

3
Bu, kolayca tekrar üretilemeyen bir çekirdek dökümü yorumlamaya çalışmanın ortak sorununu ele almaz. Bu cevaptaki tavsiye sağlıklıdır, ancak soruyu ele almaz.
David Rodríguez - dribeas

4

Şu ana kadar cevap yok eu-strip --strip-debug -f <out.debug> <input>.

  • Bu elfutilspaket tarafından sağlanır .
  • Sonuçta, <input>dosya şimdi içinde bulunan hata ayıklama sembollerinden arındırılmış olacaktır <out.debug>.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.