[runtime] Fix race condition in xamarin_release_managed_ref for user types. Fixes #25171#25330
[runtime] Fix race condition in xamarin_release_managed_ref for user types. Fixes #25171#25330rolfbjarne wants to merge 6 commits intomainfrom
Conversation
…25171) Add Console.WriteLine logging to every test method in LayerTest, with entry/exit markers and thread IDs. Adds detailed logging around all GC.Collect() calls and background thread operations to help pinpoint which test is running when the crash in xamarin_coreclr_reference_tracking_is_referenced_callback occurs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…types (#25171) The framework_peer_waypoint was only called for non-user types, but the same race condition exists for user types: the GC's toggle-ref callback can read the native handle and call [handle retainCount] while another thread is in the process of calling objc_release on the same handle. Move the waypoint outside the if/else block so it applies to both user types and non-user types, ensuring that objc_release never races with the GC's reference tracking callbacks. The race manifests as a SIGSEGV in objc_msgSend (called from xamarin_gc_toggleref_callback) when GC.Collect() is called on one thread while NSObject_Disposer.Drain is releasing native objects on the main thread. This is particularly likely on ARM64 where memory ordering is weak and the HasManagedRef flag write may not be visible to the GC thread before the release completes. Fixes #25171 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
✅ [PR Build #2615017] Build passed (Detect API changes) ✅Pipeline on Agent |
✅ [PR Build #2615017] Build passed (Build packages) ✅Pipeline on Agent |
✅ API diff for current PR / commitNET (empty diffs)✅ API diff vs stableNET (empty diffs)ℹ️ Generator diffGenerator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes) Pipeline on Agent |
✅ [PR Build #2615017] Build passed (Build macOS tests) ✅Pipeline on Agent |
🔥 [CI Build #2615017] Test results 🔥Test results❌ Tests failed on VSTS: test results 0 tests crashed, 14 tests failed, 155 tests passed. Failures❌ monotouch tests (iOS)13 tests failed, 0 tests passed.Failed tests
Html Report (VSDrops) Download ❌ monotouch tests (tvOS)1 tests failed, 12 tests passed.Failed tests
Html Report (VSDrops) Download Successes✅ cecil: All 1 tests passed. Html Report (VSDrops) Download macOS tests✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download Linux Build VerificationPipeline on Agent |
Summary
Fix a race condition in
xamarin_release_managed_ref(runtime/runtime.m) that causes a SIGSEGV crash during GC on ARM64 (NativeAOT).Root Cause
The
framework_peer_waypoint(which preventsobjc_releasefrom racing with the GC toggle-ref callbacks) was only called for non-user types. For user types (like customCALayersubclasses),objc_releasewas called without synchronization, allowing it to deallocate a native object while the GC'sis_referenced_callbackis reading its handle to call[handle retainCount].Fix
Move
xamarin_framework_peer_waypoint_safe()outside theif (user_type) / elseblock so it applies to both user types and non-user types.How Tested
The crash was reproduced in CI (NativeAOT ARM64 iOS monotouch-test,
TestBug26532). The fix ensuresobjc_releasewaits for the GC to finish its reference tracking callbacks before proceeding.Debug logging in
LayerTest.csis kept temporarily for verification in CI runs.Fixes #25171
🤖 Pull request created by Copilot