iOS Crash分析

       在iOS开发中,Crash无疑是App的致命杀手。作为一个严谨的iOS 开发人员来说,写出优秀的健硕的无Crash代码至关重要。但是随着工程代码量的提升,功能的迭代,以及协作开发的模式,难免会有Crash的发生。在发生Crash时,我们应迅速定位问题,解决问题,将Crash几率降到最低。

1 Crash 收集

       当程序运行发生Crash的时候,系统会把运行的最后时刻的程序运行记录保存下来,存储到一个.crash文件中,也就是我们常说的Crash日志。

一、  在开发中,最常遇到的Crash就是Debug状态下了,此时我们是幸运的,因为这个bug我们自己最先知道,我们可以在别人发现它之前把它改好。而且,Xcode 会提供给我们最明确的Crash信息,直接定位到Crash 的那行代码,并会打印出Crash Reason 及调用栈信息。

二、如果我们运气稍差一些,在开发中自测App没有发现任何Crash问题,但是测试童鞋或者其他部门的童鞋在测试使用中发现了Crash,但愿不要被老板发现o(╯□╰)o。无论此时的crash是必现还是非必现,我们都可以拿到测试童鞋的Crash设备,拿到设备导出Crash日志吧~

三、最难过的,无疑是自测没发现,测试童鞋也没发现,但是群众的眼睛的雪亮的,我们亲爱用户遇到了这个棘手的Crash,这极差的用户体验很有可能让用户粉转黑,怎么办?做一个Crash收集器势在必行!!!~

关于Crash收集的框架,已经有比较成熟的开源框架,KSCrashCrashKit等,也有第三方的Crash统计产品,如CrashlyticsHockeyapp友盟Bugly等等。

推荐一篇@念茜的文章http://nianxi.net/ios/ios-crash-reporter/

        当App发生Crash时要上传Crash日志,之后我们可以通过服务端自己的Crash收集器拿到Crash文件,或者借助第三方服务拿到Crash文件。

2 Crash 分析

        拿到了Crash日志,我们该从何入手呢?

        Crash日志会提供给我们很多信息,我们要在其中提取出来可以帮我们快速定位问题的信息。

        首先我们看到这几行信息,

Incident Identifier:崩溃报告的唯一标识符,不同的Crash日志该标示符也不同。

CrashReporter Key:设备标识相对应的唯一键值(并非真正的设备的UDID,苹果为了保护用户隐私iOS6以后已经无法获取)。通常同一个设备上同一版本的App发生Crash时,该值都是一样的。

Hardware Model :代表发生Crash的设备类型。

Process:代表系统Crash的进程名称,通常都是我们的App的名字, [ ]里面是当时进程的ID。

Path:App的所在路径。

Identifier:我们App的Indentifier,通常为“com.xxx.yyy”,xxx代表公司的域名,yyy代表某一个App标识。

AppVersion:当前App的版本号,由Info.plist中的两个字段组成,CFBundleShortVersionString and CFBundleVersion。

Code Type:当前App的CPU架构。

Parent Process:当前进程的父进程,由于iOS中App通常都是单进程的,一般父进程都是launchd。

Date/Time:发生crash的时间

Launch Time:启动App的时间

OS Version:iOS系统固件版本

Report Version:日志版本

Exception Type: 这个信息非常重要,它就像是这个crash的名字,我们知道了它的名字,解决它还难吗?

Exception Subtype:它就是crash的小名,当它的大名满足不了我们的时候,google它的小名,你一定会有收获!~

Triggered by Thread: 问题发生的thread

我们再来看线程信息,在日志中找到crash thread,问题就发生在这里,


有些情况下,Crashed Thread 的调用栈中会明确的告诉我们是执行到哪个类中哪行代码时发生了问题,这种情况下我们很容易判断问题原因以及修改问题。但是大多数情况下,调用栈里显示我们Crash在了一个系统的库里,我们看不到代码,所以没办法确定是哪里的操作造成了问题,于是,我们需要做点事情,将crash日志文件符号化。

为了解析crash日志,我们需要三个东西:

1.crash文件

2.符号文件:.dsymb格式

3.应用程序文件:.app格式

然后我们需要把这三个文件放到同一目录下,用atos命令来符号化crash日志的某一行:

打开终端,输入

xcrun atos -o appName.app/appName -arch armv7

然后再输入你要符号化的那一行后面的调用栈地址,例如:0x000000018a650b38

这样就可以得到结果:


就能够定位到具体是代码的哪一行发生了问题。

更多符号化crash文件的方法,可参考链接。http://wufawei.com/2014/03/symbolicating-ios-crash-logs/

3 Crash 处理


一、Watchdog timeout


Exception Code:0x8badf00d

可以读作“eat bad food”,我吃了坏东西,不能继续为你工作了。是不是很形象?

当我们的App 在启动、退出、或者在响应系统事件的时候等待了太长时间,系统会直接杀死进程。Its Not A Crash~

