Add some error handler detection, to optionally notify the developer of multiple handlers that could cause crashes not to be reported to HockeyApp

Enable debugLogEnabled to get this warning.
This commit is contained in:
Andreas Linde 2012-08-20 15:46:41 +02:00
parent 02a215be6d
commit 13b918f9cd
2 changed files with 44 additions and 1 deletions

View File

@ -94,6 +94,8 @@ static NSString *kBITCrashManagerStatus = @"BITCrashManagerStatus";
BOOL _sendingInProgress;
BOOL _isSetup;
NSUncaughtExceptionHandler *_exceptionHandler;
}

View File

@ -76,7 +76,9 @@
_delegate = nil;
_showAlwaysButton = NO;
_isSetup = NO;
_exceptionHandler = nil;
_crashIdenticalCurrentVersion = YES;
_urlConnection = nil;
_responseData = nil;
@ -372,6 +374,18 @@
- (void)invokeDelayedProcessing {
BITHockeyLog(@"INFO: Start delayed CrashManager processing");
// was our own exception handler successfully added?
if (_exceptionHandler) {
// get the current top level error handler
NSUncaughtExceptionHandler *currentHandler = NSGetUncaughtExceptionHandler();
// If the top level error handler differs from our own, then at least another one was added.
// This could cause exception crashes not to be reported to HockeyApp. See log message for details.
if (_exceptionHandler != currentHandler) {
BITHockeyLog(@"[HockeySDK] WARNING: Another exception handler was added. If this invokes any kind exit() after processing the exception, which causes any subsequent error handler not to be invoked, these crashes will NOT be reported to HockeyApp!");
}
}
if (!_sendingInProgress && [self hasPendingCrashReport]) {
_sendingInProgress = YES;
if (!BITHockeyBundle()) {
@ -445,9 +459,36 @@
// PLCrashReporter is throwing an NSException if it is being enabled again
// even though it already is enabled
@try {
// Multiple exception handlers can be set, but we can only query the top level error handler (uncaught exception handler).
//
// To check if PLCrashReporter's error handler is successfully added, we compare the top
// level one that is set before and the one after PLCrashReporter sets up its own.
//
// With delayed processing we can then check if another error handler was set up afterwards
// and can show a debug warning log message, that the dev has to make sure the "newer" error handler
// doesn't exit the process itself, because then all subsequent handlers would never be invoked.
//
// Note: ANY error handler setup BEFORE HockeySDK initialization will not be processed!
// get the current top level error handler
NSUncaughtExceptionHandler *initialHandler = NSGetUncaughtExceptionHandler();
// Enable the Crash Reporter
if (![crashReporter enableCrashReporterAndReturnError: &error])
NSLog(@"[HockeySDK] WARNING: Could not enable crash reporter: %@", [error localizedDescription]);
// get the new current top level error handler, which should now be the one from PLCrashReporter
NSUncaughtExceptionHandler *currentHandler = NSGetUncaughtExceptionHandler();
// do we have a new top level error handler? then we were successful
if (currentHandler && currentHandler != initialHandler) {
_exceptionHandler = currentHandler;
BITHockeyLog(@"INFO: Exception handler successfully initialized.");
} else {
// this should never happen, theoretically only if NSSetUncaugtExceptionHandler() has some internal issues
NSLog(@"[HockeySDK] ERROR: Exception handler could not be set. Make sure there is no other exception handler set up!");
}
}
@catch (NSException * e) {
NSLog(@"[HockeySDK] WARNING: %@", [e reason]);