Addr2line 工具(它是标准的 GNU Binutils 中的一部分)是一个可以将指令的地址和可执行映像转换成文件名、函数名和源代码行数的工具。这种功能对于追踪死机地址转换成源码位置很有意义。
在调用 Addr2line 工具时,要使用
-e
选项来指定可执行映像是 test,
通过使用 -f
选项,可以告诉工具输出函数名。
例如:addr2line -e test 0x1234654(死机地址) -f
这个工具在我们日常开发中非常有用。他可以快速的定位到程序死机的位置。注意,这里说的死机是指程序因为非法地址访问,除数为0,地址未对其访问(部分平台有此限制),bus error等错误造成的程序崩溃。不包含死锁、程序死循环等造成的死机现象。
在说明该工具的用法之前,先了解两个概念:
1. epc:在学校我们学习汇编的时候知道pc是CPU保存当前运行指令地址的寄存器,那么这个
epc就是error pc。保存的是当程序崩溃时,造成指令异常的那条指令的地址。也就是问题的第一现场。比如,程序因为非法地址访问造成了死机,那么epc保存的就是直接造成非法地址访问的那条指令的地址。
2. ra:当前程序返回地址。当程序进行函数调用时更新该寄存器。当程序死机时,该地址就是第二现场。
一般程序崩溃时都有epc、ra的地址打印出来。
addr2line实例
命令:addr2line -e integration/product/a.out 802f07a8 –f
其中integration/product/a.out为造成死机对应的程序。 802f07a8 为地址。比如上面一张所说的epc地址或者是ra地址。
待查地址的确定?
有时出现的是fault add 地址,有时出现的是epc地址(
exception地址)或者pc地址(通常是指向函数的地址),针对fault add地址,此处假设该为
0x00250465,而有没有堆栈,则可以先通过查看进程的内存映射信息,定位到地址所在的映像文件(动态库or可执行文件)所在的位置。
cat /proc/PID/maps 查看内存信息,例如:
[root@rhel5 ~]# cat /proc/2674/maps 00110000-00239000 r-xp 00000000 08:02 130647 /lib/libcrypto.so.0.9.8e 00239000-0024c000 rwxp 00129000 08:02 130647 /lib/libcrypto.so.0.9.8e 0024c000-00250000 rwxp 0024c000 00:00 0 00250000-00252000 r-xp 00000000 08:02 130462 /lib/mylib-2.5.so 00252000-00253000 r-xp 00001000 08:02 130462 /lib/mylib.so |
找到对应的地址区间和映像(库)之后,然后利用fault addr地址和该库地址区间计算出,该死机地址在该库中的偏移地址。接着使用addr2line 来定位该地址的所在的代码位置。
使用此命令时有几个条件:
(1)test 可执行文件在gcc编译时必须包含-g选项;
(2)(死机)地址的确定;
相关示例: