Publish GCHandle assignments with release semantics#130213
Merged
Merged
Conversation
GC handles can be observed by other threads after assignment. On weakly ordered ARM64 systems, a plain store to the handle slot can publish the object reference before prior object initialization writes are visible to the observing thread. Use VolatileStore when assigning handle slots in HndAssignHandle and HndAssignHandleGC so the handle publication is a release store. This matches the runtime's volatile publication pattern and prevents weak-reference readers from seeing partially initialized objects.
Contributor
|
Tagging subscribers to this area: @agocke |
This was referenced Jul 5, 2026
Member
|
/backport to release/10.0 |
Contributor
|
Started backporting to |
4 tasks
JulieLeeMSFT
pushed a commit
that referenced
this pull request
Jul 6, 2026
…130224) Backport of #130213 to release/10.0 /cc @jkotas @BradBarnich ## Customer Impact - [x] Customer reported - [ ] Found internally Stress failure found on Arm64 caused by weak memory model ## Regression - [ ] Yes - [x] No ## Testing Customer validated the fix in the affected workload ## Risk Low. Co-authored-by: Brad Barnich <brad@careevolution.com>
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.
Summary
Use release-store semantics when assigning GC handle slots in
HndAssignHandleandHndAssignHandleGC.On weakly ordered ARM64 systems, the previous plain store could publish an object reference through a GC handle before prior object initialization writes were visible to another thread observing that handle.
This can allow weak-reference readers to see partially initialized managed objects.
Details
GC handle assignment stores the raw object reference into the handle slot with a plain store:
https://github.com/dotnet/runtime/blob/main/src/coreclr/gc/handletable.inl#L47
This changes that store to VolatileStore, making handle assignment a release publication point:
VolatileStore((_UNCHECKED_OBJECTREF *)handle, value);This matches the runtime's existing volatile publication pattern and ensures prior writes are visible before another thread can observe the object through the handle.
Discovered this via rare NullReferenceExceptions in Regex.Replace in an application when running on arm64 (10.0.9). The repro for that is https://gist.github.com/BradBarnich/4e6368d7e3ae5a32896852c146e0eb3f. It can take a lot of time to produce an error but was most reliable on graviton4. Never did produce on Mac.
This produced a dump file that showed the partial object (null ._rules) and focuses the analysis on the WeakReference
There is a shared WeakReference to RegexReplacement and the exception was thrown when it would sometimes observe a partially constructed RegexReplacement. The
WeakReference.SetTargetis called after construction https://github.com/dotnet/runtime/blob/main/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexReplacement.cs#L107-L117Internally
WeakReference.SetTargetcallsGCHandle.InternalSethttps://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/WeakReference.T.cs#L120Validation
Validated with a focused WeakReference publication repro https://gist.github.com/BradBarnich/ccd7e3811cfbe4142ff7c85ec8305c76
Without the patch, the repro fails quickly on Mac and AWS arm64. Does not fail on x64.
When the patch, does not fail on Mac or AWS arm64