[英]gcc -g flag: Moving the Source Code
我的理解是,當您使用gcc -g
編譯C代碼時,gcc將插入包含對原始源代碼(例如行號)的引用的調試信息。 然后其他程序如gdb和objdump可以在以后恢復這些引用。 為了舉個例子,我們將使用objdump -S
來打印與相應源代碼交錯的程序集。
我的目標是將已編譯的二進制文件復制到另一台計算機,並仍然能夠檢索此調試信息。 但是,目前,當我這樣做時,所有的調試信息都會丟失。 我不介意復制源文件,但第二台計算機運行的是不同的操作系統,因此文件結構不同,我無法將源文件放在完全相同的絕對位置,這樣就無法查找objdump源代碼。 我查看了二進制文件,看到一個看起來像這樣穿插了一堆二進制文件的部分:
/home/path/to/source/code
我嘗試編輯它以匹配源的新路徑,但它只是使二進制文件無效。
我還研究了gcc標志,希望其中一個允許指定源代碼的相對路徑而不是絕對路徑,但我找不到類似的東西。
作為參考,這是我希望從objdump - S
獲得的輸出objdump - S
:
0804840b <main>:
#include <stdio.h>
int main(){
804840b: 8d 4c 24 04 lea 0x4(%esp),%ecx
804840f: 83 e4 f0 and $0xfffffff0,%esp
8048412: ff 71 fc pushl -0x4(%ecx)
8048415: 55 push %ebp
8048416: 89 e5 mov %esp,%ebp
8048418: 51 push %ecx
8048419: 83 ec 14 sub $0x14,%esp
for(int varName = 0; varName < 100; varName++){
804841c: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp)
8048423: eb 32 jmp 8048457 <main+0x4c>
for(int innerLoop = 0; innerLoop < 30; innerLoop++){
8048425: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp)
804842c: eb 1f jmp 804844d <main+0x42>
if(innerLoop == varName){
804842e: 8b 45 f4 mov -0xc(%ebp),%eax
8048431: 3b 45 f0 cmp -0x10(%ebp),%eax
8048434: 75 13 jne 8048449 <main+0x3e>
printf("%d\n", innerLoop);
8048436: 83 ec 08 sub $0x8,%esp
8048439: ff 75 f4 pushl -0xc(%ebp)
804843c: 68 f0 84 04 08 push $0x80484f0
8048441: e8 9a fe ff ff call 80482e0 <printf@plt>
8048446: 83 c4 10 add $0x10,%esp
#include <stdio.h>
int main(){
for(int varName = 0; varName < 100; varName++){
for(int innerLoop = 0; innerLoop < 30; innerLoop++){
8048449: 83 45 f4 01 addl $0x1,-0xc(%ebp)
804844d: 83 7d f4 1d cmpl $0x1d,-0xc(%ebp)
8048451: 7e db jle 804842e <main+0x23>
#include <stdio.h>
int main(){
for(int varName = 0; varName < 100; varName++){
8048453: 83 45 f0 01 addl $0x1,-0x10(%ebp)
8048457: 83 7d f0 63 cmpl $0x63,-0x10(%ebp)
804845b: 7e c8 jle 8048425 <main+0x1a>
804845d: b8 00 00 00 00 mov $0x0,%eax
if(innerLoop == varName){
printf("%d\n", innerLoop);
}
}
}
}
注意:雖然我使用objdump作為使用有關源文件信息的程序的一個例子,但它實際上並不是我感興趣的objdump的輸出。我正在運行一個需要訪問相同信息的不同程序。 問題是關於如何修復二進制文件,而不是如何使用objdump。
gcc和clang在生成調試信息時,會將DWARF屬性DW_AT_comp_dir
設置為目標文件中每個編譯單元的工作目錄。
cc a.c b.c -g -o foo
objdump -Wi foo
會表現出類似的東西
Contents of the .debug_info section:
Compilation Unit @ offset 0x0:
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<11> DW_AT_name : a.c
<15> DW_AT_comp_dir : (indirect string, offset: 0x0): /home/user/src
Compilation Unit @ offset 0x4d:
<0><58>: Abbrev Number: 1 (DW_TAG_compile_unit)
<5e> DW_AT_name : b.c
<62> DW_AT_comp_dir : (indirect string, offset: 0x0): /home/user/src
該程序通常用於轉換目標文件objcopy ,目前不支持更改這些DWARF屬性。
但是gcc和clang采用了-fdebug-prefix-map選項,它應該在編譯時做你想要的。
由於gcc使用libiberty的getpwd
函數獲取當前目錄,該函數使用PWD
環境變量(在檢查其正確性之后)優先於libc的getcwd
,我們可以通過運行shell的pwd -L
內置來獲得相同的值。
cc a.c b.c -g -fdebug-prefix-map=$(pwd -L)=. -o foo
將輸出.
而不是DW_AT_comp_dir
屬性中的當前目錄的路徑名。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.