-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
.NET 6 crashes on a macOS 12.x virtual machine on Apple Silicon (arm64) #64103
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Update: a workaround to avoid .NET 6 crashing in a macOS arm64 VM is to set the environment variable $ export COMPlus_ReadyToRun=0
$ dotnet --info
... |
@jgiannuzzi with the fix being in 6.0, can this issue be closed or is there still some remaining problem? |
@janvorli I can confirm that the problem is fully solved since Runtime 6.0.5 / SDK 6.0.300. |
Description
.NET 6 crashes when trying to run it in a macOS 12.x virtual machine on Apple Silicon (arm64). It works fine in a virtual machine on Intel (x64), or when running directly on the host.
Reproduction Steps
dotnet --info
and observe the crashExpected behavior
.NET 6 works as well in a virtual machine as it does on the host (aka it does not crash).
Actual behavior
Regression?
No response
Known Workarounds
COMPlus_ReadyToRun
to0
allows to run without crashing.Configuration
.NET 6.0.1
macOS 12.0.1
ARM64
Virtual Machine
Other information
The issue comes from the fact that ReadyToRun is broken in .NET 6 on Apple Silicon because of a memory protection mishandling issue, resulting in the JIT version of the assemblies being used instead. This memory protection mishandling issue does not happen when running in a virtual machine, which does result in the ReadyToRun section of assemblies to be loaded successfully.
Unfortunately, there is a second bug in the way variadic function arguments are passed on Apple Silicon, but this only gets triggered in ReadyToRun code, not in JIT code. It happens when a new object array gets created: JIT code will use
JIT_NewMDArrNonVarArg
, but ReadyToRun code will useJIT_NewMDArr
, passing variadic arguments in registers instead of on the stack, in contradiction to Apple's arm64 ABI guidelines. This results in the crash above.Needless to say, creating new object arrays is a pretty common operation in the .NET runtime 😅
A big side effect of this bug is that load times of .NET on Apple Silicon are slower than they should be (when running on the host of course), as only JIT version of the assemblies are used. This seems to have always been broken (since support for Apple Silicon was added to .NET).
After quite a bit of research in the background during these past 2 months, I have come up with a fix for these 2 issues.
Whilst rebasing on
main
, I have noticed that they got fixed independently in #61938 for the memory protection mishandling issue, and #62855 for the new object array creation.However those changes are impacting a much wider area of the runtime. I would thus advocate for backporting only the relevant changes to .NET 6, as it is the LTS release. Given the focus of that release on performance, and given that ReadyToRun has always been broken on Apple Silicon, I think that fixing .NET 6 would be the way to go, instead of waiting until .NET 7 is released.
I have created #64104 to address this issue.
The text was updated successfully, but these errors were encountered: