iOS: Crash文件解析

转载 2015年11月18日 13:42:26

开发程序的过程中不管我们已经如何小心,总是会在不经意间遇到程序闪退。脑补一下当你在一群人面前自信的拿着你的App做功能预演的时候,流畅的操作被无情地Crash打断。联想起老罗在发布Smartisan OS的时候说了,他准备了10个手机,如果一台有问题,就换一台,如果10台后挂了他就不做手机了。好了不闲扯了,今天就跟大家一起聊聊iOSCrash文件的组成以及常用的分析工具。

有一个WWDC 2010的视频推荐大家抽空看看,视频名称“Understanding Crash Reports on iPhone OS”,该视频详细讲解了Crash文件的结构。当然如果你没时间看的话,不妨阅读以下这篇文章。

 

一、Crash文件结构

当程序运行Crash的时候,系统会把运行的最后时刻的运行信息记录下来,存储到一个文件中,也就是我们所说的Crash文件。iOS的Crash日志通常由以下6各部分组成。

1、Process Information(进程信息)

Incident Idnetifier 崩溃报告的唯一标识符,不同的Crash
CrashReporter Key 设备标识相对应的唯一键值(并非真正的设备的UDID,苹果为了保护用户隐私iOS6以后已经无法获取)。通常同一个设备上同一版本的App发生Crash时,该值都是一样的。
Hardware Model 代表发生Crash的设备类型,上图中的“iPad4,4”代表iPad Air
Process 代表Crash的进程名称,通常都是我们的App的名字, []里面是当时进程的ID
Path 可执行程序在手机上的存储位置,注意路径时到XXX.app/XXX,XXX.app其实是作为一个Bundle的,真正的可执行文件其实是Bundle里面的XXX,感兴趣的可以自己查一下相关资料,有机会我后面也会介绍到
Identifier 你的App的Indentifier,通常为“com.xxx.yyy”,xxx代表你们公司的域名,yyy代表某一个App
Version 当前App的版本号,由Info.plist中的两个字段组成,CFBundleShortVersionString and CFBundleVersion
Code Type 当前App的CPU架构
Parent Process 当前进程的父进程,由于iOS中App通常都是单进程的,一般父进程都是launchd

 

2、Basic Information

Date/Time Crash发生的时间,可读的字符串
OS Version 系统版本,()内的数字代表的时Bulid号
Report Version Crash日志的格式,目前基本上都是104,不同的version里面包含的字段可能有不同

 

3、Exception(非常重要)

Exception Type 异常类型
Exception Subtype: 异常子类型
Crashed Thread 发生异常的线程号

 

4、Thread Backtrace

发生Crash的线程的Crash调用栈,从上到下分别代表调用顺序,最上面的一个表示抛出异常的位置,依次往下可以看到API的调用顺序。上图的信息表明本次Crash出现xxxViewController的323行,出错的函数调用为orderCountLoadFailed。

5、Thread State

Crash时发生时刻,线程的状态,通常我们根据Crash栈即可获取到相关信息,这部分一般不用关心。

6、Binary Images

Crash时刻App加载的所有的库,其中第一行是Crash发生时我们App可执行文件的信息,可以看出为armv7,可执行文件的包得uuid位c0f……cd65,解析Crash的时候dsym文件的uuid必须和这个一样才能完成Crash的符号化解析。

二、常见的Crash类型

1、Watchdog timeout

Exception Code:0x8badf00d, 不太直观,可以读成“eat bad food”,意思是don‘t block main thread

紧接着下面会有一段描述:

Application Specific Information:

com.xxx.yyy   failed to resume in time

对于此类Crash,我们应该去审视自己App初始化时做的事情是否正确,是否在主线程请求了网络,或者其他耗时的事情卡住了正常初始化流程。

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

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

2、User force-quit

Exception Codes: 0xdeadfa11, deadfall

这个强制退出跟我们平时所说的kill掉后台任务操作还不太一样,通常在程序bug造成系统无法响应时可以采用长按电源键,当屏幕出现关机确认画面时按下Home键即可关闭当前程序。

3、Low Memory termination

跟一般的Crash结构不太一样,通常有Free pages,Wired Pages,Purgeable pages,largest process 组成,同事会列出当前时刻系统运行所有进程的信息。

关于Memory warning可以参看我之前写的一篇文章IOS 内存警告 Memory warning level

App在运行过程中,系统内存紧张时通常会先发警告,同时把后台挂起的程序终止掉,最终如果还是内存不够的话就会终止掉当前前台的进程。

当接受到内存警告的事后,我们应该释放尽可能多的内存,Crash其实也可以看做是对App的一种保护。

4、Crash due to bugs

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

三、常见的Exception Type & Exception Code

1、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

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

3)EXC_ARITHMETIC

