বিল্ড টার্গেটের বাইরে জিসিসি ডিবাগ প্রতীক কীভাবে তৈরি করবেন?


176

আমি জানি আমি -g বিকল্পটি ব্যবহার করে ডিবাগ প্রতীক তৈরি করতে পারি। তবে চিহ্নটি ফাইলের মধ্যে এম্বেড করা আছে। জিসিসি ফলাফল নির্বাহী / গ্রন্থাগারের বাইরে ডিবাগ প্রতীক তৈরি করতে পারে? উইন্ডোজ ভিসি ++ সংকলক এর .pdb ফাইল পছন্দ।

উত্তর:


184

ডিবাগের তথ্য আলাদা করতে আপনাকে অবজকপি ব্যবহার করতে হবে :

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

আমি .debug ডিরেক্টরিতে একটি .debug এক্সটেনশন দিয়ে ডিবাগ তথ্য ফাইলে পৃথক করতে নীচের ব্যাশ স্ক্রিপ্টটি ব্যবহার করি। এইভাবে আমি লাইব্রেরিগুলি এবং এক্সিকিউটেবলগুলিকে একটি টার ফাইল এবং অন্যটিতে .debug ডিরেক্টরিগুলিতে ট্যার করতে পারি। আমি পরে ডিবাগ তথ্য যুক্ত করতে চাইলে আমি কেবলমাত্র ডিবাগ টার ফাইলটি বের করি এবং ভয়েলা আমার কাছে প্রতীকী ডিবাগ তথ্য রয়েছে।

এটি বাশ লিপি:

#!/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
আপনার যদি উত্পাদনে সমস্যা হয় এবং প্রক্রিয়াটি জিডিবির সাথে সংযুক্ত করার প্রয়োজন হয়, আপনি কি জিডিবিতে ডিবাগ প্রতীক ফাইলটি সরবরাহ করতে পারবেন? এবং কিভাবে, যদি তাই? thnx
Yves Baumes

3
@ আইভেস বাউমস আপনার প্রযোজনা বাক্সে .debug ফাইলের সাথে কেবলমাত্র .debug ডিরেক্টরি যুক্ত করুন এবং জিডিবি সেগুলি বেছে নিতে হবে। ডিবাগ সেশনের পরে আপনি সেগুলি আবার মুছে ফেলতে পারেন।
লোথার

উদাহরণস্বরূপ @ ল্যান্স রিচার্ডসনের উত্তর মন্তব্যগুলি দেখুন।
গুরুএম

7
মূল বাইনারি পুনরুদ্ধার করাও সম্ভব (যেমন স্ট্রিপড বাইনারি + .ডেবগ ফাইল = আসল বাইনারি)?
পল প্রয়েট

1
বাদ দেওয়া --build-idলিংকার বিকল্পটি নিয়ে আপনি কি কোনও সমস্যা পেয়েছেন ?
jwww

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

সূত্র:
https://sourceware.org/gdb/onlinedocs/gdb/Files.html#Files https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html


2
এবং আপনার objcopy --add-gnu-debuglink main main.debugতৈরি করা ডিবাগ ফাইলের নাম এবং একটি চেকসাম এম্বেড করতে ব্যবহার করা উচিত । এক্ষেত্রে জিডিবি কয়েকটি বিতরণ নির্ভর স্থানগুলিতে ডিবাগ কোড নিজেই সন্ধান করার চেষ্টা করবে, নো-এস বিকল্পের আর প্রয়োজন নেই।
লোথার

9

স্ট্রিপ কমান্ডের "--only-keep-debug" বিকল্পটি দেখুন ।

লিঙ্ক থেকে:

