在Unix系统中标准的6种信号:
-
SIGABRT
: 表示程序异常终止,英语单词即Signal Abort
-
SIGFPE
: 表示浮点数异常错误,英语单词即Signal Floating Point Exception
-
SIGILL
: 表示无效指令/操作,英语单词即Signal Illegal
-
SIGINT
: 表示交互式注意请求发送到了程序引起了中断,英语单词Signal Interrupt
-
SIGSEGV
: 表示无效的内存访问,英语单词是Segmentation Violation
-
SIGTERM
: 表示终止请求发送到了程序引起了程序退出,英语单词是Signal Terminate
除了以上6中崩溃以外,还有一些在Unix或者Unix-Like系统的15种信号
在iOS中,信号指令定义的宏比较多
主动让程序崩溃
调起崩溃的函数在signal.h文件中,其中有raise()方法可以发起崩溃,例如:
#import <signal.h>
// 直接删掉此进程
raise(SIGKILL);
例如一张崩溃的日志截图
其中:
Exception Type 就是崩溃的类型,表示程序异常终止
Triggered by Thread 表示在主线程崩溃了,后面的数字是几,就是在那个线程崩溃的
崩溃异常信息捕获
通常在Objective-C中,我们可以用NSSetUncaughtExceptionHandler
来捕获异常信息,但是功能有限,所以我们可以使用signal(p1, p2);
来捕获ObjC/C/Swift
的异常
#import <signal.h>
#import <execinfo.h>
// 2.异常捕获的回调函数
void crashSignalHandler(int signal) {
NSlog(@"Application received signal: %d", signal);
// 以下获取堆栈信息
void* callstack[128];
int frames = backtrace(callstack, 128);
backtrace_symbols_fd(callstack, frames, crashLogFileDescriptor);
exit(signal);
}
// 1.注册捕获异常的种类
void registerUncaughtExceptionHandler() {
signal(SIGABRT, crashSignalHandler);
signal(SIGILL, crashSignalHandler);
signal(SIGSEGV, crashSignalHandler);
signal(SIGFPE, crashSignalHandler);
signal(SIGBUS, crashSignalHandler);
signal(SIGPIPE, crashSignalHandler);
}
然后就能捕获注册的这些异常类别,你也可以增加更多的异常类别的捕获
文档1:
http://devmonologue.com/ios/implementing-crash-reporting-for-ios/ 文档2:
http://devmonologue.com/ios/implementing-crash-reporting-for-ios/
Bad Memory Access [EXC_BAD_ACCESS // SIGSEGV // SIGBUS]
进程尝试去访问一个无效的内存,或者说,进程尝试去访问一个受保护等级的区域内存,例如:往read-only内存写入数据。
Abnormal Exit [EXC_CRASH // SIGABRT]
进程异常退出。大部分通常的引起此崩溃的原因是由于未捕获到Objective-C/C++的异常而引起系统调用abort()函数。
App Extensions可能会引发此崩溃,原因是可能由于初始化时间太长导致的。如果遇到LAUNCH_HANG
的子类型表示启动时进程被悬停了。