corert
corert copied to clipboard
Main thread Thread::WaitForGC infinitely
I had a demo MonoGame 3.8 game project and try CoreRT with it.
The game use two thread loops, one is a background thread for sending draw commands to a ConcurrentQueue, another is the game loop in main thread that receive draw commands from ConcurrentQueue and draw the game.
After compiled with CoreRT and run, the window just freezed and nothing was showed. Then I debug it with vscode and it seems the Main thread stuck on Thread::WaitForGC, sometimes stuck on ThreadStore::WaitForSuspendComplete.
I've noticed that the background thread, which is MirGameTemplate.WindowsDX.exe!MirEngine_MirEngine_GameBase__ActiveSceneDrawLoop() in the following stack trace, is not suspended and is running in a intential inifinite loop. If I put a Thread.Sleep(1) in this loop then everything is working.
Here is a stack trace of threads:
Main Thread
ntdll.dll!00007fff7bb6be44() (未知源:0)
KernelBase.dll!00007fff795626ee() (未知源:0)
MirGameTemplate.WindowsDX.exe!Thread::WaitForGC(void * pTransitionFrame) Line 89 (e:\a\_work\103\s\corert_4026918\src\native\runtime\thread.cpp:89)
MirGameTemplate.WindowsDX.exe!RhpWaitForGC2(PInvokeTransitionFrame * pFrame) Line 979 (e:\a\_work\103\s\corert_4026918\src\native\runtime\thread.cpp:979)
MirGameTemplate.WindowsDX.exe!RhpWaitForGCNoAbort() Line 84 (e:\A\_work\103\s\corert_4026918\src\Native\Runtime\amd64\PInvoke.asm:84)
MirGameTemplate.WindowsDX.exe!RhpWaitForGC() Line 114 (e:\A\_work\103\s\corert_4026918\src\Native\Runtime\amd64\PInvoke.asm:114)
MirGameTemplate.WindowsDX.exe!Internal_CompilerGenerated__Module___<Calli>UnmanagedCallingConventionStdCall, Static<Int32__S_P_CoreLib_System_Void<Pointer>__S_P_CoreLib_System_Void<Pointer>__S_P_CoreLib_System_Void<Pointer>__S_P_CoreLib_System_Void<Pointer>>() (未知源:0)
MirGameTemplate.WindowsDX.exe!SharpDX_Direct3D11_SharpDX_Direct3D11_Device__CreateBuffer() (未知源:0)
MirGameTemplate.WindowsDX.exe!SharpDX_Direct3D11_SharpDX_Direct3D11_Buffer___ctor_2() (未知源:0)
MirGameTemplate.WindowsDX.exe!MonoGame_Framework_Microsoft_Xna_Framework_Graphics_VertexBuffer__GenerateIfRequired() Line 49 (d:\MonoGame\MonoGame\MonoGame.Framework\Platform\Graphics\Vertices\VertexBuffer.DirectX.cs:49)
MirGameTemplate.WindowsDX.exe!MonoGame_Framework_Microsoft_Xna_Framework_Graphics_GraphicsDevice__SetUserVertexBuffer<MonoGame_Framework_Microsoft_Xna_Framework_Graphics_VertexPositionColorTexture>() Line 1385 (d:\MonoGame\MonoGame\MonoGame.Framework\Platform\Graphics\GraphicsDevice.DirectX.cs:1385)
MirGameTemplate.WindowsDX.exe!MonoGame_Framework_Microsoft_Xna_Framework_Graphics_GraphicsDevice__PlatformDrawUserIndexedPrimitives<MonoGame_Framework_Microsoft_Xna_Framework_Graphics_VertexPositionColorTexture>() Line 1502 (d:\MonoGame\MonoGame\MonoGame.Framework\Platform\Graphics\GraphicsDevice.DirectX.cs:1502)
MirGameTemplate.WindowsDX.exe!MonoGame_Framework_Microsoft_Xna_Framework_Graphics_GraphicsDevice__DrawUserIndexedPrimitives_0<MonoGame_Framework_Microsoft_Xna_Framework_Graphics_VertexPositionColorTexture>() Line 1218 (d:\MonoGame\MonoGame\MonoGame.Framework\Graphics\GraphicsDevice.cs:1218)
MirGameTemplate.WindowsDX.exe!MonoGame_Framework_Microsoft_Xna_Framework_Graphics_SpriteBatcher__FlushVertexArray() Line 285 (d:\MonoGame\MonoGame\MonoGame.Framework\Graphics\SpriteBatcher.cs:285)
MirGameTemplate.WindowsDX.exe!MonoGame_Framework_Microsoft_Xna_Framework_Graphics_SpriteBatcher__DrawBatch() Line 209 (d:\MonoGame\MonoGame\MonoGame.Framework\Graphics\SpriteBatcher.cs:209)
MirGameTemplate.WindowsDX.exe!MirEngine_MirEngine_Engine__ExecuteCommandBuffer() Line 346 (d:\xxx\xxxEngine\xxxEngine\Engine.cs:346)
MirGameTemplate.WindowsDX.exe!MirEngine_MirEngine_GameBase__EndDraw() Line 290 (d:\xxx\MirEngine\MirEngine\GameBase.cs:290)
MirGameTemplate.WindowsDX.exe!MonoGame_Framework_Microsoft_Xna_Framework_Game__Tick() Line 611 (d:\MonoGame\MonoGame\MonoGame.Framework\Game.cs:611)
MirGameTemplate.WindowsDX.exe!MonoGame_Framework_MonoGame_Framework_WinFormsGameWindow__TickOnIdle() Line 479 (d:\MonoGame\MonoGame\MonoGame.Framework\Platform\Windows\WinFormsGameWindow.cs:479)
MirGameTemplate.WindowsDX.exe!System_Windows_Forms_System_Windows_Forms_Application_ThreadContext__System_Windows_Forms_UnsafeNativeMethods_IMsoComponent_FDoIdle() (未知源:0)
MirGameTemplate.WindowsDX.exe!System_Windows_Forms_System_Windows_Forms_Application_ComponentManager__System_Windows_Forms_UnsafeNativeMethods_IMsoComponentManager_FPushMessageLoop() (未知源:0)
MirGameTemplate.WindowsDX.exe!System_Windows_Forms_System_Windows_Forms_Application_ThreadContext__RunMessageLoopInner() (未知源:0)
MirGameTemplate.WindowsDX.exe!System_Windows_Forms_System_Windows_Forms_Application_ThreadContext__RunMessageLoop() (未知源:0)
MirGameTemplate.WindowsDX.exe!MonoGame_Framework_MonoGame_Framework_WinFormsGameWindow__RunLoop() Line 450 (d:\MonoGame\MonoGame\MonoGame.Framework\Platform\Windows\WinFormsGameWindow.cs:450)
MirGameTemplate.WindowsDX.exe!MonoGame_Framework_Microsoft_Xna_Framework_Game__Run_0() Line 482 (d:\MonoGame\MonoGame\MonoGame.Framework\Game.cs:482)
MirGameTemplate.WindowsDX.exe!MirGameTemplate_WindowsDX_MirGameTemplate_WindowsDX_Program__Main() Line 11 (d:\xxx\MirEngine\MirGameTemplate.WindowsDX\Program.cs:11)
MirGameTemplate.WindowsDX.exe!MirGameTemplate_WindowsDX__Module___StartupCodeMain() (未知源:0)
MirGameTemplate.WindowsDX.exe!wmain(int argc, wchar_t * * argv) Line 440 (e:\a\_work\103\s\corert_4026918\src\native\bootstrap\main.cpp:440)
[Inline Frame] MirGameTemplate.WindowsDX.exe!invoke_main() Line 90 (d:\agent\_work\9\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:90)
MirGameTemplate.WindowsDX.exe!__scrt_common_main_seh() Line 288 (d:\agent\_work\9\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288)
kernel32.dll!00007fff7ae16fd4() (未知源:0)
ntdll.dll!00007fff7bb1cec1() (未知源:0)
MirGameTemplate.Windows.DX.exe!FinalizerStart
ntdll.dll!00007fff7bb6be44() (未知源:0)
KernelBase.dll!00007fff795626ee() (未知源:0)
[Inline Frame] MirGameTemplate.WindowsDX.exe!PalWaitForSingleObjectEx(void * arg1, unsigned int) (未知源:0)
MirGameTemplate.WindowsDX.exe!RhpWaitForFinalizerRequest() Line 203 (e:\a\_work\103\s\corert_4026918\src\native\runtime\finalizerhelpers.cpp:203)
MirGameTemplate.WindowsDX.exe!ProcessFinalizers() (未知源:0)
MirGameTemplate.WindowsDX.exe!FinalizerStart(void * pContext) Line 72 (e:\a\_work\103\s\corert_4026918\src\native\runtime\finalizerhelpers.cpp:72)
kernel32.dll!00007fff7ae16fd4() (未知源:0)
ntdll.dll!00007fff7bb1cec1() (未知源:0)
MirGameTemplate.WindowsDX.exe!S_P_CoreLib_System_Threading_Thread_ThreadEntryPoint
ntdll.dll!00007fff7bb6be44() (未知源:0)
KernelBase.dll!00007fff795626ee() (未知源:0)
MirGameTemplate.WindowsDX.exe!Thread::WaitForGC(void * pTransitionFrame) Line 89 (e:\a\_work\103\s\corert_4026918\src\native\runtime\thread.cpp:89)
MirGameTemplate.WindowsDX.exe!RhpWaitForGC2(PInvokeTransitionFrame * pFrame) Line 979 (e:\a\_work\103\s\corert_4026918\src\native\runtime\thread.cpp:979)
MirGameTemplate.WindowsDX.exe!RhpWaitForGCNoAbort() Line 84 (e:\A\_work\103\s\corert_4026918\src\Native\Runtime\amd64\PInvoke.asm:84)
MirGameTemplate.WindowsDX.exe!RhpWaitForGC() Line 114 (e:\A\_work\103\s\corert_4026918\src\Native\Runtime\amd64\PInvoke.asm:114)
MirGameTemplate.WindowsDX.exe!Microsoft_Win32_SystemEvents_Interop_User32__MsgWaitForMultipleObjectsEx() (未知源:0)
MirGameTemplate.WindowsDX.exe!Microsoft_Win32_SystemEvents_Microsoft_Win32_SystemEvents__WindowThreadProc() (未知源:0)
MirGameTemplate.WindowsDX.exe!S_P_CoreLib_System_Threading_Thread__StartThread() (未知源:0)
MirGameTemplate.WindowsDX.exe!S_P_CoreLib_System_Threading_Thread__ThreadEntryPoint() (未知源:0)
kernel32.dll!00007fff7ae16fd4() (未知源:0)
ntdll.dll!00007fff7bb1cec1() (未知源:0)
*MirGameTemplate.WindowsDX.exe!unsigned int
ntdll.dll!00007fff7bb6f534() (未知源:0)
KernelBase.dll!00007fff795bbe20() (未知源:0)
MirGameTemplate.WindowsDX.exe!PalHijack(void * hThread, unsigned int(*)(void *, PAL_LIMITED_CONTEXT *, void *) callback, void * pCallbackContext) Line 330 (e:\a\_work\103\s\corert_4026918\src\native\runtime\windows\palredhawkminwin.cpp:330)
MirGameTemplate.WindowsDX.exe!Thread::Hijack() Line 648 (e:\a\_work\103\s\corert_4026918\src\native\runtime\thread.cpp:648)
MirGameTemplate.WindowsDX.exe!ThreadStore::SuspendAllThreads(bool waitForGCEvent, bool fireDebugEvent) Line 263 (e:\a\_work\103\s\corert_4026918\src\native\runtime\threadstore.cpp:263)
MirGameTemplate.WindowsDX.exe!GCToEEInterface::SuspendEE(SUSPEND_REASON reason) Line 809 (e:\a\_work\103\s\corert_4026918\src\native\runtime\gcrhenv.cpp:809)
[Inline Frame] MirGameTemplate.WindowsDX.exe!WKS::gc_heap::bgc_suspend_EE() (未知源:0)
MirGameTemplate.WindowsDX.exe!WKS::gc_heap::background_mark_phase() Line 26483 (e:\a\_work\103\s\corert_4026918\src\native\gc\gc.cpp:26483)
MirGameTemplate.WindowsDX.exe!WKS::gc_heap::gc1() Line 16153 (e:\a\_work\103\s\corert_4026918\src\native\gc\gc.cpp:16153)
MirGameTemplate.WindowsDX.exe!WKS::gc_heap::bgc_thread_function() Line 27540 (e:\a\_work\103\s\corert_4026918\src\native\gc\gc.cpp:27540)
MirGameTemplate.WindowsDX.exe!GCToEEInterface::CreateThread::__l2::<lambda>(void * argument) Line 1349 (e:\a\_work\103\s\corert_4026918\src\native\runtime\gcrhenv.cpp:1349)
kernel32.dll!00007fff7ae16fd4() (未知源:0)
ntdll.dll!00007fff7bb1cec1() (未知源:0)
MirGameTemplate.WindowsDX.exe!S_P_CoreLib_System_Threading_Thread_ThreadEntryPoint
MirGameTemplate.WindowsDX.exe!MirEngine_MirEngine_GameBase__ActiveSceneDrawLoop() Line 250 (d:\xxx\MirEngine\MirEngine\GameBase.cs:250)
MirGameTemplate.WindowsDX.exe!RhpGcProbeHijackScalar() Line 152 (e:\A\_work\103\s\corert_4026918\src\Native\Runtime\amd64\GcProbe.asm:152)
The long running uninterrupted computation will run into problems though. For example, if the program has infinite loop for(;;) { } on one thread and allocates on a second thread, the GC thread suspension will hang in CoreRT today https://github.com/dotnet/corert/issues/7807#issuecomment-537646340
@jkotas So this GC suspension hanging bug still exists in current CoreRT?
Yes, this problem still exists in current CoreRT.
Got it. Thanks for reply.
I managed to make this game demo works in .NET Native in UWP before.
.NET Native has the codegen+runtime feature necessary for the GC to be able to make progress in a case like this. CoreRT has a different codegen so this requires extra work that hasn't happened yet.