Пожалуйста, проверьте:
- Все ли функции в вашем двоичном коде скомпилированы с
-g
, addr2line
только функции поддержки имеют отладочную информацию, которая скомпилирована с -g
- Является ли ваше смещение действительным смещением. Это означает, что ваше смещение не должно быть адресом виртуальной памяти, а должно быть только смещением в разделе
.text
. В разделе .text
означает, что адрес должен указывать на инструкцию в двоичном виде
использование addr2line
Ниже следует сообщение от man addr2line
.
addr2line - преобразовать адреса в имена файлов и номера строк.
addresses
должен быть адресом в исполняемом файле или смещением в разделе перемещаемого объекта.
Вывод будет выглядеть примерно так: FILENAME:LINENO
, имя исходного файла и номер строки в файле
* * Пример 1 028.
Возьмите helloworld
в качестве примера.
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}
После компиляции с помощью gcc -g hello.c
мы могли бы сначала использовать objdump
, чтобы получить представление об информации о смещении в сгенерированном файле a.out
.
Ниже приводится часть сброшенной разборки:
Disassembly of section .text:
0000000000400440 <_start>:
400440: 31 ed xor %ebp,%ebp
400442: 49 89 d1 mov %rdx,%r9
400445: 5e pop %rsi
400446: 48 89 e2 mov %rsp,%rdx
400449: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
40044d: 50 push %rax
40044e: 54 push %rsp
40044f: 49 c7 c0 c0 05 40 00 mov $0x4005c0,%r8
400456: 48 c7 c1 50 05 40 00 mov $0x400550,%rcx
40045d: 48 c7 c7 36 05 40 00 mov $0x400536,%rdi
400464: e8 b7 ff ff ff callq 400420 <__libc_start_main@plt>
400469: f4 hlt
40046a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
...
0000000000400536 <main>:
#include <stdio.h>
int main()
{
400536: 55 push %rbp
400537: 48 89 e5 mov %rsp,%rbp
printf("hello\n");
40053a: bf d4 05 40 00 mov $0x4005d4,%edi
40053f: e8 cc fe ff ff callq 400410 <puts@plt>
return 0;
400544: b8 00 00 00 00 mov $0x0,%eax
}
400549: 5d pop %rbp
40054a: c3 retq
40054b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Самый левый столбец кода - это смещение в двоичном файле. __start
функция взята из стандартной библиотеки C и предварительно скомпилирована без отладочной информации. Функция main
взята из нашего кода helloworld, который содержит отладочную информацию, поскольку мы компилируем файл с -g
.
Ниже выводится addr2line
:
$ addr2line -e a.out 0x400442 #offset in the `__start` function
??:?
$ addr2line -e a.out 0x400536 #offset in the `main` function
hello.c:21
$ addr2line -e a.out 0x40054b -f #The last instruction of the `main` function
main
??:?
Из приведенного выше вывода можно сделать некоторые выводы:
- Только сегмент кода, созданный с флагом
-g
(что означает, что сегмент имеет отладочную информацию), может успешно генерировать информацию об имени файла и номере белья.
- Не все смещения тела функции, скомпилированные с флагом
-g
, успешно выведут имя файла и номер белья. Смещение 0x40054b
является последней инструкцией после ret
инструкции функции main
, но мы не смогли получить информацию.