我们应该查看App是否在主线程请求了网络,或者其他耗时的事情卡住了正常初始化流程。

通常系统允许一个App从启动到可以相应用户事件的时间最多为5S,如果超过了5S,App就会被系统终止掉。在Launch,resume,suspend,quit时都会有相应的时间要求。在Highlight Thread里面我们可以看到被终止时调用到的位置,xxxAppDelegate加上行号。

PS. 在连接Xcode调试时为了便于调试,系统会暂时禁用掉Watchdog,所以此类问题的发现需要使用正常的启动模式。

二、用户强制退出


Exception Codes: 0xdeadfa11, deadfall

与正常退出杀死App不同,这种情况可能是用户强制关机或系统强制关机等造成。

三、低内存闪退


当系统发生低内存闪退时,很有可能我们拿不到任何的Crash信息日志,但App的的确确是闪退了。好好做下检讨吧,是不是哪里有内存泄露?用工具好好测试下。

如果我们能够拿到日志,会发现它和一般的Crash日志不太一样,通常有Free pages,Wired Pages,Purgeable pages,largest process 组成,同时会列出当前系统调用栈信息。

如果我们用的是MRC,首先静态分析一下,是不是哪里忘记了release ? dealloc 写的是否正确? 然后使用Instruments检查下内存使用情况,看看哪里的内存占用较高?是否内存泄露?通常大量的图片不能及时释放内存空间的时候会使内存占用飚升。

内存警告通常在我们debug的时候就会发现,及时的清理掉不用的内存,否则内存占用越来越高,超过系统限制就会被系统杀死。

四、Crash due to bugs


因为程序bug导致的Crash通常千奇百怪,很难一概而论。大部分情况通过Crash日志就可以定位出问题,当然也不排除部分疑难杂症看半天都不值问题出在哪儿。这个就只能看功底了,一点点找,总是能发现蛛丝马迹。是在看不出来时还可以求助于Google大神,总有人遇到和你一样的Bug

五、Exception Type


1)EXC_BAD_ACCESS

此类型的Excpetion是我们最长碰到的Crash,通常用于访问了不改访问的内存导致。一般EXC_BAD_ACCESS后面的"()"还会带有补充信息。

SIGSEGV:通常由于重复释放对象导致,这种类型在切换了ARC以后应该已经很少见到了。

SIGABRT:收到Abort信号退出,通常Foundation库中的容器为了保护状态正常会做一些检测,例如插入nil到数组中等会遇到此类错误。

SEGV:(Segmentation  Violation),代表无效内存地址,比如空指针,未初始化指针,栈溢出等;

SIGBUS:总线错误,与 SIGSEGV 不同的是,SIGSEGV 访问的是无效地址,而 SIGBUS 访问的是有效地址,但总线访问异常(如地址对齐问题)

SIGILL:尝试执行非法的指令,可能不被识别或者没有权限

2)EXC_BAD_INSTRUCTION

此类异常通常由于线程执行非法指令导致。

1.在代码中修改了storyboard与outlet的对应关系,但是storyboard没有更新时发生过此crash。

2.与第三方库中方法冲突时发生过此crash。

3.调用系统方法时传入了不恰当的指针类型。

3)EXC_ARITHMETIC

代码中做除法时分母为零了会发生此问题。

6、Exception Code

0xbaaaaaad此种类型的log意味着该Crash log并非一个真正的Crash,它仅仅只是包含了整个系统某一时刻的运行状态。通常可以通过同时按Home键和音量键,可能由于用户不小心触发

0xbad22222当VOIP程序在后台太过频繁的激活时,系统可能会终止此类程序

0x8badf00d这个前面已经介绍了,程序启动或者恢复时间过长被watch dog终止

0xc00010ff程序执行大量耗费CPU和GPU的运算,导致设备过热,触发系统过热保护被系统终止

0xdead10cc程序退到后台时还占用系统资源,如通讯录被系统终止

0xdeadfa11前面也提到过,程序无响应用户强制关闭

更多开发中遇到的错误码可以参考链接https://en.wikipedia.org/wiki/Hexspeak


欢迎订阅我的个人主页~

新浪微博:@小花哥哥是天才

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,387评论 25 707
  • 在分析一份crash日志之前,如果开发人员对于常见的错误类型有所了解,那定是极好的。crash日志的产生来源于两种...
    怪小喵阅读 1,769评论 0 9
  • [TOC] 本文转载于同事的分享文章 siyi.xie,在这里记录一下 [TOC] iOS crash分析 符号化...
    game3108阅读 6,210评论 1 51
  • 如果你有过分析iOS崩溃日志的经验,一定经常看到日志里出现很多<redacted>的字段。这篇文章就是帮助开发者将...
    黑超熊猫zuik阅读 11,579评论 26 70
  • 前言 iOS崩溃是让iOS开发人员比较头痛的事情,app崩溃了,说明代码写的有问题,这时如何快速定位到崩溃的地方很...
    齐滇大圣阅读 65,222评论 29 443