浅谈第三方 SDK 和自定义 crash 上报冲突问题

简介

在开发 iOS 应用,解决 Crash 问题始终是一个难题。Crash 分为两种,一种是由 EXC_BAD_ACCESS 引起的,原因是访问了不属于本进程的内存地址,有可能是访问已被释放的内存;另一种是未被捕获的 Objective-C 异常,导致程序向自身发送了 UNIX 信号而崩溃。对于这两种 Crash 的捕获,精准高效的收集线上崩溃可以帮助我们更好的解决问题和提高用户体验,现在比较成熟的崩溃收集工具也比较多,比如:友盟统计,Crashlytics,腾讯的 bugly 等等。也可以通过自定义 crash 上报,来处理异常。

问题

但是当自定义 crash 上报收集工具与第三方 crash 收集工具共存的时候,发现自定义 crash 上报收集工具,不能捕获到 exception

原因

/* Set the uncaught exception handler */
NSSetUncaughtExceptionHandler(&uncaught_exception_handler);

由于 crash 的捕获机制只会保存最后一个注册的 handle,不管是第三方还是自定义的上报收集工具,一般会常用注册 ExceptionHandler 的方式,来捕获 exception,但是并没有将异常进行抛出,所以,当工程中使用了第三方上报收集工具进行异常统计的时候,我们自己写的异常捕获有可能会失效。

解决方法

解决冲突的做法是在注册自己的 handle 之前保存已注册的处理函数,便于发生崩溃后能将 crash 信息连续的传递下去。

首先保存第三方的 ExceptionHandler,然后在设置自己处理 exceptionExceptionHandler,在自己的 ExceptionHandler 处理完异常之后,再将异常塞给之前的第三方 ExceptionHandler

static NSUncaughtExceptionHandler *_previousHandler;
 // 保存第三方处理异常的 handler
 _previousHandler = NSGetUncaughtExceptionHandler();
 // 设置自己处理异常的 handler 
 NSSetUncaughtExceptionHandler(&UncaughtExceptionHandlerYourself);

处理自己的异常

void UncaughtExceptionHandlerYourself (NSException *exception) {
}

处理完自己的逻辑之后就需要把 exception 赋值给我们之前保存的handler,否则第三方就无法统计到崩溃的数据。

_previousHandler(exception);

总结,通过这种方法,第三方和我们上报收集工具,都可以正常的收集崩溃数据。第三方上报收集工具捕获到异常,再处理完自己的逻辑后,将 exception 抛了出来,我们自己的崩溃日志收集库收到第三方上报收集工具抛出来的 exception,处理完自己的逻辑后再将 exception 抛给第三方上报收集工具的 handler

你可能感兴趣的:(浅谈第三方 SDK 和自定义 crash 上报冲突问题)