Xcrash V2.5.7框架解析

如题所述

第1个回答  2022-07-04

xcrash 是爱奇艺在2019年4月开源在GitHub上的稳定性日志收集框架,它能为android收集java crash、native crash、anr日志。不需要root权限和系统权限。支持 Android 4.0 - 10(API level 14 - 29),支持 armeabi,armeabi-v7a,arm64-v8a,x86 和 x86_64。

xcrash作为门面模式的入口,client调用通过配置InitParameter来进行初始化。Xcrash分别关联三种类型Handler来处理对应的奔溃监听和日志收集,通过FileManager和TombstoneManager对奔溃日志进行tombstone文件管理。client调用TombstoneParser来解析本地生成的对应tombstone文件,获取数据。

Java层的崩溃可以直接交给JVM的崩溃捕获机制去处理。这个非常简单,不赘述。

如果有java crash发生,会回调uncaughtException,执行handleException收集相关log信息

Crash.java

NativeHandler.java

NativeHandler在Xcrash init时会执行initialize方法进行初始化,初始化过程首先通过System.loadLibrary("xcrash”)注册native函数,其次就是调用nativeInit。

执行System.loadLibrary("xcrash”),JNI_OnLoad会被回调,这里是动态注册玩法。

xc_jni.c

数组0元素对应:

java层调用nativeInit,native xc_jni_init会被调用。
接着看nativeInit逻辑
xc_jni.c

先看xc_crash_init

1)设置callback:

xc_crash_init_callback最终回调的是NativeHandler的crashCallback

2)信号注册:

注册的是指针函数:xc_crash_signal_handler,追过去看看:

进入xc_crash_exec_dumper指针函数,看看进程dump操作:

这个部分是做各种数据的dump。简单找下main方法:

xcd_core.c

不细看了,整个过程先是挂起crash进程的所以线程,然后收集相关log,最后resume所有线程。

xc_trace_init部分不分析了,与xc_jni_init分析方法一致。这里也就简单分析了个大脉络。

Native崩溃处理步骤总结:

同样在Xcrash init时初始化

Crash.java

这里有个限制,是sdk <21的版本才抓取。

AnrHandler.java

高版本系统已经没有读取/data/anr/的权限了,因此FileObserver监听/data/anr/的方案只能支持<21的版本,而目前xcrash对>21的版本无法获取anr日志。

然后看看handleAnr收集了哪些数据:

这里重点关注checkProcessAnrState,它是AMS对外暴露的api,从AMS的mLruProcesses中过滤出crash和anr异常的进程,返回对应的错误信息。补充cause reason部分,也就是ANR in。

那么>21版本的anr如何抓取?
//init native crash handler / ANR handler (API level >= 21)
int r = Errno.OK;
if (params.enableNativeCrashHandler || (params.enableAnrHandler && Build.VERSION.SDK_INT >= 21)) {
r = NativeHandler.getInstance().initialize(...);
}
是通过nativeHandler来抓的。也就是前面提到的

它是native 注册 SIGNAL_QUIT 信号,ANR发生时接收回调去收集ANR信息。

这里xc_trace_notifier是一个eventfd ,在handler接收信号回调时被写

然后xc_trace_dumper线程会解除阻塞状态开始执行dump任务。

本篇文章简单分析了下xcrash2.5.7源码,结合之前 java crash处理分析 和 native crash 处理分析,对app收集奔溃日志的整个过程有了个全面了解。

相似回答