addr2line,如何根据地址找到出错函数

当手机发生异常,你会发现下面的一些log信息经常见到却不好从字面理解,举个栗子:

[60] [60] Attempt to program a write protected block
[70] [70] Failed Reading block @ 10
[70] [70] Reading MMC failed
[980] [980] BSN Not written.
[17680] [17680] dload mode key sequence detected
[17680] [17680] SCM call: 0x2000601 failed with :fffffffc
[17710] [17710] SCM call: 0x2000601 failed with :fffffffc
[17710] [17710] data abort, halting
[17710] [17710] r0  0xfffffffc r1  0x00000010 r2  0x536f67e8 r3  0x00000000
[17710] [17710] r4  0x000000ff r5  0x8f6bf2e0 r6  0x01f86600 r7  0x00000000
[17710] [17710] r8  0x01f06800 r9  0x00000000 r10 0x00000013 r11 0x8f6bf50c
[17710] [17710] r12 0x8f6bf2e8 usp 0x00000000 ulr 0x00000000 pc  0x8f619d10

[17710] [17710] spsr 0xa0000113

以上这段函数,最后会打印出来一些汇编的地址信息,尤其注意的是最后的pc的地址

在android源生的gcc脚本中,就存在着脚本可以专门讲此地址转换为最后指针的代码:addr2line

存放路径:

ARM 32位版本:prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-addr2line
ARM 64位版本:prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-addr2line


使用的方法:

arm-linux-androideabi-addr2line -Cfe $symbol_file 0xyyyyyyyy

其中,&symbol是对应库作为的文件,而0xyyyy则是需要转换的地址

关于&symbol,如果log的地址是lk的,那lk对应的符号文件是:
out/target/product/$proj/obj/bootloader_obj/build-$proj/lk
如果是kernel的,对应的符号文件是:
out/target/product/$proj/obj/kernel_obj/vmlinux(老版本的位置在kernel/out/vmlinux)
如果是preloader的,对应的符号文件是:
out/target/product/$proj/obj/preloader_obj/bin/preloader_$proj.elf

再举个栗子:

./arm-linux-androideabi-addr2line -Cfe lk  0x8f625ed0
@Untitled Folder./arm-linux-androideabi-addr2line -Cfe lk 0x8f625ed0
vsnprintf
/data_2/project/MSM8905_KAIOS_GFLIP2_TF_DINT/bootable/bootloader/lk/lib/libc/printf.c:172


该方法需要注意两点:

这个符号文件必须是和烧录的image版本一起生成的,如果不匹配或者被重新编译过生成的,那么log里的地址和符号文件可能对应的不上,工具可能输出错误的结果。
如果不确定符号文件是32位还是64位,建议直接使用64位版本。

你可能感兴趣的:(System)