1、介绍
addr2line是一个可以将指令的地址和可执行映像转换为文件名、函数名和源代码行数的工具。
可以通过帮助看下其使用情况:
$ addr2line -h
Usage: addr2line [option(s)] [addr(s)]
Convert addresses into line number/file name pairs.
If no addresses are specified on the command line, they will be read from stdin
The options are:
@<file> Read options from <file>
-a --addresses Show addresses
-b --target=<bfdname> Set the binary file format
-e --exe=<executable> Set the input file name (default is a.out)
-i --inlines Unwind inlined functions
-j --section=<name> Read section-relative offsets instead of addresses
-p --pretty-print Make the output easier to read for humans
-s --basenames Strip directory names
-f --functions Show function names
-C --demangle[=style] Demangle function names
-h --help Display this information
-v --version Display the program's version
2、例子
先写一个main.c文件:
#include <stdio.h>
int bbb;
int ccc = 20;
char *ddd = "abcdefg";
int myfunc(int a, int b)
{
return a+b;
}
int main()
{
int aaa = 10;
printf("tttttt : %d\n", aaa);
int eee = 20;
int fff = 30;
int ggg = myfunc(eee, fff);
printf("gggggg : %d \n", ggg);
return 0;
}
然后将其编译成可执行文件,同时将map表保存:
gcc -Wl,-Map=mymap.txt -g main.c -o main
-g代表要加入调试信息
-Wl,-Map=mymap.txt代表要将Map信息存到文件mymap.txt里。
上面有两个函数,我们查一下其地址:
$ cat mymap.txt | grep myfunc
0x0000000000400526 myfunc
$ cat mymap.txt | grep main
0x0000000000400410 __libc_start_main@@GLIBC_2.2.5
0x000000000040053a main
OUTPUT(main elf64-x86-64)
可见myfunc地址是0x0000000000400526, main的地址是0x000000000040053a。
我们可以通过addr2line查看这俩地址是不是就是那两个函数:
$ addr2line 0x0000000000400526 -e main -f -C -s
myfunc
main.c:8
$ addr2line 0x000000000040053a -e main -f -C -s
main
main.c:13
结合刚才的main.c看,确实是正确的。当出现了墓碑文件或者crash的时候,我们就可以通过地址来定位具体对应哪一个代码了。