[PLAT-12346] Harmonize all calls to manual error reporting, and ensure proper frame stripping in all cases #1668
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
Code along the critical path responsible for generating a stack trace and stripping off the stack trace generation frames themselves must always always be present exactly as written so that the top of the stack is always consistent, and the code can accurately strip off the right number of frames.
Recently, Apple introduced optimizations that inline or outline objective-c code, and can't be turned off. We need to ensure that these optimizations are never run on our call stack generation and fixup code.
Design
Since we can't instruct the compiler directly to not optimize these calls (
Bugsnag.notifyXYZ
,BugsnagClient.notifyXYZ
), we must confound the compiler so that it gives up trying to optimize them.I've added a new utility method
BSGPreventInlining()
, which takes a string and returns the last string it was given (no thread safety because the string contents don't matter at all and should never be used for anything).The key concepts here are:
BSGPreventInlining()
, the compiler won't be able to discover that it does nothing (and thus elide it).BSGPreventInlining()
, every call site can send different strings, making every call site "unique code" that can't be outlined.Ultimately, this becomes a reverse-halting-problem kind of cat-and-mouse game, where each tries to outwit and outlast the other. I think that this current design should be enough to keep the optimizations at bay long enough (a few years at least) for someone to finally allow
optnone
compiler directives in objective-c code...Note: This new design also corrects a bug where too many stack entries get stripped if you call the
BugsnagClient
notify methods directly (rather than callingBugsnag.notifyXYZ
).Testing
Existing e2e tests check call stack integrity already, and I also verified manually just to be sure.