fix: Copy mutable collections before passing to scope observers#7807
fix: Copy mutable collections before passing to scope observers#7807
Conversation
SentryScope passes mutable collections to scope observers inside @synchronized blocks. Observers like WatchdogTermination dispatch async work that iterates the collection after the lock is released, racing with concurrent mutations — causing EXC_BAD_ACCESS. Copy collections before passing to observers, consistent with the existing public getter methods that already return copies.
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. Bug Fixes 🐛
Internal Changes 🔧Deps
🤖 This preview updates automatically when you update the PR. |
|
@cursor review |
|
@sentry review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit dd9ad6b. Configure here.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #7807 +/- ##
=============================================
- Coverage 85.418% 85.130% -0.289%
=============================================
Files 487 487
Lines 29195 29207 +12
Branches 12632 12625 -7
=============================================
- Hits 24938 24864 -74
- Misses 4207 4292 +85
- Partials 50 51 +1
... and 15 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
📜 Description
Copy mutable collections (
_contextDictionary,_tagDictionary,_extraDictionary,_fingerprintArray,_attributesDictionary) before passing them to scope observers inSentryScope.m. This prevents a race condition where observers dispatch async work that iterates the collection after the@synchronizedlock is released, while another thread mutates it concurrently.Also updates the misleading thread-safety comment in
SentryWatchdogTerminationScopeObserver.swiftto accurately describe the guarantee.💡 Motivation and Context
Fixes a launch crash (
EXC_BAD_ACCESSinobjc_msgSend) reported in getsentry/sentry-react-native#5995 affecting <1% of cold launches on iOS 26+. The crash occurs becauseSentryWatchdogTerminationScopeObservercaptures mutable collection references and dispatches async disk writes, racing with concurrent scope mutations.The public getter methods (
context,extras,tags,fingerprints,attributes) already return.copy— this fix makes observer notifications consistent with that pattern.💚 How did you test it?
testModifyingFromMultipleThreads_withObserverAsyncDispatch— a concurrent stress test that rapidly mutates scope context/tags/extras/fingerprint from multiple threads while an observer with async dispatch is activeSentryScopeSwiftTests(59 tests) passSentryWatchdogTerminationScopeObserverTests(18 tests) passmake format,make analyze,make build-iosall clean📝 Checklist
You have to check all boxes before merging:
sendDefaultPIIis enabled.