| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- //
- // UncaughtExceptionHandler.m
- // UncaughtExceptions
- //
- // Created by Matt Gallagher on 2010/05/25.
- // Copyright 2010 Matt Gallagher. All rights reserved.
- //
- // Permission is given to use this source code file, free of charge, in any
- // project, commercial or otherwise, entirely at your risk, with the condition
- // that any redistribution (in part or whole) of source code must retain
- // this copyright and permission notice. Attribution in compiled projects is
- // appreciated but not required.
- //
- #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;
- @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;
- }
- }
- - (void)validateAndSaveCriticalApplicationData
- {
-
- }
- - (void)handleException:(NSException *)exception
- {
- [self validateAndSaveCriticalApplicationData];
- id delegate = [[UIApplication sharedApplication] delegate];
-
- if([delegate respondsToSelector:@selector(terminateWithException:)])
- {
-
- dismissed = (BOOL)[delegate performSelector:@selector(terminateWithException:) withObject:exception];
-
- }
-
- 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);
- }
|