关于iOS的异常类型(EXC_BAD_ACCESS)学习

一、概述

“异常”这个词在“崩溃日志”语境下更多与“Mach 异常”(以 EXC_ 为前缀)和 UNIX 信号(如: SIGSEGV, SIGBUS等)相关。

1、UNIX信号,详见Unix_signal

常见的有:

  • SIGSEGV,访问无效的内存地址。
    地址存在,但是应用程序无法访问。

  • SIGABRT,程序崩溃。
    由 C函数 abort() 初始化。通常意味着系统检测到某些事务出错,例如 assert() 或者 NSAssert() 校验失败。

  • SIGBUS,访问无效的内存地址。
    地址不存在,或对齐无效。(The address does not exist, or the alignment is invalid.)

2、Mach 异常,详见 Mach-EXC (sys/osfmk/mach/exception_types.h)的源码文件。

常见的有:

  • EXC_BAD_ACCESS,错误内存访问
  • EXC_CRASH,异常跳出
  • SIGBUS,访问无效的内存地址。地址不存在,或对齐无效。
  • EXC_BREAKPOINT,跟踪/断点捕获
    通用与 SIGTRAP 相关联。可以由你自己的代码或者 NSExceptions 抛出时触发。
  • EXC_GUARD,违反了受保护资源的防护(Violated Guarded Resource Protection)
    由违背受保护资源防护触发,例如‘某些文件描述符’。
  • EXC_BAD_INSTRUCTION,非法指令,通常与特定非法或未定义指令/操作数相关。
  • EXC_RESOURCE,资源限制,应用由于达到资源消耗限制而退出。
  • 00000020,十六进制异常类型,非 'OS Kernel' 异常。

二、EXC_BAD_ACCESS

1、概述

开发中经常遇到EXC_BAD_ACCESS的崩溃信息,如果使用lldb的bt打印堆栈,能对位具体代码是比较容易解决问题的。但也会遇到一些死在系统库,莫名错误引起的,就很难定位和排查问题。
它到底是什么问题引起的呢?具体要怎么分析?从哪里入手分析呢?带着疑问,找资料,学习汇总,以便查阅。

苹果官方给出EXC_BAD_ACCESS的解释是,其是一个能被捕获语言异常,是关于内存访问方面的错误。
the EXC_BAD_ACCESS exception rules out that a crash is due to an uncaught language exception.
The crash is due to a memory access issue.

  • EXC_BAD_ACCESS的堆栈错误
    thread #39, queue = 'com.apple.root.default-qos', stop reason = EXC_BAD_ACCESS (code=2, address=0x13001c040)

  • EXC_BAD_ACCESS的崩溃日志

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000011

我们发现EXC_BAD_ACCESS(code=2, address=0x13001c040)错误信息给出两个字段,一个是address代表出错的内存地址;code是啥意思呢?

2、EXC_BAD_ACCESS常见的错误子类型

上面错误中这个code代表的是异常的子类型,具体是啥呢?常见有以下几种,详见源码

  • KERN_INVALID_ADDRESS == 1
    The crashed thread accessed unmapped memory, either by accessing data or an instruction fetch.
    由访问未映射内存的线程引起的,它可能由数据访问或指令提取触发。

    访问已经被 ARC 释放(导致地址变为不可访问)的对象。如果是这个情况,你通常可以在崩溃日志中的 “Backtrace” 顶部附近看到 objc_release

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x6d783f44
  • KERN_PROTECTION_FAILURE == 2
    The crashed thread tried to use a valid memory address that’s protected. Some types of protected memory include read-only memory regions, or nonexecutable memory regions.
    访问受保护的内存地址,例如制度内存区域 或者 不可执行的内存区域。

经常导致的原因就是访问某些尚未初始化的对象(SIGBUS) ,如下

Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000011
  • KERN_MEMORY_ERROR
    The crashed thread tried to access memory that couldn’t return data at that moment, such as a memory-mapped file that became unavailable.
    访问无法返回数据的内存区域,例如无效非法的文件。

3、如何定位EXC_BAD_ACCESS更多信息

  • 在debug运行是打开内存管理的Zombie Objects可以获得有效的调试信息。

三、EXC_CRASH(异常跳出)

  • 它通常发生在对象接收到未实现的消息时,如 Xcode 调试器中显示的 “unrecognized selector sent to instance 0x6a33840”。

  • 另一个常见的“EXC_CRASH”情况是关于“应用扩展(App Extensions)”。
    应用扩展如果“花了太长时间来初始化”则会被系统终止。在这种情况下,异常子类型显示为 LAUNCH_HANG

Exception Type: EXC_CRASH (SIGABRT)
Exception Subtype: LAUNCH_HANG
Exception Message: The extension took too much time to initialize

四、EXC_RESOURCE

“EXC_RESOURCE”意思是进程“达到资源消耗上限”。通常,当你的应用在一定时间内持续超出限制时会被触发。
这个异常包含“Exception Subtype”以帮助理解实际情况:

  • CPU - 限制为 50%,时间不超过 180秒。
  • WAKEUPS - 表示线程每秒唤醒次数太多。限制为 150次/每秒, 时间不超过 300秒。
  • MEMORY - 没有相关文档描述限制信息。
Exception Type: EXC_RESOURCE
Exception Subtype: CPU
Exception Message: (Limit 50%) Observed 85% over 180 secs
---
Exception Type: EXC_RESOURCE
Exception Subtype: WAKEUPS
Exception Message: (Limit 150/sec) Observed 206/sec over 300 secs
---
Exception Type: EXC_RESOURCE
Exception Subtype: MEMORY
Exception Message: Crossed High Water Mark

五、00000020

与“EXC_”异常不同,这个“异常类型”实际上不能告诉你任何信息。取而代之,你应该查看“异常代码”获取更多详情。

  • 0x8badf00d(读作 ate bad food)- 表示由于 watchdog 出现超时而导致应用被操作系统终止。通常意味着应用程序花了太长时间启动、关闭或者响应系统事件。一个非常典型的情况是“在主线程上做同步网络请求”。
  • 0xbaaaaaad(读作 “plooookhy”)- 表示日志是整个系统的堆栈,而不是崩溃报告。
  • 0xc00010ff(读作 cool off(冷静))- 表示应用程序被系统关闭以响应热事件。
  • 0xbad22222 - 表示操作系统终止了一个VoIP程序,因为它过于频繁的执行恢复。
  • 0xdead10cc(读作 dead lock(死锁))- 表示应用在后台运行时保持了系统资源。
  • 0xdeadfa11(读作 deadfall)- 表示应用被用户强制关闭了。强制关闭发生于用户先按下电源键直到“滑动来关机”出现然后按住主屏幕按钮。

参考

在exc_bad_access中,代码=1和代码=2有什么区别?
Diagnosing Issues Using Crash Reports and Device Logs
Understanding the Exception Types in a Crash Report
Investigating Memory Access Crashes
译:理解 iOS 异常类型
iOS Abort问题系统性解决方案

你可能感兴趣的:(关于iOS的异常类型(EXC_BAD_ACCESS)学习)