一、介绍
描述
Linux下addr2line命令用于将程序指令地址转换为所对应的函数名、以及函数所在的源文件名和行号。当含有调试信息(-g)的执行程序出现crash时(core dumped),可使用addr2line命令快速定位出错的位置。
如果无法确定文件名或函数名,addr2line将在它们的位置打印两个问号;如果无法确定行号,addr2line将打印0或一个问号。
查看使用和帮助手册
man addr2line
addr2line -h
参数说明
-a --addresses:在函数名、文件和行号信息之前,显示地址,以十六进制形式。
-b --target=<bfdname>:指定目标文件的格式为bfdname。
-e --exe=<executable>:指定需要转换地址的可执行文件名。
-i --inlines : 如果需要转换的地址是一个内联函数,则输出的信息包括其最近范围内的一个非内联函数的信息。
-j --section=<name>:给出的地址代表指定section的偏移,而非绝对地址。
-p --pretty-print:使得该函数的输出信息更加人性化:每一个地址的信息占一行。
-s --basenames:仅仅显示每个文件名的基址(即不显示文件的具体路径,只显示文件名)。
-f --functions:在显示文件名、行号输出信息的同时显示函数名信息。
-C --demangle[=style]:将低级别的符号名解码为用户级别的名字。
-h --help:输出帮助信息。
-v --version:输出版本号。
注意:使用时一般需通过 -e 指定可执行程序名称,若不指定则默认a.out
dmesg命令
:全称为display message,用来显示Linux内核环形缓冲区信息。
二、使用示例
有如下test.cpp文件:
#include<stdio.h>
int divide(int x, int y)
{
return x/y;
}
int main()
{
printf("hello world\n");
int x = 3;
int y = 0;
int div = divide(x, y);
printf("%d / %d = %d\n", x, y, div);
return 0;
}
编译:g++ -Wl,-Map=test.map -g test.cpp -o test
注意:-Wl,-Map=test.map 这里Wl后面的东西是作为参数传递给链接器ld,这里的含义是生成名叫test.map的.map文件。
.map文件:map 文件对应的中文名应该是映射文件,用来展示(映射)项目构建的链接阶段的细节。
从map文件我们可以了解到:
- 程序各区段的寻址是否正确
- 程序各区段的size,即目前存储器的使用量
- 程序中各个symbol的地址
- 各个symbol在存储器中的顺序关系(这在调试时很有用)
- 各个程序文件的存储用量
查找divide函数的地址
grep divide test.map
使用addr2line定位
#显示文件和行数
addr2line -e test 0x0000000000001169
#显示文件、行数和内容
addr2line -e test 0x0000000000001169 -f -C
三、参考资料
其他参考