Skip to content

Commit

Permalink
fix: Record NSException details immediately from C++ handler
Browse files Browse the repository at this point in the history
This avoids a case where if the NSException handler is overridden
without calling the previous handler, no report is recorded. In the case
that the handler is invoked twice for a given exception, it is only
recorded once by checking that the last recorded exception is the same.
  • Loading branch information
kattrali committed Sep 13, 2018
1 parent 3a68f27 commit 93a08d7
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 10 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

## TBD

### Bug Fixes

* Ensure NSException is captured when handler is overridden
[#313](https://github.com/bugsnag/bugsnag-cocoa/pull/313)

## 5.16.3 (14 Aug 2018)

### Bug Fixes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@
#define likely_if(x) if (__builtin_expect(x, 1))
#define unlikely_if(x) if (__builtin_expect(x, 0))

#ifdef __cplusplus
extern "C" {
#endif
// Internal NSException recorder
void bsg_recordException(NSException *exception);
#ifdef __cplusplus
}
#endif

// ============================================================================
#pragma mark - Globals -
// ============================================================================
Expand Down Expand Up @@ -114,9 +123,11 @@ static void CPPExceptionTerminate(void) {
try {
throw;
} catch (NSException *exception) {
BSG_KSLOG_DEBUG(@"Detected NSException. Letting the current "
BSG_KSLOG_DEBUG(@"Detected NSException. Recording details "
@"and letting the current "
@"NSException handler deal with it.");
isNSException = true;
bsg_recordException(exception);
} catch (std::exception &exc) {
strncpy(descriptionBuff, exc.what(), sizeof(descriptionBuff));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,21 @@
/** Context to fill with crash information. */
static BSG_KSCrash_SentryContext *bsg_g_context;

static NSException *bsg_lastHandledException = NULL;

// ============================================================================
#pragma mark - Callbacks -
// ============================================================================


// Avoiding static methods due to linker issue.
/**
Capture exception details and write a new report. If the exception was
recorded before, no new report will be generated.
@param exception The exception to process
*/
void bsg_recordException(NSException *exception);

/** Our custom excepetion handler.
* Fetch the stack trace from the exception and write a report.
Expand All @@ -74,6 +84,30 @@ void bsg_ksnsexc_i_handleException(NSException *exception) {
bsg_kscrashsentry_uninstall(BSG_KSCrashTypeAll);
}

bsg_recordException(exception);

BSG_KSLOG_DEBUG(
@"Crash handling complete. Restoring original handlers.");
bsg_kscrashsentry_uninstall(BSG_KSCrashTypeAll);

if (bsg_g_previousUncaughtExceptionHandler != NULL) {
BSG_KSLOG_DEBUG(@"Calling original exception handler.");
bsg_g_previousUncaughtExceptionHandler(exception);
}
}
}

void bsg_recordException(NSException *exception) {
if (bsg_g_installed) {
BOOL previouslyHandled = exception == bsg_lastHandledException;
if (previouslyHandled) {
BSG_KSLOG_DEBUG(@"Handled exception previously, "
@"exiting exception recorder.");
return;
}
bsg_lastHandledException = exception;
BSG_KSLOG_DEBUG(@"Writing exception info into a new report");

BSG_KSLOG_DEBUG(@"Suspending all threads.");
bsg_kscrashsentry_suspendThreads();

Expand All @@ -95,15 +129,6 @@ void bsg_ksnsexc_i_handleException(NSException *exception) {

BSG_KSLOG_DEBUG(@"Calling main crash handler.");
bsg_g_context->onCrash();

BSG_KSLOG_DEBUG(
@"Crash handling complete. Restoring original handlers.");
bsg_kscrashsentry_uninstall(BSG_KSCrashTypeAll);

if (bsg_g_previousUncaughtExceptionHandler != NULL) {
BSG_KSLOG_DEBUG(@"Calling original exception handler.");
bsg_g_previousUncaughtExceptionHandler(exception);
}
}
}

Expand Down

0 comments on commit 93a08d7

Please sign in to comment.