iOS 충돌 이상 캡처

4660 단어
iOS는 이미 이상을 포착하는 메커니즘을 제공했다
NSSetUncaughtExceptionHandler
우리는 붕괴 원인을 분석하는 방법을 적는 crash를 포획하는 클래스를 만들 것이다
헤더 파일
#import 

@interface UncaughtExceptionHandler : NSObject{

}

@end

void HandleException(NSException *exception);
void SignalHandler(int signal);

// didFinishLaunchingWithOptions 
//   
/*
  InstallUncaughtExceptionHandler();
*/
void InstallUncaughtExceptionHandler(void);

.m 파일
정의
#include 
#include 

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)handleException:(NSException *)exception
{
 // alert 
/* message 
  [NSString stringWithFormat:NSLocalizedString(   
                @" .
" @"%@
%@", nil), [exception reason], // [[exception userInfo] objectForKey:UncaughtExceptionHandlerAddressesKey]] */ 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); { kill(getpid(),[[[[exception userInfo] allValues] lastObject] intValue]); } } @end
void HandleException(NSException *exception)
{
 int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
 if (exceptionCount > UncaughtExceptionMaximum)
 {
  return;
 }
 
 NSArray *callStack = [exception callStackSymbols];// 
    //[UncaughtExceptionHandler backtrace];
 NSMutableDictionary *userInfo =
  [NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];
 [userInfo
  setObject:callStack
  forKey:UncaughtExceptionHandlerAddressesKey];
 
 [[[[UncaughtExceptionHandler alloc] init] autorelease]
  performSelectorOnMainThread:@selector(handleException:)
  withObject:
   [NSException
    exceptionWithName:[exception name]
    reason:[exception reason]
    userInfo:userInfo]
  waitUntilDone:YES];
}

void SignalHandler(int signal)
{
      NSLog(@"handleException 4");
 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] autorelease]
  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);
}

좋은 웹페이지 즐겨찾기