Android 稳定性(一) Crash知识点记录

原文地址:https://juejin.cn/post/6844903972587716621#heading-56

稳定性

维度:Crash率,性能,业务可用性
重预防,稳监控
UV、PV
采集、处理(清洗、聚合、分类、趋势)、展示(数据还原、维度、版本分析)、预警

Crash优化治理

根据堆栈及现场信息分析原因
找共性:机型、OS、实验开关、资源包,考虑影响范围
线下复现、远程调试
Crash解决三步走
常规直接解、系统及Hook绕、疑难重点突破

常用代码

出现未捕获异常,导致出现异常退出,进程唯一

Thread.setDefaultUncaughtExceptionHandler()

获取主线程的堆栈信息:

Looper.getMainLooper().getThread().getStackTrace();
复制代码

获取当前线程的堆栈信息:

Thread.currentThread().getStackTrace();
复制代码

获取全部线程的堆栈信息:

Thread.getAllStackTraces();
复制代码

第三方Crash监控工具如 Fabric、腾讯Bugly,都是以字符串拼接的方式将数组StackTraceElement[]转换成字符串形式,进行保存、上报或者展示。

反混淆:Mapping映射

Java Crash

logcat日志流程,**应用层(logcat命令) --> liblog.so(hook liblog.so 中的 **__android_log_buf_write方法) --> logd(通过socket直接跟logd交互,底层使用 ring buffer 来存储数据。
Thread.getAllStackTraces()。

优点:简单,兼容性好。

缺点:1.成功率不高,依靠系统接口在极端情况也会失败。2.7.0之后这个接口是没有主线程堆栈。3.使用Java层的接口需要暂停线程。

hook libart.so。

通过hook ThreadList和Thread 的函数,获得跟ANR一样的堆栈。为了稳定性,需要在fork的子进程中执行

优点:信息很全,基本跟ANR的日志一样,有native线程状态,锁信息等等。

缺点:黑科技的兼容性问题,失败时我们可以使用Thread.getAllStackTraces()兜底。

Crash流程

1、首先发生crash所在进程,在创建之初便准备好了defaultUncaughtHandler,用来处理Uncaught Exception,并输出当前crash的基本信息;
2、调用当前进程中的AMP.handleApplicationCrash;经过binder ipc机制,传递到system_server进程;
3、接下来,进入system_server进程,调用binder服务端执行AMS.handleApplicationCrash;
4、从mProcessNames查找到目标进程的ProcessRecord对象;并将进程crash信息输出到目录/data/system/dropbox;
5、执行makeAppCrashingLocked:
  • 创建当前用户下的crash应用的error receiver,并忽略当前应用的广播;
  • 停止当前进程中所有activity中的WMS的冻结屏幕消息,并执行相关一些屏幕相关操作;
6、再执行handleAppCrashLocked方法:
  • 当1分钟内同一进程未发生连续crash两次时,则执行结束栈顶正在运行activity的流程;
  • 当1分钟内同一进程连续crash两次时,且非persistent进程,则直接结束该应用所有activity,并杀死该进程以及同一个进程组下的所有进程。然后再恢复栈顶第一个非finishing状态的activity;
  • 当1分钟内同一进程连续crash两次时,且persistent进程,则只执行恢复栈顶第一个非finishing状态的activity。
7、通过mUiHandler发送消息SHOW_ERROR_MSG,弹出crash对话框;
8、到此,system_server进程执行完成。回到crash进程开始执行杀掉当前进程的操作;
9、当crash进程被杀,通过binder死亡通知,告知system_server进程来执行appDiedLocked();
10、最后,执行清理应用相关的四大组件信息。
Binder 回收

由于Crash进程中拥有一个Binder服务端ApplicationThread,而应用进程在创建过程调用attachApplicationLocked(),从而attach到system_server进程,在system_server进程内有一个ApplicationThreadProxy,这是相对应的Binder客户端。当Binder服务端ApplicationThread所在进程(即Crash进程)挂掉后,则Binder客户端能收到相应的死亡通知,从而进入binderDied流程。

Native Crash

  • 访问非法地址
  • 地址对齐出错
  • 发生程序主动abort
成熟方案:Google BreakPad、Crashpad
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值