美文网首页
Crash信息监控思考

Crash信息监控思考

作者: ModestStorm | 来源:发表于2022-11-25 14:27 被阅读0次

1.Crash信息监控
Crash修复的难点在于信息收集,针对Crash上报信息进行修复,Crash分为java层Crash和Native层Crash

  1. Java 层Crash捕获:自定义异常捕获器继承自UncaughtExceptionHandler接口,实现unCaughtException(Thread thread,Throwable)方法,根据Throwable收集调用栈信息(出现Crash的类名,方法名,行号等信息)上传服务器。
  2. native层Crash通过注册信息处理函数监听指定的信号,当native层出现crash时将异常信息返回给应用上层。同时提示用户重启应用,提升用户体验。

抛给 Java层 处理的好处是 Java 层可以继续在当前上下文上加上 Java 层的各种状态信息,写入到同一个文件中进行上传,
使得开发在解决 bug 的时候能更方便。

  之所以通过注册信号处理函数的方式是因为在发生crash的时候,系统会向目标进程发送信号,应用程序的虚拟机会捕获该信号输出异常信息并kill掉目标进程。

Native层异常捕获是通过注册信号函数实现,native异常信息包含函数名称,SO动态库名称,函数地址+偏移量(定位函数中某一行出现异常信息)根据ABI找到相对应的addr2line工具和带符号表的so文件,进行解析修复,

获取Native Crash 发生时的函数调用栈:
直接使用系统的<unwind.h>库,可以获取到出错文件与函数名。只不过需要自己解析函数符号,同时经常会捕获到系统错误,需要手动过滤。

下面也可以使用,但是太难了。
使用 Google 的breakpad,这是所有 C/C++堆栈获取的权威方案,基本上业界都是基于这个库来做的。只不过这个库是全平台的 android、iOS、Windows、Linux、MacOS 全都有,所以非常大,在使用的时候得把无关的平台剥离掉减小体积。

Crash修复:JpAssit插件异常捕获,方法替换,比如startActivity在某些手机上出现异常,还有第三方的SDK内部出现异常要进行方法替换或者异常捕获,最难解决的是第三方SDK中的异常和jni层的异常。

AOP方案:但是面对庞大的旧代码仓库和诸多的业务部门,修改现有代码需要极大成本,还有更多的外部依赖SDK基本不可能使用我们自己的工具类,此时就需要AOP大展身手了。

相信在各个大厂都有一套“安全气囊”装置,比如crash一定次数就启用轻量版本或者自动重新启动等等。

native crash不同于java/kotlin层的crash,在java环境中,如果程序出现了不可预期的crash(即没有捕获),就会往上抛出给最终的线程uncaghtexceptionhandler,在这里我们可以再次处理,比如屏蔽某个exception即可保持app的稳定,然后native层的crash不一样,native 层的crash大多数是“不可恢复”的,比如某个内存地址方面的错误,这些往往是不可处理的,需要中断当前进程,所以如果发生了native crash,我们转移到自定义的安全处理,比如自动重启后提示用户等等,就会提高用户很大的体验感(比起闪退)。

对于Crash的治理,我们尽量遵守以下三点原则:控制增量,降低存量
1.由点到面:一个Crash发生了,我们不能只针对这个Crash的去解决,而要去考虑这一类Crash怎么去解决和预防。只有这样才能使得这一类Crash真正被解决。

2.异常不能随便吃掉:随意的使用try-catch,只会增加业务的分支和隐蔽真正的问题,要了解Crash的本质原因,根据本质原因去解决。catch的分支,要根据业务场景去兜底,保证后续的流程正常。

3.预防胜于治理。当Crash发生的时候,损失已经造成了,我们再怎么治理也只是减少损失。尽可能的提前预防Crash的发生,可以将Crash消灭在萌芽阶段。

系统级Crash治理

众所周知,Android的机型众多,碎片化严重,各个硬件厂商可能会定制自己的ROM,更改系统方法,导致特定机型的崩溃。发现这类Crash,主要靠云测平台配合自动化测试,以及线上监控,这种情况下的Crash堆栈信息很难直接定位问题。下面是常见的解决思路:

尝试找到造成Crash的可疑代码,看是否有特异的API或者调用方式不当导致的,尝试修改代码逻辑来进行规避。通过Hook来解决,Hook分为Java Hook和Native Hook。Java Hook主要靠反射或者动态代理来更改相应API的行为,需要尝试找到可以Hook的点,一般Hook的点多为静态变量,同时需要注意Android不同版本的API,类名、方法名和成员变量名都可能不一样,所以要做好兼容工作。

Native Hook原理上是用更改后方法把旧方法在内存地址上进行替换,需要考虑到Dalvik和ART的差异;相对来说Native Hook的兼容性更差一点,所以用Native Hook的时候需要配合降级策略。

特定机型的Crash针对特定机型适配修改,比如hook方式修改特定的api,产生难以修改的crash捕获异常后采用应用降级,比如超过crash一定的次数之后将native页面转换为H5页面来保障业务流程正常运转。

