美文网首页
IOS程序异常捕获

IOS程序异常捕获

作者: Zzzzzeng | 来源:发表于2016-10-31 23:28 被阅读0次

    .h

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    @interface UncaughtExceptionHandler : NSObject
    { 
        BOOL dismissed;
    }
    +(void) InstallUncaughtExceptionHandler;
    @end
    

    .m

    #import "UncaughtExceptionHandler.h"
    #include <libkern/OSAtomic.h>
    #include <execinfo.h>
    NSString * const UncaughtExceptionHandlerSignalExceptionName = @"UncaughtExceptionHandlerSignalExceptionName";
    NSString * const UncaughtExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey";
    NSString * const UncaughtExceptionHandlerAddressesKey = @"UncaughtExceptionHandlerAddressesKey";
    volatile int32_t UncaughtExceptionCount = 0;
    const int32_t UncaughtExceptionMaximum = 10;
    const NSInteger UncaughtExceptionHandlerSkipAddressCount = 4;
    const NSInteger UncaughtExceptionHandlerReportAddressCount = 5;
    NSString* getAppInfo()
    {
        NSString *appInfo = [NSString stringWithFormat:@"App : %@ %@(%@)\nDevice : %@\nOS Version : %@ %@\n",
            [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"],
            [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"],
            [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"],
            [UIDevice currentDevice].model,
            [UIDevice currentDevice].systemName,
            [UIDevice currentDevice].systemVersion];
        //      [UIDevice currentDevice].uniqueIdentifier];
        NSLog(@"Crash!!!! %@", appInfo);
        return appInfo;
    }
    
    
    void MySignalHandler(int signal)
    {
        int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
        if (exceptionCount > UncaughtExceptionMaximum)
        {
            return;
        }
        if(signal==11)
        {//比较坑爹的是 我遇到的一个问题只有iPhone5出现问题 但是我这边测试的没有iPhone5 无法直接log  可能是内存不足 果然 删除几个应用就可以了 所以加了这句
    UIAlertView * tip2 = [[UIAlertView alloc]initWithTitle:@"可能原因:key" message:@"内存不足" delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil];
            [tip2 show];
            [tip2 release];
        }
        
        NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:signal] forKey:UncaughtExceptionHandlerSignalKey];
        NSArray *callStack = [UncaughtExceptionHandler backtrace];
        [userInfo setObject:callStack forKey:UncaughtExceptionHandlerAddressesKey];
        [[[[UncaughtExceptionHandler alloc] init] autorelease]
         performSelectorOnMainThread:@selector(handleException:)
         withObject:
         [NSException
          exceptionWithName:UncaughtExceptionHandlerSignalExceptionName
          reason:
          [NSString stringWithFormat:
           NSLocalizedString(@"Signal %d was raised.\n"
                             @"%@", nil),
           signal, getAppInfo()]
          userInfo:
          [NSDictionary
           dictionaryWithObject:[NSNumber numberWithInt:signal]
           forKey:UncaughtExceptionHandlerSignalKey]]
         waitUntilDone:YES];
    
    }
    
    
    @implementation UncaughtExceptionHandler
    +(void) InstallUncaughtExceptionHandler
    {
        signal(SIGABRT, MySignalHandler);
        signal(SIGILL, MySignalHandler);
        signal(SIGSEGV, MySignalHandler);
        signal(SIGFPE, MySignalHandler);
        signal(SIGBUS, MySignalHandler);
        signal(SIGPIPE, MySignalHandler);
    }
    + (NSArray *)backtrace
    {
        void* callstack[128];
        int frames = backtrace(callstack, 128);
        char **strs = backtrace_symbols(callstack, frames);
        int i;
        NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
        for (
             i = UncaughtExceptionHandlerSkipAddressCount;
             i < UncaughtExceptionHandlerSkipAddressCount +
             UncaughtExceptionHandlerReportAddressCount;
             i++)
        {
            [backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
        }
        free(strs);
        return backtrace;
    }
    - (void)alertView:(UIAlertView *)anAlertView clickedButtonAtIndex:(NSInteger)anIndex
    {
        if (anIndex == 0)
        {
            dismissed = YES;
        }
    }
    - (void)handleException:(NSException *)exception
    {
        UIAlertView *alert =
        [[[UIAlertView alloc]
          initWithTitle:NSLocalizedString(@"Unhandled exception", nil)
          message:[NSString stringWithFormat:NSLocalizedString(
              @"You can try to continue but the application may be unstable.\n"
              @"%@\n%@", nil),
                   [exception reason],
                   [[exception userInfo] objectForKey:UncaughtExceptionHandlerAddressesKey]]
          delegate:self
          cancelButtonTitle:NSLocalizedString(@"Quit", nil)
          otherButtonTitles:NSLocalizedString(@"Continue", nil), nil]
         autorelease];
        [alert show];
        CFRunLoopRef runLoop = CFRunLoopGetCurrent();
        CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
        while (!dismissed)
        {
            for (NSString *mode in (NSArray *)allModes)
            {
                CFRunLoopRunInMode((CFStringRef)mode, 0.001, false);
            }
        }
        CFRelease(allModes);
        NSSetUncaughtExceptionHandler(NULL);
        signal(SIGABRT, SIG_DFL);
        signal(SIGILL, SIG_DFL);
        signal(SIGSEGV, SIG_DFL);
        signal(SIGFPE, SIG_DFL);
        signal(SIGBUS, SIG_DFL);
        signal(SIGPIPE, SIG_DFL);
        if ([[exception name] isEqual:UncaughtExceptionHandlerSignalExceptionName])
        {
            kill(getpid(), [[[exception userInfo] objectForKey:UncaughtExceptionHandlerSignalKey] intValue]);
        }
        else
        {
            [exception raise];
        }
    }
    void UncaughtExceptionHandlers (NSException *exception) {
        NSArray *arr = [exception callStackSymbols];
        NSString *reason = [exception reason];
        NSString *name = [exception name];
        NSString *urlStr = [NSString stringWithFormat:@"mailto://443617299@qq.com?subject=bug报告&body=感谢您的配合!<br><br><br>"
                            "错误详情:<br>%@<br>--------------------------<br>%@<br>---------------------<br>%@",
                            name,reason,[arr componentsJoinedByString:@"<br>"]];
        NSURL *url = [NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
        [[UIApplication sharedApplication] openURL:url];
        
        //或者直接用代码,输入这个崩溃信息,以便在console中进一步分析错误原因
        NSLog(@"1heqin, CRASH: %@", exception);
        NSLog(@"heqin, Stack Trace: %@", [exception callStackSymbols]);
    }
    
    @end
    

    然后在delegate文件里面- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions函数里面

    [UncaughtExceptionHandler InstallUncaughtExceptionHandler];
    NSSetUncaughtExceptionHandler (&UncaughtExceptionHandlers);
    

    相关文章

      网友评论

          本文标题:IOS程序异常捕获

          本文链接:https://www.haomeiwen.com/subject/kbaputtx.html