iOS中的崩溃主要分为两种:oc语言抛出的异常和Mach层的异常。
 
	上图可以看到对于这两种异常都可以注册回调函数进行检测。在异常抛出时,将调用堆栈的信息记录下来,供之后异常分析。
Objective-C Exception 1 2 3 4 void NSSetUncaughtExceptionHandler(NSUncaughtExceptionHandler *);  description: Changes the top-level error handler. Sets the top-level error-handling function where you can perform last-minute logging before the program terminates. 
 
1 2 3 4 5 6 7 8 - (void)installOCExceptionHandle { 	NSSetUncaughtExceptionHandler(&oc_exception_handler); } static void oc_exception_handler(NSException *exception) { 	NSLog(@"%@", exception);     NSLog(@"%@", [exception callStackSymbols]); } 
 
	apple文档中描述中可以看到top-level的handler只能有一个,即多次通过该函数注册handler会有覆盖现象。
	覆盖的问题的解决方案是将原本的handler函数赋值给一个全局变量,在自己的handler函数末尾再调用这个函数。这样就能使原本的handler不失效。
1 2 3 4 5 6 7 8 9 10 11 static  void  (*origin_exception_handler) (NSException  *);- (void )installOCExceptionHandle {     orgin_exception_handler = NSGetUncaughtExceptionHandler (); 	NSSetUncaughtExceptionHandler (&oc_exception_handler); } static  void  oc_exception_handler(NSException  *exception) {	NSLog (@"%@" , exception);     NSLog (@"%@" , [exception callStackSymbols]);     (*origin_exception_handler)(exception); } 
 
XNU Exception 	xnu的异常捕捉同oc的异常捕捉同理,都需要注册一个handler函数。额外注意的一点,在DEBUG模式下xcode会优先捕捉异常,所以不能连着xcode进行调试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 static  void  origin_signal_action(int  signal, siginfo_t* info, void  context);- (void )installXNUExceptionHandler { 	     struct  sigaction old_action;     sigaction(SIGABRT, NULL , &old_action);     if  (old_action.sa_flags & SA_SIGINFO) {         origin_signal_action = old_action.sa_sigaction;     }          struct  sigaction action;     action.sa_sigaction = signal_exception_handler;     action.sa_flags = SA_NODEFER | SA_SIGINFO;     sigemptyset(&action.sa_mask);     sigaction(SIGABRT, &action, 0 ); } static  void  signal_exception_handler(int  signal, siginfo_t* info, void  context) {    NSMutableString  *mstr = [NSMutableString  new];     void  *callstack[120 ];     int  i, frames = backtrace(callstack, 120 );     char ** strs = backtrace_symbols(callstack, frames);     for  (i = 0 ; i < frames; i++) {         [mstr appendString:@"%s\n" , strs[i]]     } 	            origin_signal_action(signal, info, context); }