OOM

OOM是OutOfMemoryError的简称,在常见的Crash疑难排行榜上,OOM绝对可以名列前茅并且经久不衰。
因为它发生时的Crash堆栈信息往往不是导致问题的根本原因,而是压死骆驼的最后一根稻草。

可以配合应用页面状态信息进行分析。

导致OOM的原因大部分如下:
1.内存泄漏,大量无用对象没有被及时回收导致后续申请内存失败。LeakCanary和StrictMode来检查Activity的泄露
2.大内存对象过多,最常见的大对象就是Bitmap,几个大图同时加载很容易触发OOM。

对于图片内存优化的建议
1.尽量使用成熟的图片库,比如 Glide,图片库会提供很多通用方面的保障,减少不必要的人为失误。

2.根据实际需要,也就是View尺寸来加载图片,可以在分辨率较低的机型上尽可能少地占用内存。除了常用的BitmapFactory.Options#inSampleSize和Glide提供的BitmapRequestBuilder#override之外,我们的图片CDN服务器也支持图片的实时缩放,可以在服务端进行图片缩放处理,从而减轻客户端的内存压力。

Crash的监控&止损的实践

监控
1.首先是灰度监控,灰度阶段是增量Crash最容易暴露的阶段,如果这个阶段没有很好的把握住,会使得增量变存量,从而导致Crash率上升.

制定一些灰度策略去提高这个阶段Crash的暴露:分渠道灰度、分城市灰度、分业务场景灰度等多个灰度维度

止损
尽管我们在前面做了那么多,但是Crash还是无法避免的,
例如,在灰度阶段因为量级不够,有些Crash没有被暴露出来;
又或者某些功能客户端比后台更早上线,而这些功能在灰度阶段没有被覆盖到;
这些情况下,如果出现问题就需要考虑如何止损了。

crash问题发生时首先需要评估重要性,如果问题不是很严重而且修复成本较高可以考虑在下个版本再修复,

如果问题比较严重,对用户体验或下单有影响时就必须要修复.

1.修复时首先考虑业务降级,主要看这部分异常的业务是否有兜底或者A/B策略,这样是最稳妥也是最有效的方式。

2.如果业务不能降级就需要考虑热修复了,目前美团外卖Android App接入的热修复框架是自研的 Robust,可以修复90%以上的场景,热修成功率也达到了99%以上

3.如果问题发生在热修复无法覆盖的场景,就只能强制用户升级。强制升级因为覆盖周期长,同时影响用户的体验,只在万不得已的情况下才会使用。

线上某些怪异的Crash发生后,我们除了分析Crash堆栈信息之外,还可以使用离线日志回捞、下发动态日志等工具来还原Crash发生时的场景,帮助开发同学定位问题,但是这两种方式都有它们各自的问题。离线日志顾名思义,它的内容都是预先记录好的,有时候可能会漏掉一些关键信息,因为在代码中加日志一般只是在业务关键点,在大量的普通方法中不可能都加上日志。动态日志( Holmes)存在的问题是每次下发只能针对已知UUID的一个用户的一台设备,对于大量线上Crash的情况这种操作并不合适,因为我们并不能知道哪个发生Crash的用户还会再次复现这次操作,下发配置充满了不确定性。

相关文章

  • Crash信息监控思考

    1.Crash信息监控Crash修复的难点在于信息收集,针对Crash上报信息进行修复,Crash分为java层C...

  • iOS Crash

    不需要通过dSYM来符号化crash。 注册监控: 监控处理: 通过这种方式就可以拿到crash信息了,再把cra...

  • iOS监控-启动crash

    iOS监控-启动crash

  • 性能优化之稳定性优化

    提高代码质量 代码审查 android lint 代码检测 Crash监控 java层Crash监控 虚拟机为每个...

  • Crash 监控

    Crash(应用崩溃)是由于代码异常而导致 App 非正常退出,导致应用程序无法继续使用,所有工作都停止的现象。发...

  • safemode小记

    Crash监控?Thread.setDefaultHandler() onCaughtException()方法拦...

  • 实锤证明Fabric OOM-free-session的误报

    Fabric 是业界著名的 crash 监控平台,国内外均有不少 app 使用 Fabric 进行 crash 和...

  • Crash 日志 简单分析 缩小查找范围

    看懂 Crash 日志 Crash 头部信息 Incident Identifier:每个 Crash 生成的唯一...

  • 学习笔记集合01

    一、性能优化 1.0、APM性能监控 CPU占用率、内存/磁盘使用率、卡顿监控定位、Crash防护、线程数量监控、...

  • Android 稳定性优化

    1. 如何提升App的稳定性 Crash维度 性能维度 业务高可用维度 重在预防、监控必不可少。 思考更深一层、重...

网友评论

      本文标题:Crash信息监控思考

      本文链接:https://www.haomeiwen.com/subject/ifvazrtx.html