iOS监控笔记之启动监控笔记之启动crash
前言前言
相较于正常的崩溃问题,启动crash造成的损失要远远大得多。正常来说,如果有足够强健的构建发布系统,大多数时候能在版本上线之前及时发现问题并且修复,但是仍然存在小概率的线上意
外。启动crash一般同时具备损害严重以及难以捕获两大特点
启动过程启动过程
从应用图标被用户点击开始,直到应用可以开始响应发生了很多事情。正常来说,尽管我们希望crash监控工具启动的尽可能早,但接入方往往总是等到launch事件之后才能启动工具,而在这个时
间之前发生的崩溃就是启动crash,下面列出了在应用直到launch时,存在的可能发生启动crash的阶段:
其中initialize的顺序可能在更早,但总是会在load和launch之间。从图中来说,如果我们想要监控启动crash,那么开始监控的时间点必须要放到load阶段,才能保证最好的监控效果
如何监控如何监控
最简单的方式是不管接入方愿不愿意启动crash监控,我们在load方法中直接启动监控功能。但是这样的做法会让应用面临四个风险点:
类似A/B的线上开关方案失去了对监控工具的控制能力
crash监控启动存在崩溃问题,这将导致应用完全瘫痪
load阶段类未加载完毕,启动工具过程的递归加载引发的崩溃无法监控
综合这些风险点,启动crash监控的方案应该满足这些条件:
启动过程不依赖类,避免递归加载造成的crash
一旦过程发生crash,能够保证日志记录的安全性
最终得出监控的流程图:
不依赖类不依赖类
不依赖类意味着监控工具需要使用C接口来实现功能,虽然比较麻烦,但由于runtime的机制决定了所有方法调用最终要以objc_msgSend函数作为入口,因此如果能够hook掉这个函数并且实现一个
调用栈结构,将所有调用入栈记录,那么追踪方法调用就不是难事。fishhook提供了hook掉函数的能力:
__unused static id (*orig_objc_msgSend)(id, SEL, ...);
__attribute__((__naked__)) static void hook_Objc_msgSend() {
/// save stack data
/// push msgSend
/// resume stack data
评论0
最新资源