iOS 崩溃分析

1.工程设置

打包的时候生成dSYM(符号表),用来将崩溃的日志符号化

可以将release模式下设置为DWARF with dSYM File

注意:如需要在Xcode中进行错误日志分析,需要在上传到app store时勾选如下选项,上传符号表给Apple

image.png

2.dSYM文件收集

步骤如下:

在Xcode中顶部菜单Window -> Organizer -> Archives中,选中archive的版本右击,选择Show in Finder就可以获取dSYM文件了。

保存好你的app archive,app archive包含调试符号的dSYM。

如果app包含bitcode,需要使用Archives Organizer 中Download Debug Symbols 按钮来下载位码编译生成的dSYM。

3.收集错误日志

收集错误日志有如下几种途径:

a. Xcode,在Xcode中顶部菜单Window -> Organizer -> Crashes中,选择crash然后Show in Finder

b. 第三方,友盟、Bugly、神测等

c. 也可以将发生崩溃的设备连接Xcode,选择window-> devices -> 选择自己的手机 -> view device logs 就可以查看手机上所有的崩溃信息了。

d. 在Mac上使用控制台app查看设备或者模拟器的崩溃日志

e. 在崩溃设备上选择 设备-》隐私 -》 分析与改进 -》分析数据

4. 日志分析

.crash 文件包含:

a.顶部的设备型号、app名称、app版本号、启动时间、崩溃时间、操作系统版本等信息

image.png

b.含崩溃原因,这是操作系统发送用来杀死该进程的具体错误或特定信号

崩溃信号说明 https://developer.umeng.com/docs/193624/detail/204694

image.png

c.崩溃信息 Application Specific Infomation ,包含控制台信息,在模拟器上部分情况可用,在iOS设备上出于个人隐私原因通常会被隐藏

image.png

如果有未处理的异常,则它可能包含如下的异常回溯

d.崩溃线程堆栈,记录崩溃时所有的线程的回溯,其中一条被标记为崩溃的线程

e.崩溃线程的寄存器状态

f.加载到进程中的二进制数据镜像,这是app可执行文件和所有其它的库。Xcode使用它进行符号化,以查找符号文件和行号信息并且显示在堆栈跟踪中

如何查看崩溃日志

  1. 查看异常类型Exception Type,上面的异常类型为EXC_CRASH (SIGABRT)
    异常类型为EXC_BAD_INSTRUCTION (SIGKILL),SIGKILL信号指的是非法指令信号,意味着CPU正在尝试执行由于某种原因不存在或无效的指令,通常被用在当操作系统想要终止你的进程时。SIGKILL信号无法被处理,你的进程也无法捕获它
    异常类型为EXC_BAD_ACCESS(SIGSEGV),即段冲突信号,通常由内存错误引起的,要么时写入只读的内存,要么是尝试从内存中读取根本不存在的内容
  2. 查看异常回溯,查看崩溃时正在执行的代码

常见的内存错误:

image.png
  1. Objective-C 中objc_msgSend 或者retain/release
    这通常是由于你拥有某种类型的对象,然后该对象被释放并再次使用导致的。
  2. Unrecognized selector exception
    同一地址分配了一个新的对象取代了以前旧对象所在的位置,当代码尝试使用旧对象调用旧对象的函数,该地址处去有一个不同类型的不同对象,并且它根本无法识别该函数。

反汇编找出具体奔溃地址:

image.png
image.png

终端找出崩溃地址:

终端符号化崩溃日志

/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

拷贝上面文件和崩溃日志文件、dSYM文件到统一目录,终端cd到这个目录执行如下命令:

