Repository navigation
Fix re-entrant exclusive-access crash in drag handle hit test - #771
Conversation
When sibling.hitTest() triggers a SwiftUI layout pass during the drag handle's sibling walk, AppKit can call back into windowDragHandleShouldCaptureHit before the outer invocation finishes. This re-entry accesses SwiftUI view state that is already held exclusively, causing a Swift runtime SIGABRT. Add a module-level re-entrancy guard that bails out (returns false) on nested calls to the sibling walk. Since hitTest is always called on the main thread, a simple Bool flag is sufficient. Crash was reproduced on macOS Sequoia 15.1.1 (24B91) in a UTM VM. The crash stack: DraggableView.hitTest -> windowDragHandleShouldCaptureHit -> sibling.hitTest -> SwiftUI body evaluation -> hitTest (re-entry) -> exclusive-access violation -> SIGABRT.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughA re-entrancy guard mechanism is added to WindowDragHandleView to prevent SwiftUI from re-entering the sibling-hit testing path, with an accompanying test that verifies the guard prevents crashes during re-entrant scenarios. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
Greptile SummaryFixed a SIGABRT crash on macOS Sequoia caused by re-entrant calls to
Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant DraggableView
participant Guard as Re-entrancy Guard
participant Function as windowDragHandleShouldCaptureHit
participant Sibling as ReentrantSiblingView
User->>DraggableView: Mouse down event
DraggableView->>Function: hitTest(point)
Function->>Guard: Check _windowDragHandleIsResolvingSiblingHits
Guard-->>Function: false (not set)
Function->>Guard: Set flag = true
Note over Function: Start sibling walk
Function->>Sibling: hitTest(pointInSibling)
Note over Sibling: Triggers SwiftUI layout
Sibling->>Function: Re-entrant call (same drag handle)
Function->>Guard: Check _windowDragHandleIsResolvingSiblingHits
Guard-->>Function: true (already set!)
Function-->>Sibling: Return false (bail out, no crash)
Sibling-->>Function: Return nil
Note over Function: Continue sibling walk
Function->>Guard: defer resets flag = false
Function-->>DraggableView: Return true (capture hit)
Last reviewed commit: 568da85 |
Includes upstream hit-test crash fixes (manaflow-ai#698, manaflow-ai#736, manaflow-ai#771)
Includes upstream hit-test crash fixes (manaflow-ai#698, manaflow-ai#736, manaflow-ai#771)
…ow-ai#771) When sibling.hitTest() triggers a SwiftUI layout pass during the drag handle's sibling walk, AppKit can call back into windowDragHandleShouldCaptureHit before the outer invocation finishes. This re-entry accesses SwiftUI view state that is already held exclusively, causing a Swift runtime SIGABRT. Add a module-level re-entrancy guard that bails out (returns false) on nested calls to the sibling walk. Since hitTest is always called on the main thread, a simple Bool flag is sufficient. Crash was reproduced on macOS Sequoia 15.1.1 (24B91) in a UTM VM. The crash stack: DraggableView.hitTest -> windowDragHandleShouldCaptureHit -> sibling.hitTest -> SwiftUI body evaluation -> hitTest (re-entry) -> exclusive-access violation -> SIGABRT.
Summary
Fixes #761.
SIGABRT crash caused by re-entrant calls to
windowDragHandleShouldCaptureHitduring the sibling hit-test walk. Whensibling.hitTest()triggers a SwiftUI layout pass, AppKit calls back into the drag handle's hit resolution while the outer invocation is still walking siblings. This violates Swift's exclusive-access rules on SwiftUI view state.The fix adds a module-level re-entrancy guard (
_windowDragHandleIsResolvingSiblingHits) that bails out on nested calls to the sibling walk. Main-thread only, no lock needed.Crash stack:
DraggableView.hitTest->windowDragHandleShouldCaptureHit->sibling.hitTest-> SwiftUI body eval ->hitTest(re-entry) -> exclusive-access violation -> SIGABRT.Test plan
testDragHandleSiblingHitTestReentrancyDoesNotCrashregression test that simulates the re-entrant call path