fix: Fix UITouch background thread access in SentryTouchTracker#6584
Merged
fix: Fix UITouch background thread access in SentryTouchTracker#6584
Conversation
Extract UITouch data on main thread before dispatching to background queue to prevent EXC_BAD_ACCESS crashes when accessing UIKit objects from background threads. - Added ExtractedTouchData struct to hold thread-safe touch information - Changed trackedTouches dictionary to use ObjectIdentifier as key instead of UITouch - Extract touch.location, touch.phase, and ObjectIdentifier on calling thread - Process only thread-safe data structures on background queue Fixes #6231
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## v8.x #6584 +/- ##
=============================================
+ Coverage 85.196% 86.097% +0.901%
=============================================
Files 441 441
Lines 27426 27470 +44
Branches 10368 11933 +1565
=============================================
+ Hits 23366 23651 +285
+ Misses 4018 3773 -245
- Partials 42 46 +4
... and 33 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
- Added testObjectIdentifierCollision_NewTouchGetsNewId to demonstrate the bug - Fix prevents corrupted touch data when UITouch memory is reused - When .began phase is detected, always create new TouchInfo - Updated CHANGELOG.md with combined entry for both fixes
- Removed trackedTouches dictionary entirely - Use single allTouchInfos array with O(n) lookup - Store ObjectIdentifier in TouchInfo for matching - Eliminates collision/orphaning complexity - Reduced cyclomatic complexity (no more linter warnings) - All 14 tests pass
Contributor
Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| ab82dac | 1213.12 ms | 1240.92 ms | 27.80 ms |
| c11a8e0 | 1203.00 ms | 1223.23 ms | 20.23 ms |
| ab82dac | 1249.73 ms | 1272.69 ms | 22.96 ms |
| 41834f1 | 1235.15 ms | 1256.31 ms | 21.17 ms |
| f76f6bf | 1207.70 ms | 1233.27 ms | 25.57 ms |
| b66be9b | 1218.22 ms | 1244.19 ms | 25.96 ms |
| 5fce94f | 1226.31 ms | 1246.82 ms | 20.50 ms |
| a7a0a2b | 1218.61 ms | 1248.69 ms | 30.08 ms |
| e537c90 | 1226.22 ms | 1256.64 ms | 30.41 ms |
| 3af1ae9 | 1225.60 ms | 1252.65 ms | 27.05 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| ab82dac | 23.75 KiB | 991.86 KiB | 968.11 KiB |
| c11a8e0 | 23.75 KiB | 991.86 KiB | 968.12 KiB |
| ab82dac | 23.75 KiB | 991.85 KiB | 968.10 KiB |
| 41834f1 | 23.75 KiB | 991.88 KiB | 968.13 KiB |
| f76f6bf | 23.74 KiB | 981.30 KiB | 957.56 KiB |
| b66be9b | 23.75 KiB | 996.03 KiB | 972.28 KiB |
| 5fce94f | 23.75 KiB | 991.62 KiB | 967.87 KiB |
| a7a0a2b | 23.75 KiB | 996.04 KiB | 972.29 KiB |
| e537c90 | 23.75 KiB | 992.03 KiB | 968.28 KiB |
| 3af1ae9 | 23.74 KiB | 981.29 KiB | 957.55 KiB |
noahsmartin
reviewed
Oct 29, 2025
Sources/Swift/Integrations/SessionReplay/SentryTouchTracker.swift
Outdated
Show resolved
Hide resolved
noahsmartin
reviewed
Oct 29, 2025
Address PR feedback - use dictionary for O(1) lookup instead of O(n) array search. - trackedTouches: O(1) dictionary lookup for active touches - orphanedTouches: array for collision-replaced touches - When .began collides, move old touch to orphanedTouches before replacing - Extract processTouchEvent method to reduce cyclomatic complexity - replayEvents returns both active + orphaned touches - Maintains performance while preserving all events - All 14 tests pass
Contributor
|
CI is being very slow, I am backporting some fixes on #6604 to help this PR and the later release |
itaybre
added a commit
that referenced
this pull request
Oct 30, 2025
* test: Ensure test is server running (#6300) Ensure that the test server is running with a retry mechanism to avoid flakiness in CI. * ci: Add v8.x branch to workflows (#6321) * chore: Explain v8 branch (#6323) Add decision log entry for v8 branch and explain how to release from it. * ci(v8): Bump Xcode from 26.0 to 26.0.1 (#6394) * docs: Add note to README with reference to v9 on main branch (#6402) * fix: Wrong Frame Delay when becoming active (#6393) The SDK reported false frame delay statistics when it moved from the background to the foreground, which also led to falsely reported app hangs. Fixes GH-6345 * fix(session-replay): Add detection for potential PII leaks disabling session replay (#6389) * release: 8.57.0 * chore: Bump simulators to 26.1 (#6578) * fix: Fix crash when last replay info is missing some keys (#6577) * fix: Fix crash when last replay info is missing keys * Update changelog * fix: Disable SessionSentryReplayIntegration if the environment is unsafe (#6573) * fix: Disable SessionSentryReplayIntegration if the environment is unsafe * Simplify shouldEnableSessionReplay * Rename test * Add log message * Update changelog * Safely unwrap SentryOptions * fix: Fix UITouch background thread access in SentryTouchTracker (#6584) * release: 8.57.1 * Fix merge issues * Fix another merge issue * More merge conflicts * Add SentryThreadInspector again * Fix tests on iOS 26 * Add `enableSessionReplayInUnreliableEnvironment` --------- Co-authored-by: Philipp Hofmann <[email protected]> Co-authored-by: Philip Niedertscheider <[email protected]> Co-authored-by: getsentry-bot <[email protected]> Co-authored-by: getsentry-bot <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
📜 Description
This PR fixes a crash caused by accessing UITouch instances from a background thread in . The fix extracts all necessary data from UITouch objects on the main thread before dispatching to the background queue, then processes only thread-safe data structures on the background thread.
Changes:
ExtractedTouchDatastruct to hold thread-safe touch informationtrackedTouchesdictionary to useObjectIdentifieras key instead ofUITouchtouch.location,touch.phase, andObjectIdentifieron calling thread (main thread)💡 Motivation and Context
Fixes #6231
The issue was that
trackTouchFrom(event:)dispatched to a background queue and then accessed UITouch properties (touch.location(in: nil)andtouch.phase) from that background thread. This violates UIKit's thread-safety requirements and causedEXC_BAD_ACCESScrashes.The stack trace from the issue showed:
💚 How did you test it?
SentryTouchTrackerTestspass successfully📝 Checklist
sendDefaultPIIis enabled.