Native Crash捕获原理与实践(一)

在Android平台,native crash一直是crash里的大头。native crash具有上下文不全、出错信息模糊、难以捕捉等特点,比java crash更难修复。

一、为什么会产生Native Crash?

常见导致Native Crash的原因有以下几种:

1. jni内部数组越界、缓冲区溢出、空指针、野指针等;

2. jni中多线程出现竞争,比如一个线程调用jni接口释放了内部一个指针,另一个线程调用另外一个jni接口还在使用这个指针;

3. Android ART发现或出现异常;

4. 其他framework、Kernel或硬件bug;

二、现有的方案

方案

优点

缺点

Google Breakpad 权威,跨平台 代码体量大
利用Logcat日志 利用Android系统实现 需要在crash时启动新进程过滤logcat日志,不可靠
coffeecatch 实现简介,改动容易 存在兼容性问题

Google breakpad是一个跨平台的崩溃转储和分析框架和工具集合,具有权威、跨平台等优点,其实现原理如下图所示。

Breakpad由三个主要组件:

  • client:以library的形式内置在你的应用中,当崩溃发生时写 minidump文件
  • symbol dumper:读取由编译器生成的调试信息(debugging information),并生成 symbol file
  • processor:读取 minidump文件 和 symbol file ,生成可读的c/c++ Stack trace.

由于google-breakpad是夸平台开源工具,体量较大,在其基础上生成的通用so和dmp日志也都较大,对于sdk大小有严格要求的APP,可能不是很方便。Logcat日志虽然是利用Android系统实现,但是需要在crash时启动新进程过滤logcat日志,而且不可靠。因此,下面介绍一种体量较小的基于c/c++异常信号处理的NativeCrash日志收集方法,其实现原理如下图所示。

三、信号机制

1、用户态和内核态

介绍信号机制之前,我们先来了解两个概念,即用户态和内核态。

用户态(User Mode):运行用户程序。

内核态(Kernel Mode):运行操作系统程序。

用户态和内核态是操作系统的两种CPU状态。

CPU状态之间的转换如下图所示。

2、信号机制

信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号。应用程序运行在用户态,当遇到系统调用、中断或异常的情况时,程序会进入内核态。信号涉及到了这两种状态之间的转换,其转换过程如下图所示。

(1) 信号的接收

接收信号的任务是由内核代理的,当内核接收到信号后,会将其放到对应进程的信号队列中,同时向进程发送一个中断,使其陷入内核态。注意,此时信号还只是在队列中,对进程来说暂时是不知道有信号到来的。

(2) 信号的检测

进程陷入内核态后,有两种场景会对信号进行检测:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值