linux 定位 踩内存_应用稳定性优化系列(二),Crash/Tombstone问题分析及定位

本文介绍了Linux系统中Crash/Tombstone问题的原因和定位方法,包括信号量分析、反编译调用栈和地址分析。通过对进程内存分布的深入理解,找出函数调用错误,例如栈溢出、数组越界和函数指针错误。下篇将讨论资源泄露类故障。
摘要由CSDN通过智能技术生成
继上周介绍了稳定性三大故障之一的 ANR类故障 后,本章继续介绍第二大类故障Crash/Tombstone及其分析定位方法。

1. Crash/Tombstone问题原因分析

47c2b74b7e15017487eade4927eb485f.png

2. Tombstone问题定位方法

本节主要讲解Tombstone问题的分析定位方法。

2.1 信号量分析法

信号机制是进程之间相互传递消息的一种方法,下表展示的是一些常见的信号种类。

260f81730fe2ce859b245f9280785d2b.png
  • SIGBUS与SIGSEGV的区别

SIGBUS(Bus error)意味着指针所对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问所致。比如int型要4字节对齐,short型的2字节对齐。例如:short array[16];int * p = (int *)&array[1];*p = 1;SIGSEGV(Segment fault)意味着指针所对应的地址是无效地址,没有物理内存对应该地址。例如:int *pi= (int*)0x00001111;*pi = 17。

2.2 反编译调用栈法

417899cfb25761cd4574cdcb00c7a2bb.png 反编译调用栈步骤
  • 新建一个tombstone.txt,把backtrace里面的内容写入到txt里面去;
  • 执行脚本 ./panic.py tombstone.txt>log.txt;
  • 更细致的调用栈可以参考stack里面的纪录;
  • 打开log.txt之后,分析函数的调用栈,从调用栈找出逻辑关系。
虚拟机调用流程 反编译了调用栈之后,一般中间都有很多的虚拟机调用,这部分的顺序一般都是相同的,了解这些虚拟机函数,也有助于我们分析问题。下图是主要的虚拟机函数: 33b0ff87f732278e1149b7dda712f482.png 案例分析 进入某应用就崩溃,调用栈如下:

62990ae829639c1ae02a8e8c407e932a.png

c6ffe4a66fd55f79cb47bc5e6cef0bd1.png

分析上方调用栈发现,因为调用dvmInterpret方法,表明启动Dalvik虚拟机解释器,并且解释执行指定的JAVA代码。

a2b110a9839933bcf638d343e5c90b2b.png

通过分析上方调用栈可以看到,因为调用dvmCallJNIMethod方法,表明是在native侧触发错误。

接着往下看,真正的原因在下方调用栈:

ac595fb59ff16bc85e1afa59e298c0e9.png 一个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,如下:

d886832a0af5fbdab7165ab2c0d5d7c6.png

可以看到各个对应的偏移地址的函数。

  • 操作步骤

  1. 取出stack里面的地址
  2. 通过前面输出的该进程的内存分布图,分析该地址属于哪一个.so
  3. 把该栈地址减去对应.so的基地址,就是偏移地址
  4. 把该偏移地址,放到objdump反编译的文件里面找,就能找到对应的方法

继介绍稳定性ANR类故障和Crash/Tombstone类故障后,下篇我们将围绕资源泄露类故障进行分析,欢迎持续关注。

ee9b66b8b8b5c8f546275d9cb780cc21.png

【往 期 精 选 文 章 回 顾

57917656b157205ace362f2a53d8269c.png

应用稳定性优化系列(一),ANR问题全面解析

46f95b59dfaa85075d7d7d6749c98c5e.png

高标准严要求,彰显绿盟力量!标准评测工作组例会顺利召开

1eede87feab8fdd558c8c9c8f7cee73f.png

【直播预告】 “折叠屏高效适配的进阶之路”线上沙龙已开启招募

f50fff8d66004eb6e048fcf9b4e17fae.gif

6613ac396568d0f246ae0561b186374d.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值