[DO NOT MERGE] Instrument __MonoMac_NSAsyncActionDispatcher for issue #25861#25919
[DO NOT MERGE] Instrument __MonoMac_NSAsyncActionDispatcher for issue #25861#25919rolfbjarne wants to merge 7 commits into
Conversation
…25861 Add throwaway instrumentation to diagnose the GC/marshalling race in #25861. For every async dispatcher, record the creation stack trace and a log of lifecycle events (Apply/Dispose/Finalize). This is stored directly on the native Objective-C object via an associated reference, so it survives even after the managed instance is garbage collected. When the marshalling exception from the issue is raised (MissingCtor), this information is appended to the error message. 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.
…/issue-25861-instrumentation
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.
… objc associated objects The previous approach stored the diagnostic info on the native object via objc_setAssociatedObject with OBJC_ASSOCIATION_RETAIN. Reading it back with objc_getAssociatedObject deterministically segfaulted in objc_msgSend_uncached on the normal Apply path, crashing every test that dispatches an async action. Replace the objc-associated-object mechanism with a static managed dictionary keyed by the native handle (IntPtr). This still survives GC of the managed dispatcher instance (the key is the native pointer, the value is a string, so it does not keep the managed object alive), but performs no Objective-C calls and therefore cannot crash. Verified: tests/linker "dont link" MacCatalyst now passes (9/9) instead of segfaulting at startup. 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.
…/issue-25861-instrumentation
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.
…/issue-25861-instrumentation
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.
…/issue-25861-instrumentation
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.
…/issue-25861-instrumentation
This comment has been minimized.
This comment has been minimized.
✅ [PR Build #f227cd0] Build passed (Detect API changes) ✅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 #f227cd0] Build passed (Build packages) ✅Pipeline on Agent |
✅ [PR Build #f227cd0] Build passed (Build macOS tests) ✅Pipeline on Agent |
🔥 [CI Build #f227cd0] Test results 🔥Test results❌ Tests failed on VSTS: test results 0 tests crashed, 5 tests failed, 194 tests passed. Failures❌ monotouch tests (iOS)1 tests failed, 17 tests passed.Failed tests
Html Report (VSDrops) Download ❌ monotouch tests (tvOS)4 tests failed, 14 tests passed.Failed tests
Html Report (VSDrops) Download Successes✅ assembly-processing: 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 |
Throwaway diagnostic instrumentation to help reproduce and diagnose the GC/marshalling race in the flaky
NSAsyncActionDispatcherfailure.The goal is to catch the failure on CI and learn:
__MonoMac_NSAsyncActionDispatcheris instantiated (creation stack trace), and whether it's always the same call site.How it works
src/Foundation/NSAsyncDispatcherInstrumentation.cs: stores diagnostic data directly on the native Objective-C object via an associated reference (objc_setAssociatedObject), so it survives even after the managed instance is garbage collected.NSAsyncDispatcher(inNSAction.cs) records the creation stack trace in its constructor, and logs lifecycle events (Apply,Dispose, finalize) as they happen.MissingCtor(inRuntime.cs) reads this info from the still-alive native object and appends it to the marshalling exception message.Ref: #25861
🤖 Pull request created by Copilot