-
-
Notifications
You must be signed in to change notification settings - Fork 342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Capture async stack traces #998
Conversation
libdispatch on Apple has its own introspection support. However in order to use that, the user has to actually load the introspection capable version of the library, which is the case when doing debugging in XCode, but is not the case for normal runtime. See https://github.com/apple/swift-corelibs-libdispatch/blob/main/dispatch/introspection.h Instead, we rely on https://github.com/facebook/fishhook to replace the async libdispatch functions with our own wrappers, similar to how https://github.com/tiantianbobo/XBAsyncStackTrace works.
Testing sessionMac OS
Objective-C Sample
iOS-Swift
tvOS-Swift
|
Codecov Report
@@ Coverage Diff @@
## master #998 +/- ##
==========================================
+ Coverage 95.08% 95.23% +0.14%
==========================================
Files 88 88
Lines 3787 3795 +8
==========================================
+ Hits 3601 3614 +13
+ Misses 186 181 -5
Continue to review full report at Codecov.
|
The crash on 14.5 beta seems to be an upstream problem: facebook/fishhook#82 |
iPad Air (4th gen) iOS 14.5 beta 4: seems to work fine now |
This feature will soon land as part of getsentry/sentry-cocoa#998 and the way it wraps async calls creates a few well-known stackframes which we want to classify as not in-app.
Testing sessionMac OS
Objective-C Sample
iOS-Swift
tvOS-Swift
|
This feature will soon land as part of getsentry/sentry-cocoa#998 and the way it wraps async calls creates a few well-known stackframes which we want to classify as not in-app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RSLGTM
Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_MachineContext.c
Show resolved
Hide resolved
54459fc
to
8af9aff
Compare
Testing sessionMac OS
Objective-C Sample
iOS-Swift
tvOS-Swift
I had two cases where the device context was missing, but I'm not sure if this is related to this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for an alpha this is good enough. Before GA we still need to figure out why on some devices the stacktrace is not complete and why the device data is sometimes missing. A review from someone from the native team is IMO required before merging this.
This feature will soon land as part of getsentry/sentry-cocoa#998 and the way it wraps async calls creates a few well-known stackframes which we want to classify as not in-app.
if (!bt) { | ||
return; | ||
} | ||
__atomic_fetch_add(&bt->refcount, 1, __ATOMIC_SEQ_CST); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i suspect SEQ_CST is overkill, but this is hard so probably fine to leave it until this is actually a perf bottleneck
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use basically the same all over the native SDK. Getting the memory orderings right is quite difficult, so IMO there is nothing wrong with being too conservative.
BTW, there is a nice series on these patterns on LWN which I’m reading these days: https://lwn.net/Articles/844224/
📜 Description
libdispatch on Apple has its own introspection support. However in order to use that, the user has to actually load the introspection capable version of the library, which is the case when doing debugging in XCode, but is not the case for normal runtime.
See https://github.com/apple/swift-corelibs-libdispatch/blob/main/dispatch/introspection.h
Instead, we rely on https://github.com/facebook/fishhook to replace the async libdispatch functions with our own wrappers, similar to how https://github.com/tiantianbobo/XBAsyncStackTrace works.
Creating the async stack traces is based on these hooks. We capture a stacktrace in the caller, and pass that trace into the async context via an async closure (block). There, we save it in a hashtable keyed by the thread id.
We use that "thread-local" to chain multiple async calls together, and also to attach the async caller to any thread that is being captured by SentryCrash.
When SentryCrash is walking (serializing) the stacktrace, we chain those async callers together.
💡 Motivation and Context
When done, this will allow us to capture the chained stacktrace of async dispatched blocks/functions.
💚 How did you test it?
📝 Checklist
🔮 Next steps
fixes #852