簡體   English   中英

gcc -g flag:移動源代碼

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM