1xCrash原理

xCrash 架构与实现

整体架构

xCrash 整体分为两部分:运行于崩溃的 APP 进程内的部分,和独立进程的部分(我们称为 dumper)。

image

1、APP 进程内

这部分可以再分为 Java 和 native 两个部分。

(1)Java 部分:

①Java 崩溃捕获。直接使用 JVM 提供的机制来完成,最后生成兼容 tombstone 格式的 dump 文件。

②Native 崩溃捕获机制的注册器。通过 JNI 激活 native 层的对应机制。

③Tombstone 文件解析器。可以将 tombstone 文件解析成 json 格式。

④Tombstone 文件管理器。可以检索设备上已经生成的 tombstone 文件。

(2)Native 部分:

①JNI Bridge。负责与 Java 层的交互。(传参与回调)

②Signal handlers。负责信号捕获,以及启动独立进程 dumper。

③Fallback mode。负责当 dumper 捕获崩溃信息失败时,尝试在崩溃进行的 signal handler 中收集崩溃信息。

2、Dumper 独立进程

这部分是纯 native 的实现:

①Process。负责崩溃进程中各个线程的控制(attach 和 detach),以及进程层面的信息收集,比如 FD 列表、logcat 等等。

②Threads。负责崩溃进程中的线程相关数据的收集,比如 registers、backtrace、stack 等等。

③Memory Layout。负责 maps 和 smaps 的解析。

④Memory。负责各种内存数据的读写。比如来自本地 buffer、来自mmap() 的 ELF 文件、或者通过 ptrace() 远程访问的崩溃进程的内存。

⑤Registers。负责各种处理机架构相关的数据处理。

⑥ELF。负责 ELF 信息的解析。需要解析各种 unwind table 和 symbols 信息,有时需要使用 LZMA 解压 .gnu_debugdata 中的 mini debug info 信息做进一步的处理。

xCrash 的其他功能

除了获取常见的设备信息、registers、backtrace、stack、memory near、maps、logcat 等基本信息,xCrash 还提供以下的功能:

1、完整的 FD 列表

让你知道崩溃时进程中的每一个 FD 具体都用在了哪里。

2、详细的内存使用统计

获取了操作系统全局的物理内存使用统计、崩溃进程的虚拟内存使用统计、崩溃进程的内存详细使用信息(类似 dumpsys meminfo)。让你对进程崩溃时的内存状态有全面的了解。

3、用正则白名单设置需要获取哪些线程的信息

APP 的线程数超过 100 个是很常见的,如果像系统 tombstone 那样总是获取全部线程的 registers、backtrace 等信息,在大多数情况下是没有必要的;这也容易导致 unwind 时间过长,崩溃捕获逻辑还没有走完,APP 就被系统强杀了。xCrash 让你能通过一组正则表达式白名单来设置需要获取哪些线程的信息。

4、零权限需求

xCrash 不需要 root 权限,也不需要任何的 APP 系统权限,这让使用 xCrash 的 APP 没有任何权限方面的负担。

5、监测设备是否已被 root

监测的过程是完全透明和无感知的。在后期分析数据时,如果发现某个崩溃只发生在已被 root 的设备上,就有理由怀疑是否是一些特别的原因造成的。

6、极高的崩溃信息捕获成功率

xCrash 通过 FD 预留;Flash “占坑”文件;写文件失败时通过预分配内存保存 backtrace 等重要信息做紧急回调、clone() + execl() 失败后进入 fallback 模式执行本地 unwind 等一系列保护措施,最大程度的保证了崩溃信息捕获的成功率。

7、扩展性支持

xCrash 支持崩溃后附加用户自定义信息。目前在爱奇艺 APP 中,已经通过 xCrash 的扩展能力,在崩溃时投递了大播放日志、弹幕日志、NLE视频编辑日志、APP Life Cycle Trace等信息。为排查特定业务的崩溃问题提供支持。

参考

干货|安卓app崩溃捕获方案——xcrash

https://github.com/iqiyi/xCrash