1. Crash/Tombstone问题原因分析
2. Tombstone问题定位方法
本节主要讲解Tombstone问题的分析定位方法。
2.1 信号量分析法
信号机制是进程之间相互传递消息的一种方法,下表展示的是一些常见的信号种类。
SIGBUS与SIGSEGV的区别
2.2 反编译调用栈法
反编译调用栈步骤- 新建一个tombstone.txt,把backtrace里面的内容写入到txt里面去;
- 执行脚本 ./panic.py tombstone.txt>log.txt;
- 更细致的调用栈可以参考stack里面的纪录;
- 打开log.txt之后,分析函数的调用栈,从调用栈找出逻辑关系。
接着往下看,真正的原因在下方调用栈:
一个JAVA方法通过JNI调用底层方法时,传入一个非法的String,JNI在把这个String转换成char数组时导致失败。2.3 地址分析法
Linux程序在运行时,会将所有用到的模块加载到内存,所有的段分布到统一的虚拟内存空间中,程序调用过程中的地址都是内存空间的虚拟地址,我们只知道该位置位于哪个模块,却不知道具体哪个函数出了问题。而地址的确对应了一个函数,因此只有知道了模块在内存中的分布情况,才能找到对应偏移位置的函数。
取得进程pid的内存分布
问题发生时,都会打印出当前的进程号。假如进程号为2429,命令如下(需要root) : adbshell cat /proc/2429/maps>2429.txt,然后我们把fault addr, stack地址放到2429.txt里面查找。一般fault addr在栈区,是栈溢出;在堆区,一般是数组越界或者内存被踩;在代码区,一般是函数指针跑飞了。
maps地址解析
其中,[stack]表示代表栈区;(deleted)表示堆区,内存可回收;一些.so,.jar,.dex,.apk表示代码区。
深入分析栈地址
backtrace和stack:里面都是栈的调用信息。backtrace里面地址我们可以用脚本panic.py去反编译。那stack:里面的地址如何分析呢?stack里面的地址是等于基地址+偏移地址,可以借用工具arm-linux-androideabi-objdump。Objdump一下libandroid_runtime.so,如下:
可以看到各个对应的偏移地址的函数。
操作步骤
- 取出stack里面的地址
- 通过前面输出的该进程的内存分布图,分析该地址属于哪一个.so
- 把该栈地址减去对应.so的基地址,就是偏移地址
把该偏移地址,放到objdump反编译的文件里面找,就能找到对应的方法
继介绍稳定性ANR类故障和Crash/Tombstone类故障后,下篇我们将围绕资源泄露类故障进行分析,欢迎持续关注。
【往 期 精 选 文 章 回 顾】
应用稳定性优化系列(一),ANR问题全面解析
高标准严要求,彰显绿盟力量!标准评测工作组例会顺利召开
【直播预告】 “折叠屏高效适配的进阶之路”线上沙龙已开启招募