除零错误会抛出此类异常

2、Exception Code

0xbaaaaaad 此种类型的log意味着该Crash log并非一个真正的Crash,它仅仅只是包含了整个系统某一时刻的运行状态。通常可以通过同时按Home键和音量键,可能由于用户不小心触发
0xbad22222 当VOIP程序在后台太过频繁的激活时,系统可能会终止此类程序
0x8badf00d 这个前面已经介绍了,程序启动或者恢复时间过长被watch dog终止
0xc00010ff 程序执行大量耗费CPU和GPU的运算,导致设备过热,触发系统过热保护被系统终止
0xdead10cc 程序退到后台时还占用系统资源,如通讯录被系统终止
0xdeadfa11 前面也提到过,程序无响应用户强制关闭

三、获取Crash的途径

1、本机

通过xCode连接测试机器,直接在Device中即可读取到该机器上发生的所有Crash log。

2、itunes connect

通过itunes connect后台获取到用户上报的Crash日志。

3、第三方的Crash收集系统

有很多优秀的第三方Crash收集系统大大的方便了我们收集Crash,甚至还带了符号化Crash日志的功能。比较常用的有CrashlyticsFlurry等。

四、附录

Apple官方文档:Understanding and Analyzing iOS Application Crash Reports

Technical Note TN2123 CrashReporter

https://developer.apple.com/library/ios/qa/qa1592/_index.html

WWDC视频:  Understanding Crash Reports on iPhone OS

Crash日志记录的时候是将Crash发生时刻,函数的调用栈,以及线程等信息写入文件。一般都是直接写的16进制地址,如果不经过符号化的话,基本上很难获取到有用信息,下一篇我们将聊一聊Crash日志的符号化,通俗点讲就是让Crash日志变成我们可读的格式。

相关文章推荐

iOS Crash文件的解析(转)

本文转载自“一片枫叶”http://www.cnblogs.com/smileEvday/p/Crash1.html iOS Crash文件的解析 开发程序的过程中不管我们已经如何小心,总是会在不经意...
  • hherima
  • hherima
  • 2015年11月27日 18:49
  • 807

iOS Crash文件的解析工具(四)开源库 QuincyKit + KSCrash

我们知道,iOS bug定位是极看重crash log的,目前网上提供了不少crash log收集与管理服务,较有名的有Crashlytics, Flurry, 友盟,可能大部分人也就是使用这个。我这...

iOS友盟崩溃地址解析 通过dSYM文件分析定位线上 APP crash问题

有很多问题是在开发测试过程中无法遇到和重现的,这就需要统计线上的崩溃信息进行定位。什么是 dSYMXcode编译项目后,我们会看到一个同名的 dSYM 文件,dSYM 是保存 16 进制函数地址映射信...

UI Automation for IOS及Crash .dSYM 文件的解析。

最近用过 Xcode 中的 Instruments的Automation工具做了一些 IOS 的端的测试,主要用到开源的github 中开源的monkey脚本。 关于IOS for Automatio...

iOS crash log 解析 symbol address = stack address - slide 运行时获取slide的api 利用dwarfdump从dsym文件中得到symbol

概述: 为什么 crash log 内 Exception Backtrace 部分的地址(stack address)不能从 dsym 文件中查出对应的代码? 因为 ASLR(Address spa...

iOS Crash文件的解析(一)

原文发布于http://www.cnblogs.com/smileEvday/p/Crash1.html 开发程序的过程中不管我们已经如何小心,总是会在不经意间遇到程序闪退。脑补一下当你在一群人...

iOS Crash文件的解析

发程序的过程中不管我们已经如何小心,总是会在不经意间遇到程序闪退。脑补一下当你在一群人面前自信的拿着你的App做功能预演的时候,流畅的操作被无情地Crash打断。联想起老罗在发布Smartisan O...

iOS - 命令行工具解析Crash文件,dSYM文件进行符号化

序 在日常开发中,app难免会发生崩溃。简单的崩溃还好说,复杂的崩溃就需要我们通过解析Crash文件来分析了,解析Crash文件在iOS开发中是...

iOS学习笔记58-iOS- 全方位解析.crash文件崩溃报告

1、前言 想来每个iOS攻城狮,都免不了要接触.crash文件那么什么是.crash文件?iOS app的所有崩溃记录都会记录在设备上,所以对于和我一样没有集成让用户发送崩溃报告功能的iOS开发...

ios crash文件分析

IOS程序在真机运行程序出现crash状况时,机器会自动产生log文件,它包含了在程序crash之前的运行逻辑,分析carsh文件,有效的解决程序在真机上的问题,保证程序良好的稳定性,但是这个cras...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS: Crash文件解析
举报原因:
原因补充:

(最多只允许输入30个字)