উদ্দেশ্যটি হ'ল এই বিকল্পটি --add-gnu-debuglink এর সাথে দুটি অংশ এক্সিকিউটেবল তৈরির জন্য ব্যবহার করা হবে। একটি স্ট্রিপড বাইনারি যা র‌্যাম এবং বিতরণে কম স্থান দখল করবে এবং দ্বিতীয়টি একটি ডিবাগিং তথ্য ফাইল যা কেবলমাত্র ডিবাগিং সক্ষমতার প্রয়োজন হলে প্রয়োজনীয়।


1
হ্যাঁ, আমি এটি চেষ্টা করেছি: gcc -ggdb -o test.c.c; সিপি টেস্ট টেস্ট.দেবগ; স্ট্রিপ - কেবল-রাখুন-ডিবাগ পরীক্ষা.দেবগ; ফালা পরীক্ষা; objcopy --add-gnu-debuglink = test.debug test; তারপরে পরীক্ষার ডিবাগ করা ঠিক আছে
zhaorufei

8

দ্রষ্টব্য: উচ্চ-অপ্টিমাইজেশন স্তর (-O3, -O4) দিয়ে সংকলিত প্রোগ্রামগুলি অনুকূলিত ভেরিয়েবল, ইন-লাইনেড ফাংশন এবং আন-রেড লুপগুলির জন্য অনেকগুলি ডিবাগিং প্রতীক তৈরি করতে পারে না, প্রতীকগুলি এম্বেড (-জি) বা এক্সট্রাক্ট করা (অ্যাজকপি) কোনও ক্ষেত্রেই নির্বিশেষে '.debug' ফাইল।

বিকল্প পদ্ধতির হয়

  1. সংকলক অপ্টিমাইজড এক্সিকিউটেবল (-O3, -O4) এর জন্য প্রোগ্রামিংয়ে সংস্করণ (ভিসিএস, গিট, এসএনএন) ডেটা এম্বেড করুন।
  2. এক্সিকিউটেবলের ২ য় নন-অপ্টিমাইজড সংস্করণ তৈরি করুন।

প্রথম বিকল্পটি পরে ডিবেগিং এবং প্রতীক সহ প্রডাকশন কোডটি পুনর্নির্মাণের একটি উপায় সরবরাহ করে। কোনও অপ্টিমাইজেশন ছাড়াই মূল উত্পাদন কোডটি পুনরায় তৈরি করতে সক্ষম হওয়া ডিবাগিংয়ের জন্য একটি দুর্দান্ত সহায়তা। (দ্রষ্টব্য: অনুমান করা হয় যে প্রোগ্রামটির অনুকূলিত সংস্করণ দিয়ে পরীক্ষা করা হয়েছিল) testing

আপনার বিল্ড সিস্টেমটি সংকলনের তারিখ, প্রতিশ্রুতিবদ্ধ এবং অন্যান্য ভিসিএস বিবরণ সহ লোড করা একটি .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
ওফস, এটি 'সানসিসি' দিন হতে পারে, যেখানে '-O5' এমনকি একটি বিকল্প ছিল। এখানে gcc4.4.7 -O বিকল্পগুলির লিঙ্কটি রয়েছে: gcc.gnu.org/onlinesocs/gcc-4.4.7/gcc/…
জে

3
এটি কোনও মূল ডাম্প যা সহজেই পুনরুত্পাদনযোগ্য হতে পারে তা ব্যাখ্যা করার চেষ্টা করার সাধারণ সমস্যাটির সমাধান করে না। এই উত্তরের পরামর্শটি দুর্দান্ত, তবে এটি প্রশ্নের সমাধান করে না।
ডেভিড রদ্রিগেজ - ড্রিবিস

4

এখনও পর্যন্ত কোনও উত্তর উল্লেখ করা হয়নি eu-strip --strip-debug -f <out.debug> <input>

  • এটি elfutilsপ্যাকেজ দ্বারা সরবরাহ করা হয় ।
  • ফলাফলটি <input>হ'ল ফাইলটি ডিবাগ প্রতীকগুলি ছিনিয়ে নেওয়া হয়েছে যা এখন সবগুলিতে রয়েছে <out.debug>
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.