项目中遇到了tombstones。
1.什么是tombstone
当一个动态库(native 程序)开始执行时,系统会注册一些连接到 debuggerd 的 signal handlers,当系统 crash 的时候,会保存一个 tombstone 文件到/data/tombstones目录下(Logcat中也会有相应的信息),文件的确就像墓碑一样记录了死亡了的进程的基本信息(例如进程的进程号,线程号),死亡的地址(在哪个地址上发生了 Crash),死亡时的现场是什么样的(记录了一系列的堆栈调用信息)等等。
从文件中可以看出,报的是SIGABRT错误:abort()的工作原理是会发出SIGABRT信号。通常由于库函数检测到内部错误或者某些限制。
2.addr2line分析工具
通过tombstones日志文件大概知道是JNI层的报错,但是jni的报错信息,不像Java层报错信息那样可以直接在日志中看到错误的行数,JNI层中出现的错误直接看根本定位不到错误的位置。通常来说,JNI报的基本都是堆栈信息,需要NDK的一些工具进行地址转换,转换后即可看到错误的位置。这边用addr2line工具。
(1)addr2line工具是NDK自带的,所以先下载NDK,addr2line工具的路径目录如下:你的NDK路径\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin
(2)配置addr2line的环境变量:在系统环境变量中的Path添加addr2line工具的路径
这是我的环境变量配置(如果没有配置的话,记得要加上自己的完整路径,否则会出现报错:“‘arm-linux-androideabi-addrline2’ 不是内部或外部命令,也不是可运行的程序或批处理文件。”)
(3)这个时候就可以使用arm-linux-androideabi-addr2line工具进行定位
命令格式:
arm-linux-androideabi-addr2line -e 需要调试的so库路径 内存地址
比如我这边的,查找001c46b1这个内存:
我这边只看到了JNI_OnLoad,没有看到具体的行数。第三方的so库一般都是不提供源码,又或者已加密了,所以此时得出的是行号为??:?或??:0
如果遇到addr2line得到??:?或??:0的情况,原因就是编译得到的so文件没有附加上符号表(symbolic)信息。
出错的libwebviewchromium.so是chromium C++代码库,原因暂时未知,有相似的问题https://stackoverflow.com/questions/26164744/native-code-crash-on-libwebviewchromium-so。