Câu trả lời:
Bạn cần sử dụng objcopy để tách thông tin gỡ lỗi :
objcopy --only-keep-debug "${tostripfile}" "${debugdir}/${debugfile}"
strip --strip-debug --strip-unneeded "${tostripfile}"
objcopy --add-gnu-debuglink="${debugdir}/${debugfile}" "${tostripfile}"
Tôi sử dụng tập lệnh bash bên dưới để phân tách thông tin gỡ lỗi thành các tệp có phần mở rộng .debug trong thư mục .debug. Bằng cách này, tôi có thể tar các thư viện và các tệp thực thi trong một tệp tar và các thư mục .debug trong một tệp khác. Nếu tôi muốn thêm thông tin gỡ lỗi sau này, tôi chỉ cần giải nén tệp tar gỡ lỗi và voila, tôi có thông tin gỡ lỗi tượng trưng.
Đây là tập lệnh 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}"
--build-id
tùy chọn liên kết ?
Biên dịch với thông tin gỡ lỗi:
gcc -g -o main main.c
Phân tách thông tin gỡ lỗi:
objcopy --only-keep-debug main main.debug
hoặc là
cp main main.debug
strip --only-keep-debug main.debug
Dải thông tin gỡ lỗi từ tệp gốc:
objcopy --strip-debug main
hoặc là
strip --strip-debug --strip-unneeded main
gỡ lỗi bằng chế độ gỡ lỗi:
objcopy --add-gnu-debuglink main.debug main
gdb main
Bạn cũng có thể sử dụng tệp exec và tệp ký hiệu riêng biệt:
gdb -s main.debug -e main
hoặc là
gdb
(gdb) exec-file main
(gdb) symbol-file main.debug
Để biết chi tiết:
(gdb) help exec-file
(gdb) help symbol-file
Tham khảo:
https://sourceware.org/gdb/onlinesocs/gdb/Files.html#Files
https://sourceware.org/gdb/onlinesocs/gdb/Separate-Debug-Files.html
objcopy --add-gnu-debuglink main main.debug
để nhúng tên của tệp gỡ lỗi đã tạo và tổng kiểm tra. Trong trường hợp này, gdb sẽ cố gắng tự tìm mã gỡ lỗi trong một vài vị trí phụ thuộc vào phân phối, không còn tùy chọn -s nữa.
Kiểm tra tùy chọn "--only-keep-debug" của lệnh dải .
Từ liên kết:
Mục đích là tùy chọn này sẽ được sử dụng cùng với --add-gnu-debuglink để tạo ra một phần thực thi hai phần. Một tệp nhị phân bị tước sẽ chiếm ít dung lượng trong RAM và trong bản phân phối và tệp thứ hai là tệp thông tin gỡ lỗi chỉ cần nếu khả năng gỡ lỗi là bắt buộc.
LƯU Ý: Các chương trình được biên dịch với mức tối ưu hóa cao (-O3, -O4) không thể tạo nhiều ký hiệu gỡ lỗi cho các biến được tối ưu hóa, các hàm được xếp hàng và các vòng lặp không được kiểm soát, bất kể các ký hiệu được nhúng (-g) hoặc trích xuất (objcopy) vào một Tập tin '.debug'.
Phương pháp thay thế là
Tùy chọn đầu tiên cung cấp một phương tiện để xây dựng lại mã sản xuất với đầy đủ gỡ lỗi và ký hiệu vào một ngày sau đó. Có thể xây dựng lại mã sản xuất ban đầu mà không cần tối ưu hóa là một trợ giúp to lớn để gỡ lỗi. (LƯU Ý: Giả định này đã được thực hiện với phiên bản tối ưu hóa của chương trình).
Hệ thống xây dựng của bạn có thể tạo tệp .c được tải cùng với ngày biên dịch, cam kết và các chi tiết VCS khác. Dưới đây là ví dụ '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
Sau khi chương trình được biên dịch, bạn có thể xác định vị trí 'cam kết' ban đầu cho mã của mình bằng cách sử dụng lệnh: 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
Tất cả những gì còn lại là kiểm tra mã gốc, biên dịch lại mà không tối ưu hóa và bắt đầu gỡ lỗi.
-O4
thậm chí không tồn tại.