美文网首页
Crash捕获

Crash捕获

作者: L柠_檬 | 来源:发表于2016-08-30 16:07 被阅读73次
    1.1 捕获Crash日志
    1.2 信号捕获方法
    
    
    1.1  捕获Crash日志
    
    - (BOOL)application:(UIApplication *)application 
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch
        //方法调用
        [self installUncaugtExceptionHandler];
    
        return YES;
        
    }
    - (void)installUncaugtExceptionHandler{
        //捕获crash
         NSSetUncaughtExceptionHandler(&UncaughtExceptionhandler);
    }
    
    void UncaughtExceptionhandler(NSException *exception){
        //原因
        NSString *reason = [exception reason];
        //名字
        NSString *name = [exception name];
        NSString *currentVersion = [[[NSBundle 
       mainBundle]infoDictionary]objectForKey:@"CFBundleVersion"];
        NSLog(@"\n版本:%@\n名字:%@\n原因:%@",currentVersion,name,reason);
        //详细内容
        NSArray *arr = [exception callStackSymbols];
        NSLog(@"详细内容:%@",arr);
    
    
    
        测试:
        NSArray *a = @[@"1"];    
        NSLog(@"%@",a[10]);
    
        版本:1
        名字:NSRangeException
        原因:*** -[__NSArrayI objectAtIndex:]: index 10 beyond bounds [0 .. 0]
    
    }
    
    
    1.2 信号捕获方法
    
    .h
    
    #import <Foundation/Foundation.h>
    
    @interface UncaughtExceptionHandler : NSObject{
        BOOL dismissed;
    }
    
    @end
    void HandleException(NSException *exception);
    void SignalHandler(int signal);
    
    
    void InstallUncaughtExceptionHandler(void);
    
    
    .m
    
    #import "UncaughtExceptionHandler.h"
    #include <libkern/OSAtomic.h>
    #include <execinfo.h>
    #import <UIKit/UIKit.h>
    //http://www.cocoachina.com/newbie/tutorial/2012/0829/4672.html
    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;
    
    @implementation UncaughtExceptionHandler
    
    + (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;
        }else if (anIndex==1) {
            NSLog(@"ssssssss");
        }
    }
    
    - (void)validateAndSaveCriticalApplicationData
    {
        
    }
    
    - (void)handleException:(NSException *)exception
    {
        [self validateAndSaveCriticalApplicationData];
        
        UIAlertView *alert =
        [[UIAlertView alloc]
          
        initWithTitle:NSLocalizedString(@"抱歉,程序出现了异常", nil)
          
        message:[NSString stringWithFormat:NSLocalizedString(
                                                              
       @"如果点击继续,程序有可能会出现其他的问题,建议您还是点击退出按钮并重新打开\n\n"
                                                              
       @"异常原因如下:\n%@\n%@", nil),
                   [exception reason],
                   [[exception userInfo] 
        objectForKey:UncaughtExceptionHandlerAddressesKey]]
          delegate:self
          cancelButtonTitle:NSLocalizedString(@"退出", nil)
          otherButtonTitles:NSLocalizedString(@"继续", nil), nil]
         ;
        [alert show];
        
        CFRunLoopRef runLoop = CFRunLoopGetCurrent();
        CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
        
        while (!dismissed)
        {
            for (NSString *mode in (__bridge NSArray *)allModes)
            {
                CFRunLoopRunInMode((__bridge 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];
        }
    }
    
    @end
    
    void HandleException(NSException *exception)
    {
        int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
        if (exceptionCount > UncaughtExceptionMaximum)
        {
            return;
        }
        
        NSArray *callStack = [UncaughtExceptionHandler backtrace];
        NSMutableDictionary *userInfo =
        [NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];
        [userInfo
         setObject:callStack
         forKey:UncaughtExceptionHandlerAddressesKey];
        
        [[[UncaughtExceptionHandler alloc] init]
         performSelectorOnMainThread:@selector(handleException:)
         withObject:
         [NSException
          exceptionWithName:[exception name]
          reason:[exception reason]
          userInfo:userInfo]
         waitUntilDone:YES];
    }
    
    void SignalHandler(int signal)
    {
        int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
        if (exceptionCount > UncaughtExceptionMaximum)
        {
            return;
        }
        
        NSMutableDictionary *userInfo =
        [NSMutableDictionary
         dictionaryWithObject:[NSNumber numberWithInt:signal]
         forKey:UncaughtExceptionHandlerSignalKey];
        
        NSArray *callStack = [UncaughtExceptionHandler backtrace];
        [userInfo
         setObject:callStack
         forKey:UncaughtExceptionHandlerAddressesKey];
        
        [[[UncaughtExceptionHandler alloc] init]
         performSelectorOnMainThread:@selector(handleException:)
         withObject:
         [NSException
          exceptionWithName:UncaughtExceptionHandlerSignalExceptionName
          reason:
          [NSString stringWithFormat:
           NSLocalizedString(@"Signal %d was raised.", nil),
           signal]
          userInfo:
          [NSDictionary
           dictionaryWithObject:[NSNumber numberWithInt:signal]
           forKey:UncaughtExceptionHandlerSignalKey]]
         waitUntilDone:YES];
    }
    
    void InstallUncaughtExceptionHandler(void)
    {
        NSSetUncaughtExceptionHandler(&HandleException);
        signal(SIGABRT, SignalHandler);
        signal(SIGILL, SignalHandler);
        signal(SIGSEGV, SignalHandler);
        signal(SIGFPE, SignalHandler);
        signal(SIGBUS, SignalHandler);
        signal(SIGPIPE, SignalHandler);
    }
    
    
    调用:
    #import "AppDelegate.h"
    #import "UncaughtExceptionHandler.h"
    
    - (BOOL)application:(UIApplication *)application 
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch
        InstallUncaughtExceptionHandler();
    
        return YES;
    }
    
    

    相关文章

      网友评论

          本文标题:Crash捕获

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