美文网首页
iOS崩溃收集相关 SIGSEGV Background Tas

iOS崩溃收集相关 SIGSEGV Background Tas

作者: ElegantLiar | 来源:发表于2021-05-31 19:25 被阅读0次

iOS崩溃收集相关 SIGSEGV Background Task

崩溃的主要分类

我们可以看到, KVO 问题、NSNotification 线程问题、数组越界、野指针等崩溃信息,是可以通过信号捕获的。但是,像后台任务超时、内存被打爆、主线程卡顿超阈值等信息,是无法通过信号捕捉到的

  • 可以通过信号捕获到崩溃信息的
    • KVO 问题
    • NSNotification 线程问题
    • 数组越界
    • 野指针等
  • 不可以通过信号捕获到崩溃信息的
    • 后台任务超时
    • 内存被打爆
    • 主线程卡顿超阈值等

崩溃日志的收集

  1. 通过PLCrashReporter 这样的第三方开源库捕获崩溃日志,然后上传到自己服务器上进行整体监控的。
  2. 直接使用 Fabric或者Bugly来监控崩溃。

SIGSEGV信号可以捕获的崩溃信息收集

在崩溃日志里,你经常会看到下面这段说明:

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)

它表示的是,EXC_BAD_ACCESS 这个异常会通过 SIGSEGV 信号发现有问题的线程。虽然信号的种类有很多,但是都可以通过注册 signalHandler 来捕获到。其实现代码,如下所示:

void registerSignalHandler(void) {
    signal(SIGSEGV, handleSignalException);
    signal(SIGFPE, handleSignalException);
    signal(SIGBUS, handleSignalException);
    signal(SIGPIPE, handleSignalException);
    signal(SIGHUP, handleSignalException);
    signal(SIGINT, handleSignalException);
    signal(SIGQUIT, handleSignalException);
    signal(SIGABRT, handleSignalException);
    signal(SIGILL, handleSignalException);
}

void handleSignalException(int signal) {
    NSMutableString *crashString = [[NSMutableString alloc]init];
    void* callstack[128];
    int i, frames = backtrace(callstack, 128);
    char** traceChar = backtrace_symbols(callstack, frames);
    for (i = 0; i <frames; ++i) {
        [crashString appendFormat:@"%s\n", traceChar[i]];
    }
    NSLog(crashString);
}

捕获到异常信号后,在处理方法 handleSignalException 里通过 backtrace_symbols 方法就能获取到当前的堆栈信息。堆栈信息可以先保存在本地,下次启动时再上传到崩溃监控服务器就可以了。

崩溃信息的分析解决

崩溃日志,主要包含的信息为:进程信息、基本信息、异常信息、线程回溯

  • 进程信息:崩溃进程的相关信息,比如崩溃报告唯一标识符、唯一键值、设备标识;
  • 基本信息:崩溃发生的日期、iOS 版本;
  • 异常信息:异常类型、异常编码、异常的线程;
  • 线程回溯:崩溃时的方法调用栈。

分析思路:

  1. 异常信息
  2. 分析线程,回溯线程
  3. 分析方法调用栈

被系统Kill掉的常见编码

  • 0x8badf00d,表示 App 在一定时间内无响应而被 watchdog 杀掉的情况。//卡顿检测
  • 0xdeadfa11,表示 App 被用户强制退出。
  • 0xc00010ff,表示 App 因为运行造成设备温度太高而被杀掉。//运行温度过高

信号捕获不到的崩溃信息的收集

场景: App 退到后台后崩溃//系统强杀

常见的iOS保活方式

  • 使用 Background Mode 方式的话,App Store 在审核时会提高对 App 的要求 //通常情况下,只有那些地图、音乐播放、VoIP 类的 App 才能通过审核。
  • Background Fetch 方式的唤醒时间不稳定,而且用户可以在系统里设置关闭这种方式,导致它的使用场景很少。
  • Silent Push 是推送的一种,会在后台唤起 App 30 秒。它的优先级很低,会调用 application:didReceiveRemoteNotifiacation:fetchCompletionHandler: 这个 delegate,和普通的 remote push notification 推送调用的 delegate 是一样的。
  • PushKit 后台唤醒 App 后能够保活 30 秒。它主要用于提升 VoIP 应用的体验。
  • Background Task 方式,是使用最多的。App 退后台后,默认都会使用这种方式。

Background Task//系统提供了 beginBackgroundTaskWithExpirationHandler 方法来延长后台执行时间,解决退后台后还需要一些时间去处理一些任务的诉求

使用方式:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^( void) {
        [self yourTask];
    }];
}

注意: yourTask 任务最多执行 3 分钟,3 分钟内 yourTask 运行完成,你的 App 就会挂起。 如果 yourTask 在 3 分钟之内没有执行完的话,系统会强制杀掉进程

使用: 采用 Background Task 方式时,我们可以根据 beginBackgroundTaskWithExpirationHandler 会让后台保活 3 分钟这个阈值,先设置一个计时器,在接近 3 分钟时判断后台程序是否还在执行。如果还在执行的话,我们就可以判断该程序即将后台崩溃,进行上报、记录,以达到监控的效果。

相关文章

网友评论

      本文标题:iOS崩溃收集相关 SIGSEGV Background Tas

      本文链接:https://www.haomeiwen.com/subject/dzgbsltx.html