摘要:
在开发中经常会遇到崩溃,这时候你知道崩溃的文件存放在哪里?你有什么方法来获取崩溃的日志文件?崩溃日志获取到了,你知道如何查看它吗?本文将带着以上的文件,对崩溃进行分析。
崩溃日志
1.什么是崩溃日志
iOS 设备上的应用程序在闪退的时候,操作系统会声称一个崩溃日志,保存在设备上1
2
3路径:设置-> 隐私 -> 诊断与用量 -> 诊断与用量数据
在诊断与用量的界面中 有发送和不发送的操作,在这里如果选择发送的话,会自动将诊断和用量数据发送到iTunes 来帮助开发者进行崩溃日志的分析
崩溃日志的获取
1.连接设备获取崩溃日志
设备与电脑上的ITunes Stores 同步后,会将崩溃日志保存在电脑上,崩溃日志保存在一下位置1
2
3MAC OS X : ~/Library/Logs/CrashReporter/MobileDevice/
然后可以看到你的设备名称的文件夹,然后继续往下找
2.通过XCode 连接来导出崩溃日志
首先将XCode 和电脑连接,然后 window-> Devices and Simulators
然后进入查看View Device Logs
这时候可以查看到所有的日志文件,可以查看到右边窗口看到对应的
3.通过iTunes 获取崩溃日志
通过Itunes Connect 获取使用者上传的崩溃日志,登录iTunes Connect 选中APP ,点击可供销售的APP 在额外信息中可以查看到所有iOS 版本下的崩溃日志
崩溃日志的分析
这里我们来分析下对用字段的解析:incident Identifier:崩溃日志的唯一标识符
CrashReporter Key:是与设备标识相对应的唯一键值。
Hardware Model:标识设备类型
Process :是应用的名称
Version:APP的版本号
最重要的两个:
Exception Type:崩溃的类型
Last Exception Backtrace:发生崩溃的时候的堆栈
XCode 会自动符号化代码,翻译成明文:
将.crash 文件反编译得到明文的crash 文件首先在桌面新建一个文件夹 DebugTest
然后将 MyApp.app ,MyApp.app.dYSM 还有 崩溃文件 .crash 文件放入到这个文件夹中
找到Symbolicatecrash 这个文件,将其拷贝到DebugTest 这个文件夹中1cd /Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources
在终端中运行命令,符号化崩溃日志1
2
3
4
5cd /User/younmae/Desktop/DebugTest
export DEVELOP_DIR = "/Applications/Xcode.app/Contents/Developer"
./Symbolicatecrash -v crashfile MyApp.app.dYSM
然后再打开就看到了符号化后的明文的崩溃日志文件
注意:构建版本的时候会自动生成dSYM 文件,但是debug 的时候,是没有的,需要我们手动开启,在build Setting 中搜索debug
这两个就可以产生dsym 了
手动捕获崩溃日志
首先Apple 提供了一个NSSetUncaughtExceptionHandler1
2
3
4
5
6
7
8
9
10
11
12
13-(void)catchCrashLogs{
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
}
void UncaughtExceptionHandler(NSException *exception){
if(exception == nil) return;
NSArray *array = [exception callStacksSymbols];
NSString *reason = [exception reason];
NSString *name = [exception name];
}
解决崩溃收集冲突问题
在进行崩溃日志处理的时候,可能会遇到一些冲突的操作:首先因为收集崩溃日志的操作是有些第三方操作也需要实现的,所以这里我们需要先确定下处理这个冲突的流程
首先先通过 NSGetUncaughtExceptionHandler() 拿到之前日志库处理exception 的handler ,然后通过 NSSetUncaughtExceptionHandler(),设置自己处理的exception 的hanler ,在自己的handler 处理异常完之后,再将异常塞给之前的hanler
初始化
使用第三方的工具的时候,首先需要先初始化第三方的操作,然后才能初始化我们自己的日志收集工具
获取第三方的handler 和 设置自己的handler
static NSUncaughtExceptionHandler *_previousHandler;
_perviousHandler = NSGetUncaughtExceptionHandler();
//设置自己处理异常的handler
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
处理自己的异常1
2
3
4
5void UncaughtExceptionHanlder(NSException *exception){
//
取出exception 的 name reason 和 callStacksSymbols 计算出崩溃是的偏移量把这些信息以字段存储到本地上
}
将exception 塞给第三方
处理完自己的逻辑后就需要将exception 赋值给我们之前保存的handler ,否则第三方就无法统计崩溃的数据1_previousHandler(exception);
不足和改进
并不是所有的程序崩溃都是可以捕获的异常,有些时候引起异常的大多数原因:比如说内存错误,重复是否等错误信息就可能无能为力。这时候需要通过signal 来做处理
参考