iOS应用的crash日志的分析基础 数据库
Outline
如何得到crash日志
如何解析crash日志
如何分析crash日志
1. iOS策略相关
2. 常见错误标识
3. 代码bug
1、如何得到crash日志
当一个iOS应用程序崩溃时,系统会建立一份crash日志保存在设备上。这份crash日志记录着应用程序崩溃时的信息,一般包含着每一个执行线程的栈调用信息(低内存闪退日志例外),对于开发人员定位问题颇有帮助。
若是设备就在身边,能够链接设备,打开Xcode - Window - Organizer,在左侧面板中选择Device Logs(能够选择具体设备的Device Logs或者Library下全部设备的Device Logs),而后根据时间排序查看设备上的crash日志。这是开发、测试阶段最常常采用的方式。
若是应用程序已经提交到App Store发布,用户已经安装使用了,那么开发者能够经过iTunes Connect(Manage Your Applications - View Details - Crash Reports)获取用户的crash日志。不过这并非100%有效的,并且大多数开发者并不依赖于此,由于这须要用户设备赞成上传相关信息,详情可参见iOS: Providing Apple with diagnostics and usage information摘要。
考虑到并非全部iPhone用户都容许自动发送诊断报告(crash日志),并且对于部分提交到Apple得crash日志,开发者还须要手动去拉取,而后找到对应的符号文件进行解析——这是一件很繁琐的事情。因此实际项目开发中,一般接入现有的crash收集工具(参考1,参考2),或者本身编写一个进行自动化收集、解析和统计汇总。
2、如何解析crash日志
当得到一份crash日志时,咱们须要将初始展现的十六进制地址等原始信息映射为源代码级别的方法名称和代码行数,使其对开发人员可读。这个过程称为符号化解析。要成功地符号化解析一份crash日志,咱们须要有对应的应用程序二进制文件以及符号(.dSYM)文件。
若是处于开发调试阶段,一般Xcode都能匹配到crash日志对应的二进制文件和符号文件,因此可以帮咱们自动解析。
若是处于测试阶段,测试人员已经安装了不一样的版本(好比alpha、beta版本),那么须要保存好对应版本的二进制文件和符号文件,以便在应用程序崩溃时对crash日志进行解析。对于这种场景下产生的crash日志,只须要将.crash文件、.app文件和.dSYM文件三者放在同一个目录下,而后将.crash文件拖放到Xcode - Window - Organizer中左侧面板Library下的Device Logs中,便可进行解析。
若是要提交发布,那么咱们一般会先执行Clean,再Build,最后经过Product - Archive来打包。这样,Xcode会将二进制文件和符号文件归档在一块儿,能够经过Organizer中的Archives进行浏览。
这里是一份关于如何解析crash日志的讨论:http://stackoverflow.com/questions/1460892/symbolicating-iphone-app-crash-reports 。
3、如何分析crash日志
在分析一份crash日志以前,若是开发人员对于常见的错误类型有所了解,那定是极好的。
crash日志的产生来源于两种问题:违反iOS策略被干掉,以及自身的代码bug。
1. iOS策略
1.1 低内存闪退
前面提到大多数crash日志都包含着执行线程的栈调用信息,可是低内存闪退日志除外,这里就先看看低内存闪退日志是什么样的。
咱们使用Xcode 5和iOS 7的设备模拟一次低内存闪退,而后经过Organizer查看产生的crash日志,能够发现Process和Type都为Unknown:
而具体的日志内容以下:
第一部分是崩溃信息,包括识别标识、软硬件信息和时间信息等。
第二部分是内存页分配信息,以及当前占用内存最多的进程,上图中为crashTypeDemo。
第三部分是具体的进程列表,描述着每一个进程使用内存的状况以及当前状态。在较早的版本中能够在某些进程后面看到“jettisoned”字样,代表这些进程使用过多内存被终止了,而如今咱们看到的是“vm-pageshortage”字样。
当iOS检测到内存太低时,它(的VM系统)会发出低内存警告通知,尝试回收一些内存;若是状况没有获得足够的改善,iOS会终止后台应用以回收更多内存;最后,若是内存仍是不足,那么正在运行的应用可能会被终止掉。
因此,咱们的应用应该合理地响应系统抛出来的低内存警告通知,对一些缓存数据和可从新建立的对象进行释放,同时要避免出现内存泄露等问题。
低内存闪退是由iOS策略决定终止应用程序运行的,一样基于iOS策略的还有Watchdog超时和用户强制退出。
1.2 Watchdog超时
Apple的iOS Developer Library网站上,QA1693文档中描述了Watchdog机制,包括生效场景和表现。若是咱们的应用程序对一些特定的UI事件(好比启动、挂起、恢复、结束)响应不及时,Watchdog会把咱们的应用程序干掉,并生成一份响应的crash报告。
这份crash报告的有趣之处在于异常代码:“0x8badf00d”,即“ate bad food”。
若是说特定的UI事件比较抽象,那么用代码来直接描述的话,对应的就是(建立一个工程时Xcode自动生成的)UIApplicationDelegate的几个方法:
因此当遇到Watchdog日志时,能够检查下上图几个方法是否有比较重的阻塞UI的动做。
QA1693举的例子是在主线程进行同步网络请求。若是咱们是在公司的Wifi环境下使用则一切顺利,但当应用程序发布出去面向很大范围的用户,在各类网络环境下运行,则不可避免地会出现一片Watchdog超时报告。
另外一种可能出现问题的场景就是数据量比较大的状况下进行的数据库版本迁移(一样是在主线程上),这也是促使我写这篇总结的一个直接因素。
1.3 用户强制退出
一看到“用户强制退出”,首先可能想到的双击Home键,而后关闭应用程序。不过这种场景是不会产生crash日志的,由于双击Home键后,全部的应用程序都处于后台状态,而iOS随时都有可能关闭后台进程,因此这种场景没有crash日志。
另外一种场景是用户同时按住电源键和Home键,让iPhone重启。这种场景会产生日志(仅验证过一次),但并不针对特定应用程序。
这里指的“用户强制退出”场景,是稍微比较复杂点的操做:先按住电源键,直到出现“滑动关机”的界面时,再按住Home键,这时候当前应用程序会被终止掉,而且产生一份相应事件的crash日志。
一般,用户应该是遇到应用程序卡死,而且影响到了iOS响应,才会进行这样的操做——不过感受这操做好高级,因此这样的crash日志应该比较少见。
2. 常见错误标识
2.1 Exception codes
上面“用户强制退出”的crash日志中的Exception Codes是“0xdeadfa11”,再上面“Watchdog超时”的crash日志中的Exception Codes是“0x8badf00d”,这些都是特有的Exception codes。
根据官方文档描述,至少有如下几种特定异常代码:
0x8badf00d错误码:Watchdog超时,意为“ate bad food”。
0xdeadfa11错误码:用户强制退出,意为“dead fall”。
0xbaaaaaad错误码:用户按住Home键和音量键,获取当前内存状态,不表明崩溃。
0xbad22222错误码:VoIP应用(由于太频繁?)被iOS干掉。
0xc00010ff错误码:由于太烫了被干掉,意为“cool off”。
0xdead10cc错误码:由于在后台时仍然占据系统资源(好比通信录)被干掉,意为“dead lock”。
2.2 Exception types
查看咱们的crash分析报告邮件,会发现最常常遇到的错误类型是SEGV(Segmentation Violation,段违例),代表内存操做不当,好比访问一个没有权限的内存地址。
当咱们收到SIGSEGV信号时,能够往如下几个方面考虑:
访问无效内存地址,好比访问Zombie对象;
尝试往只读区域写数据;
解引用空指针;
使用未初始化的指针;
栈溢出;
此外,还有其它常见信号:
SIGABRT:收到Abort信号,可能自身调用abort()或者收到外部发送过来的信号;
SIGBUS:总线错误。与SIGSEGV不一样的是,SIGSEGV访问的是无效地址(好比虚存映射不到物理内存),而SIGBUS访问的是有效地址,但总线访问异常(好比地址对齐问题);
SIGILL:尝试执行非法的指令,可能不被识别或者没有权限;
SIGFPE:Floating Point Error,数学计算相关问题(可能不限于浮点计算),好比除零操做;
SIGPIPE:管道另外一端没有进程接手数据;
3. 代码bug
此外,比较常见的崩溃基本都源于代码bug,好比数组越界、插空、多线程安全性、访问野指针、发送未实现的selector等。若是引入Core Data,则又有另一些常见问题,不过这是另外一个话题了。
数组
遇到这些bug时,都有比较清楚的错误缘由说明,好比“index 0 beyond bounds for empty array”等。须要稍微注意点的是多线程问题,当一时找不到解决思路时,不妨往多线程方面考虑下。缓存
//http://blog.csdn.net/jasonblog/article/details/19031517安全