• iOS崩溃报告获取二


    //
    //  JKExceptionHandler.h
    //  JKExceptionHandler
    //
    //  Created by Jack on 16/9/7.
    //  Copyright © 2016年 mini1. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface JKExceptionHandler : NSObject
    {
        BOOL dismissed;
    }
    @end
    
    
    void HandleException(NSException *exception);
    void SignalHandler(int signal);
    
    
    void InstallUncaughtExceptionHandler(void);
    
    //
    //  JKExceptionHandler.m
    //  JKExceptionHandler
    //
    //  Created by Jack on 16/9/7.
    //  Copyright © 2016年 mini1. All rights reserved.
    //
    
    #import "JKExceptionHandler.h"
    #import <UIKit/UIKit.h>
    #import <libkern/OSAtomic.h>
    #import <execinfo.h>
    
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"
    
    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 JKExceptionHandler
    
    
    + (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(@"continue");
        }
    }
    
    - (void)validateAndSaveCriticalApplicationData
    {
        
    }
    
    - (void)handleException:(NSException *)exception
    {
        [self validateAndSaveCriticalApplicationData];
        
        UIAlertView *alert =
        
        [[UIAlertView alloc]
          initWithTitle:NSLocalizedString(@"抱歉,程序出现了异常", nil)
         message:[NSString stringWithFormat:NSLocalizedString(
                                                              @"如果点击继续,程序有可能会出现其他的问题,建议您还是点击退出按钮并重新打开
    
    "
                                                              @"异常原因如下:
    %@
    %@", 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((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 = [JKExceptionHandler backtrace];
        NSMutableDictionary *userInfo =
        [NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];
        [userInfo
         setObject:callStack
         forKey:UncaughtExceptionHandlerAddressesKey];
        
        [[[JKExceptionHandler 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 = [JKExceptionHandler backtrace];
        [userInfo
         setObject:callStack
         forKey:UncaughtExceptionHandlerAddressesKey];
        
        [[[JKExceptionHandler 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);
    }
    
    #pragma clang diagnostic pop
    

      

  • 相关阅读:
    最近实际项目中遇到的技术问题与解决思路
    独立完成一个城市选择组件(阿里前端题目,内附知识点、思路)
    用Node.js写爬虫,撸羞羞的图片
    Flutter项目之app升级方案
    Flutter数据持久化入门以及与Web开发的对比
    为什么要学会正则表达式
    async/await,了解一下?
    面向面试题和实际使用谈promise
    从一次输入框无法输入的bug,谈如何限制输入框输入类型
    Vue组件的is具体用法
  • 原文地址:https://www.cnblogs.com/buakaw/p/5849858.html
Copyright © 2020-2023  润新知