fix: Record NSException details immediately from C++ handler #313
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Goal
Record exception details separately from the NSException call chain.
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.
Design
When an NSException is thrown, it is first captured in the C++ termination handler.
Once it is then detected to be an NSException, it is ignored in favor of letting the default NSException handler chain catch it (which is invoked by the default C++ handler). This presents a case where an exception is detected but then lost if the NSException handler is overridden.
If we simply call the exception handler logic early, the app may enter an indeterminate state depending on what other handlers do, and there is the possibility that handlers are called once, twice, or not at all.
Good citizenship here would be to:
With those goals in mind, this change records details about an NSException immediately from the C++ handler, without invoking/interrupting the uncaught NSException handler chain.
If the same exception is then re-encountered by the uncaught NSException handler, the report is not recorded again and instead invokes the previous handler, if any.
Changeset
Added
bsg_recordException
to the NSException handler. This allows the logic for recording a report to be reused outside of the uncaught exception handler itself.bsg_lastHandledException
. This variable tracks what exception was last recorded.Changed
bsg_recordException
immediately when an NSException is detected.Tests
This change was tested on iOS 8.4/10.3/11.4 and macOS 10.12 and confirmed to send a single report when an NSException is thrown in the following scenarios:
Discussion
Linked issues
Closes #312
Review
For the submitter, initial self-review:
This pull request is ready for final review
For the pull request reviewer(s), this changeset has been reviewed for: