From 0d014b6a73936437266221a75a7b725a00e85ffa Mon Sep 17 00:00:00 2001 From: vsadov <8218165+VSadov@users.noreply.github.com> Date: Tue, 13 May 2025 19:01:03 -0700 Subject: [PATCH 1/6] fix --- src/coreclr/vm/ceemain.cpp | 76 +++++++++++++++++++------------------- src/coreclr/vm/syncblk.cpp | 7 ---- 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 53f192d8bc976f..1c25bda06a8980 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -837,35 +837,6 @@ void EEStartupHelper() InitializeDebugger(); // throws on error #endif // DEBUGGING_SUPPORTED -#ifdef PROFILING_SUPPORTED - // Initialize the profiling services. - hr = ProfilingAPIUtility::InitializeProfiling(); - - _ASSERTE(SUCCEEDED(hr)); - IfFailGo(hr); -#endif // PROFILING_SUPPORTED - - InitializeExceptionHandling(); - - // - // Install our global exception filter - // - if (!InstallUnhandledExceptionFilter()) - { - IfFailGo(E_FAIL); - } - - // throws on error - SetupThread(); - -#ifdef DEBUGGING_SUPPORTED - // Notify debugger once the first thread is created to finish initialization. - if (g_pDebugInterface != NULL) - { - g_pDebugInterface->StartupPhase2(GetThread()); - } -#endif - // This isn't done as part of InitializeGarbageCollector() above because // debugger must be initialized before creating EE thread objects FinalizerThread::FinalizerThreadCreate(); @@ -882,8 +853,6 @@ void EEStartupHelper() // of the JIT helpers. InitJITHelpers1(); - SyncBlockCache::Attach(); - // Set up the sync block SyncBlockCache::Start(); @@ -898,6 +867,43 @@ void EEStartupHelper() IfFailGo(hr); +#ifdef PROFILING_SUPPORTED + // Initialize the profiling services. + hr = ProfilingAPIUtility::InitializeProfiling(); + + _ASSERTE(SUCCEEDED(hr)); + IfFailGo(hr); +#endif // PROFILING_SUPPORTED + + InitializeExceptionHandling(); + + // + // Install our global exception filter + // + if (!InstallUnhandledExceptionFilter()) + { + IfFailGo(E_FAIL); + } + +#ifdef TARGET_WINDOWS + // g_pGCHeap->Initialize() above could take nontrivial time, so by now the finalizer thread + // should have initialized FLS slot for thread cleanup notifications. + // And ensured that COM is initialized (must happen before allocating FLS slot). + // Make sure that this was done. + FinalizerThread::WaitForFinalizerThreadStart(); +#endif + + // throws on error + SetupThread(); + +#ifdef DEBUGGING_SUPPORTED + // Notify debugger once the first thread is created to finish initialization. + if (g_pDebugInterface != NULL) + { + g_pDebugInterface->StartupPhase2(GetThread()); + } +#endif + #ifdef FEATURE_PERFTRACING // Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup. // SampleProfiler needs to cooperate with the GC which hasn't fully finished setting up in the first part of the @@ -957,12 +963,6 @@ void EEStartupHelper() g_MiniMetaDataBuffMaxSize, MEM_COMMIT, PAGE_READWRITE); #endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS -#ifdef TARGET_WINDOWS - // By now finalizer thread should have initialized FLS slot for thread cleanup notifications. - // And ensured that COM is initialized (must happen before allocating FLS slot). - // Make sure that this was done. - FinalizerThread::WaitForFinalizerThreadStart(); -#endif g_fEEStarted = TRUE; g_EEStartupStatus = S_OK; hr = S_OK; @@ -1764,6 +1764,8 @@ void InitFlsSlot() // thread - thread to attach static void OsAttachThread(void* thread) { + _ASSERTE(g_flsIndex != FLS_OUT_OF_INDEXES); + if (t_flsState == FLS_STATE_INVOKED) { _ASSERTE_ALL_BUILDS(!"Attempt to execute managed code after the .NET runtime thread state has been destroyed."); diff --git a/src/coreclr/vm/syncblk.cpp b/src/coreclr/vm/syncblk.cpp index 0d4e05a3bd4382..3839b0572b17c8 100644 --- a/src/coreclr/vm/syncblk.cpp +++ b/src/coreclr/vm/syncblk.cpp @@ -591,13 +591,6 @@ void SyncBlockCache::CleanupSyncBlocks() } EE_END_FINALLY; } -// create the sync block cache -/* static */ -void SyncBlockCache::Attach() -{ - LIMITED_METHOD_CONTRACT; -} - // create the sync block cache /* static */ void SyncBlockCache::Start() From b148eff3b6fb03b90b6178eba6ef0d405c5ab7d5 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Fri, 16 May 2025 09:27:18 -0700 Subject: [PATCH 2/6] PR feedback Co-authored-by: Jan Kotas --- src/coreclr/vm/ceemain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 1c25bda06a8980..375ccc20ddccc8 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -894,6 +894,7 @@ void EEStartupHelper() #endif // throws on error + _ASSERTE(GetThreadNULLOk() == NULL); SetupThread(); #ifdef DEBUGGING_SUPPORTED From 6642dcd27d2093badcacb22337a15fd2de902b91 Mon Sep 17 00:00:00 2001 From: vsadov <8218165+VSadov@users.noreply.github.com> Date: Fri, 16 May 2025 19:08:58 -0700 Subject: [PATCH 3/6] moved profiler init before FinalizerThreadCreate --- src/coreclr/vm/ceemain.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 375ccc20ddccc8..2fd1a4c730caf9 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -837,6 +837,15 @@ void EEStartupHelper() InitializeDebugger(); // throws on error #endif // DEBUGGING_SUPPORTED +#ifdef PROFILING_SUPPORTED + // Initialize the profiling services. + // THis must happen before the finalizer thread is stopped on its first wait. + hr = ProfilingAPIUtility::InitializeProfiling(); + + _ASSERTE(SUCCEEDED(hr)); + IfFailGo(hr); +#endif // PROFILING_SUPPORTED + // This isn't done as part of InitializeGarbageCollector() above because // debugger must be initialized before creating EE thread objects FinalizerThread::FinalizerThreadCreate(); @@ -867,14 +876,6 @@ void EEStartupHelper() IfFailGo(hr); -#ifdef PROFILING_SUPPORTED - // Initialize the profiling services. - hr = ProfilingAPIUtility::InitializeProfiling(); - - _ASSERTE(SUCCEEDED(hr)); - IfFailGo(hr); -#endif // PROFILING_SUPPORTED - InitializeExceptionHandling(); // From fdec3bdf9eaa6803c4b0f3c23fe2e00a8d11d064 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Tue, 20 May 2025 15:48:43 -0700 Subject: [PATCH 4/6] Update src/coreclr/vm/ceemain.cpp Co-authored-by: Jan Kotas --- src/coreclr/vm/ceemain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 2fd1a4c730caf9..c32c13f1f57b07 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -839,7 +839,7 @@ void EEStartupHelper() #ifdef PROFILING_SUPPORTED // Initialize the profiling services. - // THis must happen before the finalizer thread is stopped on its first wait. + // This must happen before Thread::HasStarted() that fires profiler notifications is called on the finalizer thread. hr = ProfilingAPIUtility::InitializeProfiling(); _ASSERTE(SUCCEEDED(hr)); From 4fc42cc854ccaf7960eb211586a8d1e54e0f9bf8 Mon Sep 17 00:00:00 2001 From: vsadov <8218165+VSadov@users.noreply.github.com> Date: Tue, 20 May 2025 16:04:54 -0700 Subject: [PATCH 5/6] create finalizer thread earlier only on Windows. --- src/coreclr/vm/ceemain.cpp | 21 ++++++++++++++++++--- src/coreclr/vm/finalizerthread.cpp | 1 + 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index c32c13f1f57b07..326d251a2d4a50 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -846,9 +846,12 @@ void EEStartupHelper() IfFailGo(hr); #endif // PROFILING_SUPPORTED - // This isn't done as part of InitializeGarbageCollector() above because - // debugger must be initialized before creating EE thread objects +#ifdef TARGET_WINDOWS + // Create the finalizer thread on windows earlier, as we will need to wait for + // the completion of its initialization part that initializes COM as that has to be done + // before the first Thread is attached. Thus we want to give the thread a bit more time. FinalizerThread::FinalizerThreadCreate(); +#endif InitPreStubManager(); @@ -890,7 +893,9 @@ void EEStartupHelper() // g_pGCHeap->Initialize() above could take nontrivial time, so by now the finalizer thread // should have initialized FLS slot for thread cleanup notifications. // And ensured that COM is initialized (must happen before allocating FLS slot). - // Make sure that this was done. + // Make sure that this was done before we start creating Thread objects + // Ex: The call to SetupThread below will create and attach a Thread object. + // Event pipe might also do that. FinalizerThread::WaitForFinalizerThreadStart(); #endif @@ -906,6 +911,16 @@ void EEStartupHelper() } #endif +#ifndef TARGET_WINDOWS + // This isn't done as part of InitializeGarbageCollector() above because + // debugger must be initialized before creating EE thread objects + FinalizerThread::FinalizerThreadCreate(); +#else + // On windows the finalizer thread is already partially created created and is waiting + // right before doing HasStarted(). We will release it now. + FinalizerThread::EnableFinalization(); +#endif + #ifdef FEATURE_PERFTRACING // Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup. // SampleProfiler needs to cooperate with the GC which hasn't fully finished setting up in the first part of the diff --git a/src/coreclr/vm/finalizerthread.cpp b/src/coreclr/vm/finalizerthread.cpp index db45c4c0d8d9a1..4a445d9bc08754 100644 --- a/src/coreclr/vm/finalizerthread.cpp +++ b/src/coreclr/vm/finalizerthread.cpp @@ -392,6 +392,7 @@ DWORD WINAPI FinalizerThread::FinalizerThreadStart(void *args) // handshake with EE initialization, as now we can attach Thread objects to native threads. hEventFinalizerDone->Set(); + WaitForFinalizerEvent (hEventFinalizer); #endif s_FinalizerThreadOK = GetFinalizerThread()->HasStarted(); From e119a35feb497d6567b19121c39eb277bffdc9bf Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Tue, 20 May 2025 16:39:57 -0700 Subject: [PATCH 6/6] Update src/coreclr/vm/ceemain.cpp Co-authored-by: Jan Kotas --- src/coreclr/vm/ceemain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 326d251a2d4a50..5f334584a3f709 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -916,7 +916,7 @@ void EEStartupHelper() // debugger must be initialized before creating EE thread objects FinalizerThread::FinalizerThreadCreate(); #else - // On windows the finalizer thread is already partially created created and is waiting + // On windows the finalizer thread is already partially created and is waiting // right before doing HasStarted(). We will release it now. FinalizerThread::EnableFinalization(); #endif