./symbolicatecrash ./*.crash ./*.app.dSYM > symbol.crash

会生成一个symbol.crash文件,这个文件内容就是解析crash后所需要的内容。

PS: 若报错
Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash, 只需在终端中运行

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"

若上面符号化没有变化,可以使用atos -o 还原某一行,命令如下:

atos -o (上文中.app.dSYM文件右键显示包内容,一直剥离到标有你工程名字的那一层,把那个文件的地址拖进来,这个文件的那一层已经是最后一层,不能再剥离了) -arch arm64 -l (crash日志里你想要解析的那一行从前面数第四列数字,复制过来,例如:0x1000a8000) (crash日志里你想要解析的那一行从前面数第三列数字,复制过来,例如:0x00000001009d80fc )回车就可以看到解析出来的这一行,完整示例

atos -o /Users/Chandler/Downloads/JDBClient.app.dSYM/Contents/Resources/DWARF/JDBClient -arch arm64 -l 0x1000a8000 0x00000001009d80fc 

多线程问题导致的错误

多线程错误通常时最难诊断和复现的错误类型之一,它们很难复现,因为只会偶尔导致崩溃,因此你的代码在99%的情况下正常工作,这些错误可能在很长一段时间内被忽略。

使用Thread Sanitizer可以调试处多线程问题导致的错误 ,Xcode -》 edit scheme → run -》 Diagnostics 选项卡勾选Thread Sanitizer (只能用于模拟器 )。

建议,创建队列时,可以在初始化提供自定义队列名称。

日志分析建议:

  1. 我们大部分时间都在看奔溃的特定代码和崩溃的线程上,重要的是要查看与崩溃相关的其他代码
  2. 查看崩溃线程以外的堆栈跟踪
  3. 查看多个崩溃日志,以找出特定的崩溃原因
  4. 使用Address Sanitizer 和Zombies等工具复现崩溃

5. 崩溃日志分析工具

  1. Xcode,在Xcode中顶部菜单`Window -> Organizer -> Crashes,如果上传了dSYM给Apple,可以直接在这里查看相关错误信息,但是信息没有第三方的统计的多。

注意:

  • 苹果自带的崩溃统计工具并不推荐用,如果想要使用这个功能,需要用户在iPhone中进行设置设置 -> 隐私 -> 诊断与用量 -> 诊断与用量数据(iOS8以下在通用中设置)选择自动发送,并与开发者共享。

然而很多人并不想和开发者共享数据,或者不设置这个选项,那这样就收集不到这部分的崩溃。

  • 静态库或者动态库Xcode不能查看崩溃的相关堆栈信息
  1. (推荐)第三方,友盟、Bugly、神测等,需要将上面每次发布版本的dSYM文件上传到第三方平台,第三方平台自动符号化错误日志,第三方平台还有行为日志可以追踪用户的操作的页面。

友盟2020年更新了SDK,将统计和崩溃两个功能分开了,最新的需要集成友盟的APMSDK。

如若需要还可以使用uid等其他信息精准定位错误原因 https://apm.umeng.com/platform/5b73d44bb27b0a02e20001c6/error_analysis/scrutiny,需要接入账号集成

  1. 使用 symbolicatecrash 工具
  2. 使用 atos -o

6.崩溃发生原因

代码问题:

  1. swift中可选值强制解包
  2. 数组越界
  3. 溢出,整形变量太大
  4. 未捕获的异常
  5. 自己代码写的断言

环境导致的崩溃,操作系统从外部杀死你的进程:

  1. 你的应用程序执行某件事时间太长
  2. 设备过热,操作系统将终止使用过多CPU的进程
  3. 设备内存不足,操作系统将终止正在使用大量内存的进程
  4. 无效的代码签名,操作系统强制对代码进行签名,如果签名无效或者代码未签名,操作系统将终止该进制并生成特定类型的崩溃日志

由操作系统终止的崩溃可以在设备日志和macOS控制台上找到,它们并不总是会出现在Xcode Organizer中

7. 崩溃防范

  1. 字典

    @{@"part_name":@"学院页",

    @"course_id":model.videoID?:@""}

    可变字段插入值判断nil

  2. 数组
    数组访问、修改和替换时需要做数组长度判断
    插入数组时需要判断nil

  3. 字符串访问、修改和替换时需要做字符串长度判断

  4. 其他地方的变量都建议加上nil值的判断

  5. 接口返回的数据都应是不可信的,应先判断数据类型是否正确,然后再判断是否有此值,再去取值

  6. 谨慎使用kvc

注意!!!

打包上传app store时一定要设置生成dSYM,并且保存好dSYM文件

参考资料:
https://segmentfault.com/a/1190000019569184
https://developer.apple.com/videos/play/wwdc2018/414/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • 崩溃日志的获取 崩溃日志的获取:ios设备上的应用闪退之后会生成崩溃报告存储在设备上,可以通过这样几种途径获取设备...
    纵横而乐阅读 1,516评论 0 1
  • 崩溃日志 如何得到crash report 当一个iOS应用程序崩溃时, 系统会创建一份crash日志保存在设备上...
    々莫等闲々阅读 2,893评论 0 2
  • 作为一名应用开发者,你是否有过如下经历?经常被领导叫去,让看哪位哪位客户运行APP又崩溃了,感觉解决;天天被产品狗...
    继续向前冲阅读 2,822评论 0 9
  • 一、获取 Crash、dSYM 文件 获取到的 .ips 改后缀为 .crash 即可 真机 Crash 文件目录...
    midmirror阅读 9,409评论 0 31
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,032评论 0 4