iOS crash debug

1、crash文件的获取

设备与电脑上的iTunes Store同步后,会将崩溃日志保存在电脑上。根据电脑操作系统的不同,崩溃日志将保存在以下位置:
Mac OS X:~/Library/Logs/CrashReporter/MobileDevice/
Windows XP: C:Documents and SettingsApplication DataApple ComputerLogsCrashReporterMobileDevice
Windows Vista or 7: C:UsersAppDataRoamingApple ComputerLogsCrashReporterMobileDevice
当用户抱怨闪退时,你可以要求他让设备与iTunes同步,并根据操作系统的不同,到上述位置把崩溃日志下载下来,然后通过电子邮件发送给你。

2、crash文件的符号化

将十六进制地址转化成方法名称和行数的过程称之为Symbolication(符号化)。
(1) 利用Xcode的Devices and Simulators
只要把.crash文件拉到Xcode的device log里面,然后几秒钟后就会符号化。但是这里有个前提,就是这个发生crash的版本包必须是你自己的Xcode里面Archive出来的(这个是苹果自带的方法,会自动检测是否含有匹配的.dSYM文件和应用二进制文件)。

那如果要是在新电脑上也想符号化怎么办?只有相匹配的.dSYM文件和应用二进制文件就可以符号化。必需完全匹配才行。否则,日志将无法被完全符号化。应用的二进制文件就是打的包得.ipa后缀改成.zip,然后解压后里面有个.app文件就是应用的二进制文件。将.dSYM文件与.app文件 和.crash文件放一个目录下,然后再用deviceLog方法就可以符号化了。

(2) 利用Symbolicatecrash命令行工具
如果想查看.crash文件的庐山真面目,需要找出在上传应用时所发送的.app和.dSYM文件,切记每次发送新版本都要保留这两个文件,不然没有办法解析Crash Log的。可以先把这两个文件拷贝到桌面的某一个文件夹中,然后把.crash的文件也拷贝的同一个文件夹下。

这一解析过程需要使用Symbolicatecrash来完成,首先要找到Symbolicatecrash文件,xcode5.0在 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/ Symbolicatecrash文件独立于Xcode,可以拷到刚才放crash log的文件夹中使用,在开始解析之前需要先进行一些校验:

  1. 查看xx.app文件的uuid的方法,在命令行中输入:
    dwarfdump --uuid xxx.app/xxx (xxx工程名)

  2. 查看xx.app.dSYM文件的uuid的方法,在命令行输入:
    dwarfdump --uuid xxx.app.dSYM (xxx工程名)

3.查看.crash的uuid,位于crash日志中的Binary Images:中的第一行。如:armv7s <13760bde0d073f1eb4d596c3df753f4b>
只有三者的uuid相同才能解析.crash文件,然后在命令行输入:
./symbolicatecrash xxx.crash xxx.app.dSYM > test.log
这样可以将.crash日志转换成test.log,test.log即可读的函数文件。输入上述命令可能会出现Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 53.这个错误。如果出现上述错误,输入命令:export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer,然后继续执行./symbolicatecrash xxx.crash xxx.app.dSYM > test.log可以成功

3、crash log分析

Incident Identifier:当前crash的 id,可以区分不同的crash事件
CrashReporter Key: 当前设备的id,可以判断crash在某一设备上出现的频率
Hardware Model: 设备型号
Process: 当前应用的名称,后面中括号中为当前的应用在系统中的进程id
Path: 当前应用在设备中的路径
Identifier:
bundle idVersion: 应用版本号
Code Type: (还不清楚)
Date/Time: crash事件 时间
OS Version: 当前系统版本
Exception Type: 异常类型
Exception Codes: 异常出错的代码
Triggered by Thread: 在某一个线程出了问题导致crash,Thread 0 为主线程、其它的都为子线程
Last Exception Backtrace: 最后异常回溯,一般根据这个代码就能找到crash的具体问题

(1) Crash Log分类

如果所有的CrashLog已经被采集下来了,为了避免重复解决相同的bug,这个时候就需要所有的CrashLog分类,通过上面已有的信息,就可以对CrashLog做如下的分类控制:

  1. 通过设备id查找当前设备上出现的crash(通过CrashReporter Key);
  2. 查找所有在iphone5上出现的crash(通过Hardware Model);
  3. 查找所有在ios7.1上出现的crash(通过OS Version);
  4. 查找所有在应用1.0版本上出现的crash(通过 Version);
  5. 查看在某一个时间段内出现的crash(通过 Date/Time);
  6. 查找所有因为内存问题出现的crash (通过 Exception Type);
  7. 查找在主线程出现crash的问题(Triggered by Thread == 0);
  8. 对上述条件的组合查询;
(2) 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
除零错误会抛出此类异常

(3) Exception Code

0xbaaaaaad错误码:用户按住Home键和音量键,获取当前内存状态,不代表崩溃。
0xbad22222错误码:当VOIP程序在后台太过频繁的激活时被iOS干掉。
0x8badf00d错误码:程序启动或者恢复时间过长被watch dog终止,意为“ate bad food”。
0xc00010ff错误码:程序执行大量耗费CPU和GPU的运算,导致设备过热,触发系统过热保护被系统终止,意为“cool off”。
0xdead10cc错误码:因为在后台时仍然占据系统资源(比如通讯录)被干掉,意为“dead lock”。
0xdeadfa11错误码:用户强制退出,意为“dead fall”。

你可能感兴趣的:(iOS crash debug)