Skip to content

Commit b161846

Browse files
mangod9VSadovjkotas
authored
[9.0] Backport 115546 FLS initialization fix to 9. (#116872)
* Move FLS init before EventPipeAdapter::FinishInitialize and the first SetupThread() (#115546) * fix * PR feedback Co-authored-by: Jan Kotas <[email protected]> * moved profiler init before FinalizerThreadCreate * Update src/coreclr/vm/ceemain.cpp Co-authored-by: Jan Kotas <[email protected]> * create finalizer thread earlier only on Windows. * Update src/coreclr/vm/ceemain.cpp Co-authored-by: Jan Kotas <[email protected]> --------- Co-authored-by: Jan Kotas <[email protected]> * Fix merge conflict --------- Co-authored-by: Vladimir Sadov <[email protected]> Co-authored-by: Jan Kotas <[email protected]>
1 parent 3f2f679 commit b161846

File tree

3 files changed

+51
-38
lines changed

3 files changed

+51
-38
lines changed

src/coreclr/vm/ceemain.cpp

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -862,36 +862,19 @@ void EEStartupHelper()
862862

863863
#ifdef PROFILING_SUPPORTED
864864
// Initialize the profiling services.
865+
// This must happen before Thread::HasStarted() that fires profiler notifications is called on the finalizer thread.
865866
hr = ProfilingAPIUtility::InitializeProfiling();
866867

867868
_ASSERTE(SUCCEEDED(hr));
868869
IfFailGo(hr);
869870
#endif // PROFILING_SUPPORTED
870871

871-
InitializeExceptionHandling();
872-
873-
//
874-
// Install our global exception filter
875-
//
876-
if (!InstallUnhandledExceptionFilter())
877-
{
878-
IfFailGo(E_FAIL);
879-
}
880-
881-
// throws on error
882-
SetupThread();
883-
884-
#ifdef DEBUGGING_SUPPORTED
885-
// Notify debugger once the first thread is created to finish initialization.
886-
if (g_pDebugInterface != NULL)
887-
{
888-
g_pDebugInterface->StartupPhase2(GetThread());
889-
}
890-
#endif
891-
892-
// This isn't done as part of InitializeGarbageCollector() above because
893-
// debugger must be initialized before creating EE thread objects
872+
#ifdef TARGET_WINDOWS
873+
// Create the finalizer thread on windows earlier, as we will need to wait for
874+
// the completion of its initialization part that initializes COM as that has to be done
875+
// before the first Thread is attached. Thus we want to give the thread a bit more time.
894876
FinalizerThread::FinalizerThreadCreate();
877+
#endif
895878

896879
InitPreStubManager();
897880

@@ -906,8 +889,6 @@ void EEStartupHelper()
906889
InitJITHelpers1();
907890
InitJITHelpers2();
908891

909-
SyncBlockCache::Attach();
910-
911892
// Set up the sync block
912893
SyncBlockCache::Start();
913894

@@ -922,6 +903,48 @@ void EEStartupHelper()
922903

923904
IfFailGo(hr);
924905

906+
InitializeExceptionHandling();
907+
908+
//
909+
// Install our global exception filter
910+
//
911+
if (!InstallUnhandledExceptionFilter())
912+
{
913+
IfFailGo(E_FAIL);
914+
}
915+
916+
#ifdef TARGET_WINDOWS
917+
// g_pGCHeap->Initialize() above could take nontrivial time, so by now the finalizer thread
918+
// should have initialized FLS slot for thread cleanup notifications.
919+
// And ensured that COM is initialized (must happen before allocating FLS slot).
920+
// Make sure that this was done before we start creating Thread objects
921+
// Ex: The call to SetupThread below will create and attach a Thread object.
922+
// Event pipe might also do that.
923+
FinalizerThread::WaitForFinalizerThreadStart();
924+
#endif
925+
926+
// throws on error
927+
_ASSERTE(GetThreadNULLOk() == NULL);
928+
SetupThread();
929+
930+
#ifdef DEBUGGING_SUPPORTED
931+
// Notify debugger once the first thread is created to finish initialization.
932+
if (g_pDebugInterface != NULL)
933+
{
934+
g_pDebugInterface->StartupPhase2(GetThread());
935+
}
936+
#endif
937+
938+
#ifndef TARGET_WINDOWS
939+
// This isn't done as part of InitializeGarbageCollector() above because
940+
// debugger must be initialized before creating EE thread objects
941+
FinalizerThread::FinalizerThreadCreate();
942+
#else
943+
// On windows the finalizer thread is already partially created and is waiting
944+
// right before doing HasStarted(). We will release it now.
945+
FinalizerThread::EnableFinalization();
946+
#endif
947+
925948
#ifdef FEATURE_PERFTRACING
926949
// Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup.
927950
// SampleProfiler needs to cooperate with the GC which hasn't fully finished setting up in the first part of the
@@ -982,12 +1005,6 @@ void EEStartupHelper()
9821005
g_MiniMetaDataBuffMaxSize, MEM_COMMIT, PAGE_READWRITE);
9831006
#endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
9841007

985-
#ifdef TARGET_WINDOWS
986-
// By now finalizer thread should have initialized FLS slot for thread cleanup notifications.
987-
// And ensured that COM is initialized (must happen before allocating FLS slot).
988-
// Make sure that this was done.
989-
FinalizerThread::WaitForFinalizerThreadStart();
990-
#endif
9911008
g_fEEStarted = TRUE;
9921009
g_EEStartupStatus = S_OK;
9931010
hr = S_OK;
@@ -1794,6 +1811,8 @@ void InitFlsSlot()
17941811
// thread - thread to attach
17951812
static void OsAttachThread(void* thread)
17961813
{
1814+
_ASSERTE(g_flsIndex != FLS_OUT_OF_INDEXES);
1815+
17971816
if (t_flsState == FLS_STATE_INVOKED)
17981817
{
17991818
_ASSERTE_ALL_BUILDS(!"Attempt to execute managed code after the .NET runtime thread state has been destroyed.");

src/coreclr/vm/finalizerthread.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ DWORD WINAPI FinalizerThread::FinalizerThreadStart(void *args)
445445

446446
// handshake with EE initialization, as now we can attach Thread objects to native threads.
447447
hEventFinalizerDone->Set();
448+
WaitForFinalizerEvent (hEventFinalizer);
448449
#endif
449450

450451
s_FinalizerThreadOK = GetFinalizerThread()->HasStarted();

src/coreclr/vm/syncblk.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -625,13 +625,6 @@ void SyncBlockCache::CleanupSyncBlocks()
625625
} EE_END_FINALLY;
626626
}
627627

628-
// create the sync block cache
629-
/* static */
630-
void SyncBlockCache::Attach()
631-
{
632-
LIMITED_METHOD_CONTRACT;
633-
}
634-
635628
// create the sync block cache
636629
/* static */
637630
void SyncBlockCache::Start()

0 commit comments

Comments
 (0)