-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NativeAOT ComWrappers: fix race condition in when creating native wrapper #85235
Conversation
…nstance If a ComWrapper for a native object becomes unrooted, the GCHandle in _rcwCache can be nulled out by a GC. If a new wrapper is created using GetOrCreateObjectForComInstance before the NativeObjectWrapper finializer has a chance to run, a null value could be return from GetOrCreateObjectForComInstance.
Thinking about this a bit more, the finializer will remove the new object from the cache. So this is not a correct solution. |
Once I've merged in #85000, I'll re-trigger CI and the outerloop with this change (as that PR adds a lot of test coverage for ComWrappers on NativeAOT). |
I think this should work correctly now. The finalizer for NativeObjectWrapper will now only remove its own GCHandle from the cache. |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run runtime |
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The legs I wanted to pass have passed and the code looks good!
There is a failure in System.Runtime.InteropServices.Tests in the Build windows-x64 Release NativeAOT_Checked_Libs_SizeOpt leg that looks a little bit concerning:
We have a dump that can be pulled down with
Does it look familiar to anyone? Cc @dotnet/ilc-contrib |
This is a code path that was recently added in #85087 . Before this change the GC restricted callout code for ref counted handles was not being used (Obective-C interop has its own way of calling managed code from the GC). |
@MichalStrehovsky is there a special attribute we need to put on a method other than/in addition to UnmanagedCallersOnly for GC callouts? |
Do you want to suppress the reverse p/invoke transition? Putting the SuppressGCTransition callconv on it might do it if RyuJIT respects that. |
It is a bug in the |
Opened an issue to track the problem at #85377 |
In other places we assume that
An interesting issue when a GC callout needs to call native code. |
This comment is wrong. Reverse PInvoke was always allowed in "do not trigger GC" regions. |
We use
The end result is the same - we should fix reverse prinvoke to allow GC threads to return without waiting for GC, instead of asserting. |
If a ComWrapper for a native object becomes unrooted, the GCHandle in
_rcwCache
can be nulled out by the GC. If a new wrapper is created usingGetOrCreateObjectForComInstance
before theNativeObjectWrapper
finializer has a chance to run, a null value could be returned fromGetOrCreateObjectForComInstance
.This PR adds test that passes on the main branch using CoreCLR but fails under NativeAOT. After this change, the test passes for NativeAOT as well.