Флаг gcc -g: перемещение исходного кода

Насколько я понимаю, когда вы компилируете код на C, используя gcc -g, gcc вставит отладочную информацию, которая включает ссылки на исходный исходный код (например, номера строк). Затем другие программы, такие как gdb и objdump, могут восстановить эти ссылки позже. Для примера мы будем использовать objdump -S который печатает сборку с чередованием с соответствующим исходным кодом.

Моя цель - скопировать скомпилированные двоичные файлы на другой компьютер и по-прежнему иметь возможность получать эту отладочную информацию. Однако в настоящее время, когда я делаю это, вся информация отладки теряется. Я также не против копировать исходные файлы, но второй компьютер работает под управлением другой ОС, поэтому структура файлов отличается, и я не могу поместить исходные файлы точно в одно и то же абсолютное место, что не позволяет objdump найти исходный код. Я посмотрел на двоичный файл и увидел раздел, который выглядит следующим образом:

/home/path/to/source/code

Я попытался отредактировать это, чтобы соответствовать новому пути к источнику, но это просто сделало двоичный файл недействительным.

Я также исследовал флаги gcc, надеясь, что один из них позволит указать относительный путь к исходному коду вместо абсолютного, но я не смог найти ничего подобного.

Для справки, вот тот вид вывода, который я надеюсь получить от 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.

1 ответ

Решение

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мы можем получить то же значение, запустив pwd -L встроенный.

cc a.c b.c -g -fdebug-prefix-map=$(pwd -L)=. -o foo

будет выводить .вместо пути к текущему каталогу, в DW_AT_comp_dir приписывать.

Другие вопросы по тегам