介绍addr2line调试命令

Posted by Gityuan on September 2, 2017

用addr2line可以将函数地址解析为函数名,在抓取调堆栈时Java层的堆栈本身就是显示函数名与行数,这个不需要转换,但对于native和kernel层的则是函数地址,需要借助addr2line来进行转换。 接下来分析介绍一下这个地址转换方法

一、Native地址转换

首先获取symbols表,要找到对应的版本的symbols,以及对应版本的addr2line,这样才能确保完全匹配。 然后执行如下命令,即可转换函数名:

64位:

cd prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin
./aarch64-linux-android-addr2line -f -C -e libxxx.so  <addr1> <addr2> ...

32位:

cd /prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin
./arm-linux-androideabi-addr2line -f -C -e libxxx.so  <addr1> <addr2> ...

二、Kernel地址转换

(1)首先,获取符号地址,比如获取epoll_wait的符号地址:

prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-nm  out/target/product/cancro/obj/KERNEL_OBJ/vmlinux |grep epoll_wait

该命令执行后,可获取sys_epoll_wait命令的符号地址,如下c02b2f28 T sys_epoll_wait

(2)然后,计算地址

例如 [<0000000000000000>] SyS_epoll_wait+0x2a0/0x324

则计算后的地址c02b2f28 + 2a0 = 目标地址。而对于kernel来说都是通过vmlinux来获取的,这时再执行命令可转换函数名

./aarch64-linux-android-addr2line -Cfe  /out/target/product/cancro/obj/KERNEL_OBJ/vmlinux [目标地址]

(3)实例

aarch64-linux-android-nm out/target/product/gemini/obj/KERNEL_OBJ/vmlinux | grep binder_thread_read
aarch64-linux-android-addr2line -f -C -e out/target/product/gemini/obj/KERNEL_OBJ/vmlinux ffffffc000aa8cb4

微信公众号 Gityuan | 微博 weibo.com/gityuan | 博客 留言区交流