ios中的奇怪崩溃Signal和EXC_BAD_ACCESS错误分析

什么是Signal

在计算机科学中,信号(英语:Signals)是Unix、类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式。它是一种异步的通知机制,用来提醒进程一个事件已经发生。当一个信号发送给一个进程,操作系统中断了进程正常的控制流程,此时,任何非原子操作都将被中断。如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数。

在iOS中就是未被捕获的Objective-C异常(NSException),导致程序向自身发送了SIGABRT信号而崩溃。

Signal信号的类型

SIGABRT–程序中止命令中止信号
SIGALRM–程序超时信号
SIGFPE–程序浮点异常信号
SIGILL–程序非法指令信号
SIGHUP–程序终端中止信号
SIGINT–程序键盘中断信号
SIGKILL–程序结束接收中止信号
SIGTERM–程序kill中止信号
SIGSTOP–程序键盘中止信号
SIGSEGV–程序无效内存中止信号
SIGBUS–程序内存字节未对齐中止信号
SIGPIPE–程序Socket发送失败中止信号
iOS异常捕获这篇文章中有对各种信号的解释。

SIGABRT

就crash而言,SIGABRT是一个比较好解决的,因为他是一个可掌控的crash。App会在一个目的地终止,因为系统意识到app做了一些他不能支持的事情。

通常, SIGABRT 异常是由于某个对象接收到未实现的消息引起的。 或者,用简单的话说,在某个对象上调用了不存在的方法。

SIGSEGV

SIGSEGV程序无效内存中止信号,一般是表示内存不合法,

SIGBUS

SIGBUS程序内存字节未对齐中止信号,

截取Signal和Exception从容的崩溃

一个不错的崩溃远吗,集成到项目中能捕获崩溃信息 DSSignalHandlerDemo
这是一个防止奔溃的源码,可以使一些原本会奔溃的操作弹出UIAlertView。里面写了两种信号量的崩溃:SIGSEGV、SIGABRT,还有一些信号大家可以写上去提个PR给我。

下图为源码的运行图,其中Signal中的Signal(EGV)第一次点击的时候能弹出alert,如果第二次点击就没有崩溃和alert,感觉像卡死一样。

而Signal(BRT)中的这种信号错误多次点击也是没有问题的还是能继续下去。个人猜测可能是SIGSEGV这种信号错误会导致了整个进程挂了。

注意:测试的时候如果测试Signal类型的崩溃,不要在xcode下的debug模式进行测试。因为系统的debug会优先去拦截。应该build好应用之后直接点击运行app进行测试。

ios中的奇怪崩溃Signal和EXC_BAD_ACCESS错误分析