崩溃信号 | 崩溃错误码 | 故障根因 | 关键字段 | 解决方案 |
|---|---|---|---|---|
SIGABRT | SI_TKILL | 断言检查失败 | LastFatalMessage:Assertion failed | 检查代码运行时的断言条件,修复业务逻辑异常。 |
SIGABRT | SI_TKILL | 未处理抛出的异常 | terminating due to uncaught exception of type | 在抛出异常的位置使用try-catch捕获并处理异常。 |
SIGABRT | SI_TKILL | 调用napi_fatal_error引发致命错误 | LastFatalMessage:[(xxx)(napi_fatal_error)] FATAL ERROR | 排查napi_fatal_error的调用逻辑是否符合预期。 |
SIGSEGV | SEGV_MAPERR | 空指针解引用 | probably caused by NULL pointer dereference | 排查代码中的指针变量,是否存在使用未初始化、赋值为空或已释放的指针。 |
SIGSEGV | SEGV_ACCERR | 访问越栈内存上界 | probably caused by stack-buffer-overflow | 排查递归调用时未设置递归终止条件导致栈内存耗尽;局部变量占用过多栈内存导致栈内存耗尽;在信号栈中使用超过系统限制的栈内存。 |
进程在Native层发生崩溃后,系统会抓取崩溃相关的信息,在faultlogger目录下生成cppcrash-应用包名-应用UID-发生时间.log崩溃日志并上报崩溃事件,以供开发者分析定位。CppCrash日志规格说明可以参考日志规格。
步骤一:获取cppcrash-应用包名-应用UID-发生时间.log故障日志。
步骤二:分析故障原因Reason和崩溃堆栈Stack。
Reason字段规格如下:
一般规格包含崩溃类型Signal、崩溃地址和信号发送方信息,Signal信号的含义可见基本概念和实现原理。
Reason:Signal:SIGABRT(SI_TKILL)@0x01317bc900000a02 from:2562:20020169 字段解释如下: Reason:Signal:信号值(tkill()函数信号)@崩溃地址 from:发送信号的Pid:发送信号的Uid
堆栈日志规格如下:
崩溃堆栈搜索关键字Fault thread info。
堆栈日志打印上限为256个栈帧,超出部分不打印。
Fault thread info: #00 pc 00000000001b0958 /system/lib/ld-musl-aarch64.so.1(raise+216)(52299a28d60f0bb4073bd788bc023a3a) #<序号> pc <pc在段内的偏移> <pc属于的段名称(函数名+函数内偏移的字节数)(BuildID)> pc:程序计数器(Program Counter)的缩写,作用是储存当前程序正在执行指令的地址。 BuildID:是用于标识二进制文件的唯一标识符。
问题场景如下:
步骤三:结合业务代码分析根因。
步骤四:异常崩溃场景排查地址越界(可选)。
如果多次崩溃产生了随机的崩溃调用栈,或堆栈指向的代码不应该发生此崩溃信号,则可能发生了地址越界,此时的崩溃栈已非第一现场,需要使用HWASan等内存检测工具,调试压测抓取第一现场的堆栈,详情参考地址越界类问题分析方法。