See You Again

JNI层崩溃问题代码定位

一般安卓程序遇到 JNI 层面的崩溃时会上报一个崩溃栈上来,打印出崩溃地址等,例如:

  1. I/DEBUG ( 31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
  2. I/DEBUG ( 31): Build fingerprint: 'generic/google_sdk/generic/:2.2/FRF91/43546:eng/test-keys'
  3. I/DEBUG ( 31): pid: 351, tid: 351 %gt;%gt;%gt; /data/local/ndk-tests/crasher <<<
  4. I/DEBUG ( 31): signal 11 (SIGSEGV), fault addr 0d9f00d8
  5. I/DEBUG ( 31): r0 0000af88 r1 0000a008 r2 baadf00d r3 0d9f00d8
  6. I/DEBUG ( 31): r4 00000004 r5 0000a008 r6 0000af88 r7 00013c44
  7. I/DEBUG ( 31): r8 00000000 r9 00000000 10 00000000 fp 00000000
  8. I/DEBUG ( 31): ip 0000959c sp be956cc8 lr 00008403 pc 0000841e cpsr 60000030
  9. I/DEBUG ( 31): #00 pc 0000841e /data/local/ndk-tests/crasher
  10. I/DEBUG ( 31): #01 pc 000083fe /data/local/ndk-tests/crasher
  11. I/DEBUG ( 31): #02 pc 000083f6 /data/local/ndk-tests/crasher
  12. I/DEBUG ( 31): #03 pc 000191ac /system/lib/libc.so
  13. I/DEBUG ( 31): #04 pc 000083ea /data/local/ndk-tests/crasher
  14. I/DEBUG ( 31): #05 pc 00008458 /data/local/ndk-tests/crasher
  15. I/DEBUG ( 31): #06 pc 0000d362 /system/lib/libc.so
  16. I/DEBUG ( 31):

为了便于排查,我们希望进一步定位到崩溃的函数、行号及代码。对于 JNI 需要借助一些工具才行(Java层面的崩溃一眼就能看出来了),有两个工具:

ndk-stack

这个程序在安卓SDK的这个目录下: sdk/ndk-bundle ,用法:

  1. ndk-stack -sym obj/local/armeabi -dump crash.txt

-sym 为你程序共享库的目录, -dump 是 JNI 的原崩溃栈

addr2line

这个程序在安卓SDK的这个目录下: sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin,用法:

  1. arm-linux-androideabi-addr2line -C -f -e obj/local/armeabi/libnativemaprender.so 0000841e

-f 显示函数名,-C 还原函数名

最后注意一点,辅助分析的库文件必须是带符号的(一般编译的时候会输出这类文件),否则是不能解析出崩溃代码的。

  1. $ file obj/local/armeabi/libimcore.so
  2. obj/local/armeabi/libimcore.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, not stripped
2016-06-16 喜欢

Copyright © 2015-2018 转载请注明出处

回到顶部 ↑