一、引言
移动App 发布后,如果想获取 App 的业务运行状态,通常是通过服务端接口反映到状态或者是用户反馈,缺少客户端的异常错误的线上监控、告警与异常数据聚合并沉淀的平台
。也无法在多维度进行异常数据的对比,使得收集应用信息和收集崩溃日志变得日益迫切。
37手游研发的 Bugless 定位于从线上问题追踪的视角出发,检测代码异常,通过回溯问题,从而解决代码本身问题。它的主要功能:
- 实时监控SDK业务异常
- 汇总包体崩溃排重与聚合后的数据
- 统计影响设备数
- 上报崩溃日志
- 收集iOS系统向上兼容性问题
- 监控客户端请求的网络问题
Bugless 目标定位是,支持不同项目
不同端
的异常上报告警,智能推送通知,及时发现异常,尽最快速度降低影响时间和范围,减少造成的损失。同时 Bugless 也支持后台聚合错误信息数据,分析历史异常数据,协助开发人员对项目进行实现监控和产品迭代优化。
二、认识崩溃和异常
在讲解 Bugless 之前,让我们从三个层面来介绍,让大家认识App为什么会出现崩溃和异常,以及如何应对。
2.1、App 层面
App 出现崩溃(crash)原因,是因为违反iOS系统运行规则导致的,产生crash的三种类型:
2.1.1 内存引发闪退。
一般是由以下几个方面引起:
- 无效的内存访问
- 内存访问越界
- 运行时方法调用不存在
- 解引用指向无效内存地址的指针
- 跳转到无效地址的指令
2.1.2 响应超时
启动
、挂起
、恢复
、结束
等事件响应不及时
2.1.3 触发Watchdog机制
Watchdog
是为了防止一个应用占用过多系统资源,如果超出了该场景规定的运行时间,“看门狗”就会强制kill掉这个应用,在 crashlog 会看到 “0x8badf00d
”的错误代码。
2.2、Mach 异常和 Unix 信号
Mach
是 iOS 和 macOS 操作系统的微内核,Mach 异常就是最底层的内核级异常。在 iOS 系统中,每个 Thread、Task、Host 都有一个异常端口数据。开发者可以通过设置 Thread、Task、Host 的异常端口来捕获 Mach 异常。Mach 异常会被转换成相应的 Unix 信号,并传递给出错的线程。
在常见的异常崩溃信息中,经常会看到有 Exception Type: EXC_BAD_ACCESS (SIGSEGV)
这样的字段和内容,EXC_BAD_ACCESS
和 SIGSEGV
,分别是指 Mach 异常和 Unix 信号。所以这个 Exception Type 意思是 Mach 层的异常 EXC_BAD_ACCESS 被转换成 SIGSEGV 信号并传递给出错的线程。在 Triggered by Thread
中,我们也可以看到出错的线程编号,例如Triggered by Thread: 0
,0 就是主线程 main-thread。之所以会将 Mach 异常转换成 Un