बिल्ड लक्ष्य के बाहर gcc डीबग प्रतीक कैसे उत्पन्न करें?


176

मुझे पता है कि मैं -g विकल्प का उपयोग करके डिबग प्रतीक उत्पन्न कर सकता हूं। हालाँकि प्रतीक को लक्ष्य फ़ाइल में एम्बेड किया गया है। क्या परिणाम निष्पादन योग्य / पुस्तकालय के बाहर डिबग प्रतीक उत्पन्न कर सकता है? जैसे .pdb विंडो की विंडोज़ वीसी ++ कंपाइलर ने किया।

जवाबों:


184

डिबग जानकारी को अलग करने के लिए आपको objcopy का उपयोग करने की आवश्यकता है :

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

मैं डीबग जानकारी को .debug निर्देशिका में .debug एक्सटेंशन के साथ फ़ाइलों में अलग करने के लिए नीचे दिए गए 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}"

8
यदि आपको उत्पादन में समस्या है और प्रक्रिया को gdb के साथ संलग्न करने की आवश्यकता है, तो क्या आप GDB को डिबग प्रतीक फ़ाइल प्रदान कर पाएंगे? और कैसे, यदि ऐसा है तो? thnx
यवेस ब्यूम्स

3
@yves बॉम्स बस अपने उत्पादन बॉक्स में .debug फ़ाइलों के साथ .debug निर्देशिका जोड़ें और GDB उन्हें चुनना चाहिए। डिबग सत्र के बाद आप उन्हें फिर से निकाल सकते हैं।
लोसर

एक उदाहरण के लिए @Lance रिचर्डसन की टिप्पणियों का जवाब दें।
गुरुग्राम

7
क्या मूल बाइनरी को पुनर्स्थापित करना संभव है (जैसे कि बाइनरी + .debug फ़ाइल = मूल बाइनरी)?
पॉल प्रीत

1
क्या आपको --build-idलिंकर विकल्प को छोड़ने में कोई समस्या है ?
1

110

डिबग जानकारी के साथ संकलित करें:

gcc -g -o main main.c

डिबग जानकारी अलग करें:

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

या

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

मूल फ़ाइल से डीबग जानकारी स्ट्रिप करें:

objcopy --strip-debug main

या

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

डीबगिंक मोड द्वारा डीबग करें:

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

आप निष्पादन फ़ाइल और प्रतीक फ़ाइल को अलग-अलग उपयोग कर सकते हैं:

gdb -s main.debug -e main

या

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

ब्योरा हेतु:

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

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


2
और आपको objcopy --add-gnu-debuglink main main.debugबनाई गई डीबग फ़ाइल और एक चेकसम का नाम एम्बेड करने के लिए उपयोग करना चाहिए । इस मामले में gdb डिबग कोड को स्वयं कुछ वितरण निर्भर स्थानों में खोजने का प्रयास करेगा, अब -s विकल्प की आवश्यकता नहीं है।
लोथार

9

स्ट्रिप कमांड का "--only-keep-debug" विकल्प देखें ।

लिंक से:

आशय यह है कि इस विकल्प का उपयोग दो-भाग निष्पादन योग्य बनाने के लिए --add-gnu-debuglink के साथ संयोजन में किया जाएगा। एक स्ट्रिप्ड बाइनरी जो रैम और एक वितरण में कम जगह घेरेगी और दूसरा डिबगिंग सूचना फ़ाइल जो केवल डिबगिंग क्षमताओं की आवश्यकता होने पर आवश्यक है।


1
हां, मैंने इसे आज़माया है: gcc -ggdb -o test test.c; cp परीक्षण test.debug; पट्टी - अकेला रखने-डिबग test.debug; पट्टी परीक्षण; objcopy --add-gnu-debuglink = test.debug परीक्षण; इसके बाद टेस्ट डेब्यू करना ठीक है
zhaorufei

8

नोट: उच्च-अनुकूलन स्तरों (-O3, -O4) के साथ संकलित कार्यक्रम अनुकूलित चर, इन-लाइन किए गए फ़ंक्शंस और अनियंत्रित लूपों के लिए कई डीबगिंग प्रतीकों को उत्पन्न नहीं कर सकते हैं, भले ही प्रतीकों को (-g) एम्बेड किया गया हो या (objcopy) एक में '.debug' फ़ाइल।

वैकल्पिक दृष्टिकोण हैं

  1. संकलक के निष्पादन योग्य (-O3, -O4) के लिए प्रोग्राम में संस्करण (VCS, git, svn) डेटा एम्बेड करें।
  2. निष्पादन योग्य का दूसरा गैर-अनुकूलित संस्करण बनाएँ।

पहला विकल्प बाद की तारीख में पूर्ण डिबगिंग और प्रतीकों के साथ उत्पादन कोड के पुनर्निर्माण का साधन प्रदान करता है। मूल उत्पादन कोड को बिना किसी अनुकूलन के फिर से बनाने में सक्षम होना डिबगिंग के लिए एक जबरदस्त मदद है। (नोट: यह माना जाता है कि परीक्षण कार्यक्रम के अनुकूलित संस्करण के साथ किया गया था)।

आपकी निर्माण प्रणाली संकलन दिनांक, प्रतिबद्ध और अन्य VCS विवरणों से भरी हुई .c फ़ाइल बना सकती है। यहाँ एक 'मेक + गिट' उदाहरण है:

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

कार्यक्रम संकलित होने के बाद आप कमांड का उपयोग करके अपने कोड के लिए मूल 'कमिट' का पता लगा सकते हैं: 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

जो कुछ बचा है, वह मूल कोड की जांच करना, अनुकूलन के बिना फिर से संकलित करना, और डिबगिंग शुरू करना है।


3
-O4मौजूद भी नहीं है।
हाय-एंजेल

3
उफ़, यह 'सनकी' दिनों से हो सकता है, जहाँ '-ओ 5' एक विकल्प भी था। यहाँ gcc4.4.7 -O विकल्पों का लिंक दिया गया है: gcc.gnu.org/oniltocs/gcc-4.4.7/gcc/…
J Jorgenson

3
यह कोर डंप की व्याख्या करने की कोशिश की आम समस्या को संबोधित नहीं करता है जो आसानी से प्रतिलिपि प्रस्तुत करने योग्य नहीं हो सकता है। इस उत्तर में सलाह ध्वनि है, लेकिन यह प्रश्न को संबोधित नहीं करता है।
डेविड रॉड्रिग्ज -

4

अब तक कोई जवाब नहीं उल्लेख है eu-strip --strip-debug -f <out.debug> <input>

  • यह elfutilsपैकेज द्वारा प्रदान किया गया है।
  • इसका परिणाम यह होगा कि <input>फाइल डिबग प्रतीकों से छीन ली गई है जो अब सभी में हैं <out.debug>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.