当前位置: 首页 > news >正文

iOS 兼容多个有crash 收集机制的SDK

我们知道,如果一个APP内有多个第三方crash 收集SDK,那么很可能他们之间会有冲突,如果APP自身也有crash 收集机制,那么如何做兼容呢?

1.UncaughtException 如果同时有多方通过NSSetUncaughtExceptionHandler注册异常处理程序,和平的作法是:后注册者通过NSGetUncaughtExceptionHandler将先前别人注册的handler取出并备份,在自己handler处理完后自觉把别人的handler注册回去,规规矩矩的传递。不传递强行覆盖的后果是,在其之前注册过的日志收集服务写出的Crash日志就会因为取不到NSException而丢失Last Exception Backtrace等信息。(P.S. iOS系统自带的Crash Reporter不受影响) 在开发测试阶段,可以利用 fishhook 框架去hookNSSetUncaughtExceptionHandler方法,这样就可以清晰的看到handler的传递流程断在哪里,快速定位污染环境者。不推荐利用调试器添加符号断点来检查,原因是一些Crash收集框架在调试状态下是不工作的。 示例:

static NSUncaughtExceptionHandler *previousUncaughtExceptionHandler;
+ (void)installExceptionHandler {   
 //将之前的注册的handler保存起来    previousUncaughtExceptionHandler = NSGetUncaughtExceptionHandler();    NSSetUncaughtExceptionHandler(&LDAPMUncaughtExceptionHandler);
}
static void LDAPMUncaughtExceptionHandler(NSException *exception) {    
// 获取堆栈,收集堆栈    
// 这里做我们自己对exception的处理   
 // ······   
 // 处理完以后,调用前者的handler处理exception,让他们也有数据,如果不做处理,之前的注册的都将无法获取到exception   
 if (previousUncaughtExceptionHandler) {            
      previousUncaughtExceptionHandler(exception);   
    }
}
复制代码

在开发测试阶段,可以利用 fishhook 框架去hook NSSetUncaughtExceptionHandler方法,这样就可以清晰的看到handler的传递流程断在哪里,快速定位污染环境者。不推荐利用调试器添加符号断点来检查,原因是一些Crash收集框架在调试状态下是不工作的。检测代码如下,

static NSUncaughtExceptionHandler *g_vaildUncaughtExceptionHandler;​static void(*ori_NSSetUncaughtExceptionHandler(NSUncaughtExceptionHandler * );
​void my_NSSetUncaughtExceptionHandler( NSUncaughtExceptionHandler * handler)​{​    
g_vaildUncaughtExceptionHandler = NSGetUncaughtExceptionHandler();​   
 if (g_vaildUncaughtExceptionHandler != NULL) {​        
 NSLog(@"UncaughtExceptionHandler=%p",g_vaildUncaughtExceptionHandler);   
} ​    
 ori_NSSetUncaughtExceptionHandler(handler);​    
 NSLog(@"%@",[NSThread callStackSymbols]);​   
 g_vaildUncaughtExceptionHandler = NSGetUncaughtExceptionHandler();​ 
 NSLog(@"UncaughtExceptionHandler=%p",g_vaildUncaughtExceptionHandler);
​}
复制代码

2.Signal handler

typedef void (*SignalHandler)(int signo, siginfo_t *info, void *context);​
static SignalHandler previousSignalHandler = NULL;​
+ (void)installSignalHandler {    
struct sigaction old_action;    
sigaction(SIGABRT, NULL, &old_action);    
//先保存之前旧的signal的handler    
if (old_action.sa_flags & SA_SIGINFO) {        
previousSignalHandler = old_action.sa_sigaction;   
}    
//注册我们自己的handler    
LDAPMSignalRegister(SIGABRT);    
// .......​
}
//注册signal handlerstatic 
void LDAPMSignalRegister(int signal) {    
struct sigaction action;    
action.sa_sigaction = LDAPMSignalHandler;    
action.sa_flags = SA_NODEFER | SA_SIGINFO;    sigemptyset(&action.sa_mask);    
sigaction(signal, &action, 0);
}
static void LDAPMSignalHandler(int signal, siginfo_t* info, void* context) {    
// 获取堆栈,收集堆栈   
//........​    
LDAPMClearSignalRigister();​    
// 处理前者注册的 handler    
if (previousSignalHandler) {        
previousSignalHandler(signal, info, context);   
}
}
复制代码

相关文章:

  • 37.3. HQL
  • 详细解析漏洞4个boom
  • HSRP、VRRP、ACL
  • 407. 加一
  • NoClassDefFoundError
  • 压缩打包介绍 gzip压缩工具 bzip2压缩工具
  • 数组注意事项
  • Git与GitHub学习笔记(八)git如何同时同步提交到码云和GitHub上
  • 阿里人工智能实验室?对,这个神秘机构即将登场
  • 马斯克又双叒叕谈AI威胁论,李开复又双叒叕反对马斯克
  • python-登录
  • 一起撸个朋友圈吧(step3) ListAdapter篇
  • foreach Transform 同时chils.setParent引起的bug
  • python笔记7-多线程threading之函数式
  • org.codehaus.mojo:build-helper-maven-plugin:1.4:add-source (execution: add-sourc
  • 【刷算法】从上往下打印二叉树
  • 2017年终总结、随想
  • 345-反转字符串中的元音字母
  • css布局,左右固定中间自适应实现
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • Java 内存分配及垃圾回收机制初探
  • Javascript基础之Array数组API
  • Java应用性能调优
  • redis学习笔记(三):列表、集合、有序集合
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • Web设计流程优化:网页效果图设计新思路
  • Zepto.js源码学习之二
  • 百度小程序遇到的问题
  • 讲清楚之javascript作用域
  • 前端存储 - localStorage
  • 前端面试题总结
  • 全栈开发——Linux
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 一起参Ember.js讨论、问答社区。
  • 用 Swift 编写面向协议的视图
  • 用mpvue开发微信小程序
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (12)目标检测_SSD基于pytorch搭建代码
  • (2)MFC+openGL单文档框架glFrame
  • (2015)JS ES6 必知的十个 特性
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (9)STL算法之逆转旋转
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (HAL库版)freeRTOS移植STMF103
  • (Python第六天)文件处理
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (六)激光线扫描-三维重建
  • (一)80c52学习之旅-起始篇
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)Windows2003安全设置/维护