iOS Crash閃退資訊捕獲工具類
IOS SDK中提供了一個現成的函數 NSSetUncaughtExceptionHandler 用來做異常處理,但功能非常有限,而引起崩潰的大多數原因如:記憶體訪問錯誤,重複釋放等錯誤捕獲不到,因為這些異常拋出的是Signal,所以必須要專門做Signal處理。工具類的實現源碼如下:
標頭檔
#import extern NSString *const UncaughtExceptionHandlerSignalKey;extern NSString *const SingalExceptionHandlerAddressesKey;extern NSString *const ExceptionHandlerAddressesKey;@interface ExceptionHandler : NSObject+ (void)installExceptionHandler;+ (NSArray *)backtrace;@end
實現檔案
#import "ExceptionHandler.h"#include #include NSString *const UncaughtExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey";NSString *const SingalExceptionHandlerAddressesKey = @"SingalExceptionHandlerAddressesKey";NSString *const ExceptionHandlerAddressesKey = @"ExceptionHandlerAddressesKey";const int32_t _uncaughtExceptionMaximum = 20;// 系統訊號截獲處理方法void signalHandler(int signal);// 異常截獲處理方法void exceptionHandler(NSException *exception);void signalHandler(int signal){ volatile int32_t _uncaughtExceptionCount = 0; int32_t exceptionCount = OSAtomicIncrement32(&_uncaughtExceptionCount); // 如果太多不用處理 if (exceptionCount > _uncaughtExceptionMaximum) { return; } // 擷取資訊 NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:signal] forKey:UncaughtExceptionHandlerSignalKey]; NSArray *callStack = [ExceptionHandler backtrace]; [userInfo setObject:callStack forKey:SingalExceptionHandlerAddressesKey]; // 現在就可以儲存資訊到本地[] }void exceptionHandler(NSException *exception){ volatile int32_t _uncaughtExceptionCount = 0; int32_t exceptionCount = OSAtomicIncrement32(&_uncaughtExceptionCount); // 如果太多不用處理 if (exceptionCount > _uncaughtExceptionMaximum) { return; } NSArray *callStack = [ExceptionHandler backtrace]; NSMutableDictionary *userInfo =[NSMutableDictionary dictionaryWithDictionary:[exception userInfo]]; [userInfo setObject:callStack forKey:ExceptionHandlerAddressesKey]; NSLog(@"Exception Invoked: %@", userInfo); // 現在就可以儲存資訊到本地[] }@implementation ExceptionHandler//擷取呼叫堆疊+ (NSArray *)backtrace{ void* callstack[128]; int frames = backtrace(callstack, 128); char **strs = backtrace_symbols(callstack,frames); NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames]; for (int i=0;i<frames;i++) { [backtrace addObject:[NSString stringWithUTF8String:strs[i]]]; } free(strs); return backtrace;}// 註冊崩潰攔截+ (void)installExceptionHandler{ NSSetUncaughtExceptionHandler(&exceptionHandler); signal(SIGHUP, signalHandler); signal(SIGINT, signalHandler); signal(SIGQUIT, signalHandler); signal(SIGABRT, signalHandler); signal(SIGILL, signalHandler); signal(SIGSEGV, signalHandler); signal(SIGFPE, signalHandler); signal(SIGBUS, signalHandler); signal(SIGPIPE, signalHandler);}@end