-
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
[Hostfxr] [Windows] High CPU usage on background thread after invoking hostfxr_get_runtime_delegate
on non-main thread.
#39176
Comments
Tagging subscribers to this area: @vitek-karas, @swaroop-sridhar, @agocke |
Thanks a lot for the repro @Sewer56 . I debugged into it a little bit and it seems to be related to the diagnostic server thread. It loops in this callstack:
It calls the I don't know what's different running it from managed exe versus hosted via the hosting APIs - obviously a simple console app doesn't repro this. |
Tagging subscribers to this area: @tommcdon |
Indeed, would be interesting to know, even if at a high level. On an unrelated note. To trigger the correct, intended behaviour (no loop) simply load the runtime on main thread. i.e. replace initializeThreadHandle = CreateThread(nullptr, 0, &load_bootstrapper_async, 0, 0, nullptr);
WaitForSingleObject(initializeThreadHandle, INFINITE); with load_bootstrapper_async(0); in the example's entry point. I edited the opening post to reflect this. Explicitly, I set it up this way in the repro so it's easier to test & compare control flow. |
@dotnet/dotnet-diag @josalem |
Interesting! I haven't had a chance to try the repro since I'm on my Mac right now. @vitek-karas when you run this under the debugger, does a NamedPipe with a name like |
I put this under a debugger this afternoon. The server is being put into an error state where the overlapped IO is continually returning
In other words, the fact that you loaded the runtime on one thread but ended that thread broke the asynchronous IO. The abort is being recognized here at line 327: runtime/src/coreclr/src/vm/ipcstreamfactory.cpp Lines 324 to 330 in 50f82db
which unfortunately doesn't set This should be fixable by special casing the abort case and/or resetting the connection if the callback returns |
Description
In .NET 5, invoking
hostfxr_get_runtime_delegate
from a non-main thread appears to leave a background task running, consuming a full CPU thread.Specifically, the issue can be reproduced in the following fashion on Windows:
This does not occur if the runtime is initialised on the main thread.
Reproduction
Minimal reproduction is available at Reloaded.Core.Bootstrap/runtimebug.
Simply execute
Reloaded.Core.Bootstrap.Example
and observe CPU utilisation once the program begins to sleep.The offending function call that triggers the issue can be found at Reloaded.Core.Bootstrap/CoreCLR.cpp#L71.
(Requires Visual Studio 16.7 preview or newer, with
Desktop development with C++
workload as well as the latest .NET 5 SDK).Reproduction Debugging
To trigger the correct, intended behaviour (no loop/bug) simply load the runtime on main thread. i.e. replace
with
in the example's entry point.
I have set it up this way to make control flow comparisons easier between intended and unintended behaviour should that be helpful.
Configuration
Runtime: 5.0.0-preview.6
OS: Win 10 2004 (Build 19041.329)
Architecture: x86, x64
Regression?
This is a regression from .NET Core 3.X.
(i.e. Code runs as expected all the way from 3.0 Preview 6 when it became first available to the latest 3.1 release).
I have not yet identified the first .NET 5 Preview/build with the issue intact.
Images
.NET 5:
netcoreapp3.1:
netcoreapp3.0:
The text was updated successfully, but these errors were encountered: