写点什么

如何查看崩溃日志

作者:
  • 2024-01-08
    广东
  • 本文字数:3514 字

    阅读完需:约 12 分钟


描述

模拟器和真机调试运行正常,但是导出 ipa 包安装运行出现奔溃。记录一下提醒一下遇到同样问题的人少走弯路。

思路

首先遇到问题,头脑要保持清醒。思考为什么会出现这样的问题?

  • 模拟器和真机调试运行正常,模拟器和真机调试是在DeBug模式下运行的

  • 导出ipa包的环境是Release模式下

所以可以重点是在 Release 模式下查看崩溃信息才能定位问题。

查看 ipa 包崩溃日志

手机数据线连接电脑,借助克魔助手就可以看,Xcode -> Window-> Devices and Simulator

进入后,选择【View Device Logs

日志文件看的好难受,好像也没有办法定位具体问题,接着分析

刚才不是分析在Release模式下出现的问题嘛,所以可以直接将本地调试的Dudeg的模式修改为Relese模式,然后运行。默认是Debug模式,选择Release模式,然后本地调试的时候就和导出的 ipa 环境一致啦。同时记得要勾选 【Zombie Ojects】,可以定位出野指针和僵尸对象。然后运行 Xcode,可以定位到具体问题啦,同时控制台也输出了使用的对象提前释放导致的问题。

简单查看手机崩溃信息几种方式

方式 1:手机设置查看崩溃日志

步骤:【设置】-> 【隐私】 -> 【分析与改进】-> 【分析数据】

方式 2: Xocde 工具

手机数据线连接电脑,借助 Xcode 就可以看,Xcode -> Window-> Devices and Simulator,具体和上面一致,请参照上图示例。

方式 3: 第三方软件克魔助手

通过数据线连接 iOS 手机和电脑

在 iOS 应用开发过程中,调试日志和奔溃日志是开发者必不可少的工具。然而,使用 Xcode Console 等工具查看日志可能不够方便,而且处理奔溃日志也相当繁琐。克魔助手的出现为开发者带来了极大的便利,本文将详细介绍其功能和使用方法。 克魔助手会提供两种日志,一种是实时的,一种的是崩溃的。(由于崩溃日志的环境很麻烦,目前只展示实时日志操作步骤)

环境配置

  • 电脑一台(台式和笔记本都 OK)

  • iPhone 手机一台

  • 下载克魔助手

  • 下载爱思助手或者 itunes 驱动

实时日志

克魔助手提供了实时日志功能,能够在电脑上实时查看设备的日志信息。 下面是操作步骤:

1.先将 iPhone 通过数据线连接上电脑,iOS 手机上一定要信任这次连接



2.在电脑上打开克魔助手-实时日志。



3.因为你已经通过数据线连接了电脑和手机,所以此时在控制台的左侧工具栏里会显示你的设备,如果此时直接点击 开始日志那将输出的是此设备的所有日志,那么如果想要查看某一 App 的日志查看起来是非常繁琐的,那我就需要对 App 继续筛选过滤再输出。



4.选择需要查看 iPhone 里面的 App(可以通过 command+ 空格,搜索应用),然后点击 开始日志,将会输出关于此 App 的所有日志




5.如果需要对 App 里面的关键字继续过滤处理,可关键字那直接输入后点击清空日志,再点击空白处即可过滤成功



6.当你过滤出来了错误信息后,你可以将这些错误日志存储起来,形成一个 errorlog 提交给到开发,点击 导出日志即可生成一个文件夹。



奔溃日志分析

克魔助手还提供了奔溃日志分析查看模块,可以方便地导出和查看 iOS 设备上的奔溃日志,并对其进行符号化、格式化和分析。 操作如下:

1.选择需要查看的奔溃日志。



2.点击“导出日志”,即可生成一个包含奔溃日志的文件夹,便于提交给开发团队进行分析。

PS:数据连接时,先将 iPhone 通过数据线连接上电脑,iOS 手机上一定要信任这次连接,(开启 WiFi 调试时,无需数据线)



方式四:控制台资源库

可以看到所有和该电脑同步过的设备的崩溃日志(.crash 文件)

输入下方的文件地址:


~/Library/Logs/CrashReporter/MobileDevice
复制代码


找到自己手机设备的日志信息

开发程序过程也会出现程序 crash 的情况,那么这时生成的文件目录为:

~/Library/Logs/DiagnosticReports/
复制代码


线上崩溃日志

线上监听 crash 的几种方式

方式 1: 三方平台的 SDK

例如:腾讯 Bugly、crashlytics、友盟 SDK

方式 2: 自己实现异常监听,然后提交后台

自己实现异常监听的方式稍微复杂点,需要异步监听任务,不能影响到主进程的任务体验

常见的造成的崩溃的情况

1.数组越界

在取数据索引时越界,App 会发生崩溃。还有一种情况,就是给数组添加了 nil 会崩溃

2.多线程问题

在子线程中进行 UI 更新可能会发生崩溃。多个线程进行数据的读取操作,因为处理时机不一致,比如有一个线程在置空数据的同时另一个线程在读取这个数据,可能会出现崩溃情况。

3.主线程无响应

如果主线程超过系统规定的时间无响应,就会被 Watchdog 杀掉。这时,崩溃问题对应的异常编码是 0x8badf00d。

4.野指针

野指针指向一个已删除的对象访问内存区域时,会出现野指针崩溃。野指针问题是需要我们重点关注的,因为它是导致 App 崩溃的最常见,也是最难定位的一种情况

信号可捕获的崩溃日志收集

打开 Xcode 的菜单选择 Product -> Archive 然后,在提交时选上“Upload your app’s symbols to receive symbolicated reports from Apple”,以后你就可以直接在 Xcode 的 Archive 里看到符号化后的崩溃日志了。

但是这种查看日志的方式,每次都是纯手工的操作,而且时效性较差。所以,目前很多公司的崩溃日志监控系统,都是通过克魔助手这样的第三方开源库捕获崩溃日志,然后上传到自己服务器上进行整体监控的。

信号捕获的原理

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


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 方法就能获取到当前的堆栈信息。堆栈信息可以先保存在本地,下次启动时再上传到崩溃监控服务器就可以了。

信号不可捕获的崩溃日志收集

App 退到后台后,即使代码逻辑没有问题也很容易出现崩溃。而且,这些崩溃往往是因为系统强制杀掉了某些进程导致的,而系统强杀抛出的信号还由于系统限制无法被捕获到。

iOS 后台保活的 5 种方式

  • Background Mode

  • Background Fetch

  • Silent Push

  • PushKit

  • Background Task (App 退后台后,默认都会使用这种方式)

采集过程原理

Background Task 这种方式,就是系统提供了 beginBackgroundTaskWithExpirationHandler 方法来延长后台执行时间,可以解决你退后台后还需要一些时间去处理一些任务的诉求。


- (void)applicationDidEnterBackground:(UIApplication *)application {    self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^( void) {        //你的任务逻辑        [self yourTask];    }];}
复制代码


在这段代码中,yourTask 任务最多执行 3 分钟,3 分钟内 yourTask 运行完成,你的 App 就会挂起。 如果 yourTask 在 3 分钟之内没有执行完的话,系统会强制杀掉进程,从而造成崩溃,这就是为什么 App 退后台容易出现崩溃的原因。

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

崩溃日志分析

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

  • 进程信息:崩溃进程的相关信息,比如崩溃报告唯一标识符、唯一键值、设备标识;

  • 基本信息:崩溃发生的日期、iOS 版本;

  • 异常信息:异常类型、异常编码、异常的线程;

  • 线程回溯:崩溃时的方法调用栈。


    一些被系统杀掉的情况,我们可以通过异常编码来分析。


    常见的就是如下三种:

  • 0x8badf00d,表示 App 在一定时间内无响应而被 watchdog 杀掉的情况。

  • 0xdeadfa11,表示 App 被用户强制退出。

  • 0xc00010ff,表示 App 因为运行造成设备温度太高而被杀掉。

用户头像

关注

还未添加个人签名 2023-03-27 加入

还未添加个人简介

评论

发布
暂无评论
如何查看崩溃日志_世_InfoQ写作社区