Skip to content

[runtime] Fix race condition in xamarin_release_managed_ref for user types. Fixes #25171#25330

Draft
rolfbjarne wants to merge 6 commits intomainfrom
dev/rolf/issue-25171-layertest
Draft

[runtime] Fix race condition in xamarin_release_managed_ref for user types. Fixes #25171#25330
rolfbjarne wants to merge 6 commits intomainfrom
dev/rolf/issue-25171-layertest

Conversation

@rolfbjarne
Copy link
Copy Markdown
Member

@rolfbjarne rolfbjarne commented May 5, 2026

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 prevents objc_release from racing with the GC toggle-ref callbacks) was only called for non-user types. For user types (like custom CALayer subclasses), objc_release was called without synchronization, allowing it to deallocate a native object while the GC's is_referenced_callback is reading its handle to call [handle retainCount].

Fix

Move xamarin_framework_peer_waypoint_safe() outside the if (user_type) / else block 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 ensures objc_release waits for the GC to finish its reference tracking callbacks before proceeding.

Debug logging in LayerTest.cs is kept temporarily for verification in CI runs.

Fixes #25171

🤖 Pull request created by Copilot

…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>
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

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>
@rolfbjarne rolfbjarne changed the title [tests] Add debug logging to LayerTest to diagnose random GC crash. Fixes #25171 [runtime] Fix race condition in xamarin_release_managed_ref for user types. Fixes #25171 May 6, 2026
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2
Copy link
Copy Markdown
Collaborator

✅ [PR Build #2615017] Build passed (Detect API changes) ✅

Pipeline on Agent
Hash: 2615017d672058379adadc357b7fc7124612bf38 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Copy Markdown
Collaborator

✅ [PR Build #2615017] Build passed (Build packages) ✅

Pipeline on Agent
Hash: 2615017d672058379adadc357b7fc7124612bf38 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Copy Markdown
Collaborator

✅ API diff for current PR / commit

NET (empty diffs)

✅ API diff vs stable

NET (empty diffs)

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: 2615017d672058379adadc357b7fc7124612bf38 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Copy Markdown
Collaborator

✅ [PR Build #2615017] Build passed (Build macOS tests) ✅

Pipeline on Agent
Hash: 2615017d672058379adadc357b7fc7124612bf38 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Copy Markdown
Collaborator

🔥 [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

  • monotouch-test/iOS - simulator/Debug: LaunchTimedOut
  • monotouch-test/iOS - simulator/Debug (LinkSdk): LaunchTimedOut
  • monotouch-test/iOS - simulator/Debug (static registrar): LaunchTimedOut
  • monotouch-test/iOS - simulator/Release (all optimizations): LaunchTimedOut
  • monotouch-test/iOS - simulator/Debug (ARM64): LaunchTimedOut
  • monotouch-test/iOS - simulator/Release (NativeAOT, ARM64): LaunchTimedOut
  • monotouch-test/iOS - simulator/Release (trimmable static registrar, NativeAOT, ARM64): LaunchTimedOut
  • monotouch-test/iOS - simulator/Debug (managed static registrar): LaunchTimedOut
  • monotouch-test/iOS - simulator/Release (managed static registrar, all optimizations): LaunchTimedOut
  • monotouch-test/iOS - simulator/Release (NativeAOT, x64): LaunchTimedOut
  • monotouch-test/iOS - simulator/Release (trimmable static registrar, NativeAOT, x64): LaunchTimedOut
  • monotouch-test/iOS - simulator/Debug (interpreter): LaunchTimedOut
  • monotouch-test/iOS - simulator/Release (interpreter): LaunchTimedOut

Html Report (VSDrops) Download

❌ monotouch tests (tvOS)

1 tests failed, 12 tests passed.

Failed tests

  • monotouch-test/tvOS - simulator/Release (managed static registrar, all optimizations): BuildFailure

Html Report (VSDrops) Download

Successes

✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (iOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (MacCatalyst): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (macOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (Multiple platforms): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (tvOS): All 1 tests passed. Html Report (VSDrops) Download
✅ framework: All 2 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 4 tests passed. Html Report (VSDrops) Download
✅ generator: All 5 tests passed. Html Report (VSDrops) Download
✅ interdependent-binding-projects: All 4 tests passed. Html Report (VSDrops) Download
✅ introspection: All 6 tests passed. Html Report (VSDrops) Download
✅ linker: All 44 tests passed. Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 18 tests passed. Html Report (VSDrops) Download
✅ monotouch (macOS): All 18 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
✅ sharpie: All 1 tests passed. Html Report (VSDrops) Download
✅ windows: All 3 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. Html Report (VSDrops) Download

macOS tests

✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Ventura (13): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Sonoma (14): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Sequoia (15): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Tahoe (26): All 5 tests passed. Html Report (VSDrops) Download

Linux Build Verification

Linux build succeeded

Pipeline on Agent
Hash: 2615017d672058379adadc357b7fc7124612bf38 [PR build]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

monotouch-test: random CoreCLR GC crash (maybe in MonoTouchFixtures.CoreAnimation.LayerTest?)

2 participants