Флаг 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
приписывать.