iOS异常捕获和处理

2013年4月份整理的代码,仅作记录:
 

//先宏定义
//发布和未发布状态的日志切换
#ifdef DEBUG
    //异常栈开关
    #define STACK_KEY YES
    //日志重定向开关
    #define STDERR_KEY NO
    //调试日志
    #define DebugLog(format,...)    NSLog(@"{%s,%d}" format, __FUNCTION__,__LINE__,##__VA_ARGS__)
    //异常栈日志
    #define StackLog(format,...)    NSLog(@"{%s,%d}" format, __FUNCTION__,__LINE__,##__VA_ARGS__)
    //输出日至
    #define DLOG(...)   NSLog(__VA_ARGS__)
    //输出详细日志
    #define DLOGEXT(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
    //输出调用
    #define DLOGCALL DLOG(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd))
    //输出方法
    #define DLOGMETHODNSLog(@"[%s] %@", class_getName([self class]), NSStringFromSelector(_cmd));
    //输出点
    #define DLOGPOINT(p)NSLog(@"%f,%f", p.x, p.y);
    //输出大小
    #define DLOGSIZE(p)NSLog(@"%f,%f", p.width, p.height);
    //输出矩形
    #define DLOGRECT(p)NSLog(@"%f,%f %f,%f", p.origin.x, p.origin.y, p.size.width, p.size.height);
#else
    #define STACK_KEY YES
    #define STDERR_KEY YES
    #define DebugLog(format,...)
    #define StackLog(format,...)
    #define DLOG(...)
    #define DLOGEXT(...)
    #define DLOGCALL
    #define DLOGMETHOD
    #define DLOGPOINT(p)
    #define DLOGSIZE(p)
    #define DLOGRECT(p)
#endif
 

AppDelegate的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中加入以下代码:
 
 
 
    //设置异常日志文件
    if (STDERR_KEY) {
         NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentDir = [paths objectAtIndex:0];
        NSString *decyStr = [NSString stringWithFormat:@"decrypt.log"];
        NSString *logPath = [documentDir stringByAppendingPathComponent:decyStr];
        freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding], "w+", stderr);
    }
   
    //异常栈
    if (STACK_KEY) {
        //设置处理异常的Handler
        NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
       
        //signal处理机制
        struct sigaction mySigAction;
        mySigAction.sa_sigaction = stacktrace;
        mySigAction.sa_flags = SA_SIGINFO;
       
        sigemptyset(&mySigAction.sa_mask);
        sigaction(SIGQUIT, &mySigAction, NULL);
        sigaction(SIGILL , &mySigAction, NULL);
        sigaction(SIGTRAP, &mySigAction, NULL);
        sigaction(SIGABRT, &mySigAction, NULL);
        sigaction(SIGEMT , &mySigAction, NULL);
        sigaction(SIGFPE , &mySigAction, NULL);
        sigaction(SIGBUS , &mySigAction, NULL);
        sigaction(SIGSEGV, &mySigAction, NULL);
        sigaction(SIGSYS , &mySigAction, NULL);
        sigaction(SIGPIPE, &mySigAction, NULL);
        sigaction(SIGALRM, &mySigAction, NULL);
        sigaction(SIGXCPU, &mySigAction, NULL);
        sigaction(SIGXFSZ, &mySigAction, NULL);
    }
 
 

并在同个页面中实现以下方法:
 
//异常处理
#pragma mark - DebugMethods
void UncaughtExceptionHandler(NSException *exception) {
    StackLog(@"receive a UncaughtExceptionHandler");
    NSArray *arr = [exception callStackSymbols];
    NSString *reason = [exception reason];
    NSString *name = [exception name];
    NSString *syserror = [NSStringstringWithFormat:@"UncaughtExceptionHandlerName:%@\nUncaughtExceptionHandlerReason:%@\nUncaughtExceptionHandlerArray:%@",name, reason, arr];
    StackLog(@"%@", syserror);
}
void stacktrace(int sig, siginfo_t *info, void *context)
{
    
    NSMutableString * mstr = [[[NSMutableStringalloc] initWithCapacity:0] autorelease];
    [mstr appendString:@"Stack:\n"];
    StackLog(@"sig %d",sig);
    
    void* callstack[128];
    int i, frameCount = backtrace(callstack, 128);
    char** strs = backtrace_symbols(callstack, frameCount);
    for (i = 0; i < frameCount; ++i) {
        [mstr appendFormat:@"%s\n", strs[i]];
    }
    
    StackLog(@"Stack Trace:\r\n%@", mstr);
}

posted @ 2019-01-03 16:21  小、  阅读(596)  评论(0编辑  收藏  举报