@@ -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
17951812static 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." );
0 commit comments