iOS Crash闪退信息捕获工具类

来源:互联网 发布:php怎么链接数据库 编辑:程序博客网 时间:2024/04/28 02:07

        IOS SDK中提供了一个现成的函数 NSSetUncaughtExceptionHandler 用来做异常处理,但功能非常有限,而引起崩溃的大多数原因如:内存访问错误,重复释放等错误捕获不到,因为这些异常抛出的是Signal,所以必须要专门做Signal处理。工具类的实现源码如下:

头文件

#import <Foundation/Foundation.h>extern NSString *const UncaughtExceptionHandlerSignalKey;extern NSString *const SingalExceptionHandlerAddressesKey;extern NSString *const ExceptionHandlerAddressesKey;@interface ExceptionHandler : NSObject+ (void)installExceptionHandler;+ (NSArray *)backtrace;@end

实现文件

#import "ExceptionHandler.h"#include <libkern/OSAtomic.h>#include <execinfo.h>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


0 0