iOS Crash日志字段解析

一、崩溃类型

  • 应用层存在bug ,即OC程序崩溃
    如 数组越界,selector方法没实现等抛出一系列NSException
    可通过系统API 注册UncaughtNSException处理函数捕捉,定位比较容易
  • 违反系统规则而出错
    如 watchdog超时,访问了不属于本进程的内存地址,用户强制退出,低内存终止等,系统抛出unix信号,但没有错误堆站信息
    可通过注册信号处理函数捕捉,但只能补拙有限的几种类型,定位较困难

二、Crash日志,几个重要的关键词

Crash日志信息
1、 进程信息

第一部分是闪退进程的相关信息:

  • Incident Identifier : 是崩溃报告的唯一标识符。
  • CrashReporter Key: 是与设备标识相对应的唯一键值。同一个设备上同一版本的App发生Crash时,该值都是一样的。虽然它不是真正的设备标识符,但也是一个非常有用的情报:如果你看到100个崩溃日志的CrashReporter Key值都是相同的,或者只有少数几个不同的CrashReport值,说明这不是一个普遍的问题,只发生在一个或少数几个设备上。
  • Hardware Model :标识设备类型。 如果很多崩溃日志都是来自相同的设备类型,说明应用只在某特定类型的设备上有问题。上面的日志里,崩溃日志产生的设备是iPhone 4s。
  • Process:代表Crash的进程名称,通常都是我们的App的名字, []里面是当时进程的ID
  • Path:崩溃文件的路径
  • Identifier:项目标识符,就是Bundle Id
  • Version:版本号
  • Code Type:当前App的CPU架构
  • Parent Process:当前进程的父进程,由于iOS中App通常都是单进程的,一般父进程都是launchd
2、基本信息

这部分给出了一些基本信息

  • Date/Time:闪退发生的日期
  • Launch Time:进入应用的时间
  • OS Version:设备的iOS版本
  • Report Version-Crash:日志的格式,目前基本上都是104,不同的version里面包含的字段可能有不同
3、异常信息
  • Exception Type:异常的类型。
  • Exception Codes :异常错误码
  • Termination Reason:闪退的原因,比如常见的数组越界啊,什么的。
  • Triggered by Thread:出现问题在哪个线程,这个比较重要,首先确定在哪个线程中出了问题,然后再去定位。
4、线程回溯

这部分提供应用中所有线程的回溯日志。
回溯是闪退发生时所有活动帧清单。它包含闪退发生时调用函数的清单. 线程调用的一些堆栈信息,压根看不懂,所有需要进行符号化处理。看下面这行日志:

05  UIKit       0x00000001943bd7fc 0x194343000 + 501756
 
它包括四列:
帧编号—— 此处是12。
二进制库的名称 ——此处是 UIKit
调用方法的地址 ——此处是 0x00000001943bd7fc
第四列分为两个子列,一个基本地址和一个偏移量。此处是0x194343000 + 501756, 第一个数字指向文件,第二个数字指向文件中的代码行。
5、 二进制映像(Binary Images)

这部分列出了当Crash发生时被装载进进程内存空间的依赖库或者模块


Binary Images

三、异常类型信息

1、Exception Type

1)EXC_BAD_ACCESS

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

  • SIGSEGV: 通常由于重复释放对象导致,这种类型在切换了ARC以后应该已经很少见到了。
  • SIGABRT: 收到Abort信号退出,SIGABRT 异常是由于某个对象接收到未实现的消息引起的。
    SEGV:(Segmentation Violation),代表无效内存地址,比如空指针,未初始化指针,栈溢出等;
  • SIGBUS:总线错误,与 SIGSEGV 不同的是,SIGSEGV 访问的是无效地址,而 SIGBUS 访问的是有效地址,但总线访问异常(如地址对齐问题)
  • SIGILL:尝试执行非法的指令,可能不被识别或者没有权限

2)EXC_BAD_INSTRUCTION

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

3)EXC_ARITHMETIC

除零错误会抛出此类异常

2、Exception Code 异常编码

前面日至的第3部分找到异常编码。有些编码比较常见。通常,异常编码以一些文字开头,紧接着是一个或多个十六进制值,此数值正是说明闪退根本性质的所在。 从这些编码中,可以区分出闪退是因为程序错误、非法内存访问或者是其他原因

常见的异常编码:

  • 0xbaaaaaad 此种类型的log意味着该Crash log并非一个真正的Crash,它仅仅只是包含了整个系统某一时刻的运行状态。通常可以通过同时按Home键和音量键,可能由于用户不小心触发
  • 0xbad22222 当VOIP(指在 IP 网络上使用 IP 协议以数据包的方式传输语音)程序在后台太过频繁的激活时,系统可能会终止此类程序
  • 0x8badf00d 程序启动或者恢复时间过长被watch dog终止,通常是应用花费太多时间而无法启动、终止或响应用系统事件
  • 0xc00010ff 程序执行大量耗费CPU和GPU的运算,导致设备过热,触发系统过热保护被系统终止
  • 0xdead10cc 程序退到后台时还占用系统资源,如通讯录被系统终止
  • 0xdeadfa11 程序无响应,用户强制关闭

(注意: 在后台任务列表中关闭已挂起的应用不会产生崩溃日志。 一旦应用被挂起,它何时被终止都是合理的。所以不会产生崩溃日志。)

四、低内存崩溃

低内存崩溃日志与其他类型的崩溃日志很不一样,它们不指向特定的文件和代码行。相反,它们画出了闪退时设备上的内存使用情况的图表
头部还是跟其他崩溃日志很像的: 提供了 Incident Identifier, CrashReporter Key, Hardware Model, OS Version等信息。

接下来部分是低内存崩溃日志特有的:

  • Free pages 指可用内存页数。每页大小约是4KB, 上面的日志中,可用内存约为3,872 KB (或者说 3.9 MB)。
  • Purgeable pages 是那部分可被清除或重用的内存。在上面的日志中,是0KB。
  • Largest process是闪退时使用大部分内存的应用名称,在上面的日志中,正是你的应用!
  • Processes显示了闪退时各进程列表,还包含内存使用量。包含进程名 (第一列), 进程唯一标识符(第二名), 进程使用的内存页数(第三列)。最后一列是每个应用的状态。通常,发生闪退的应用的状态是 frontmost。

你可能感兴趣的:(iOS Crash日志字段解析)