@@ -839,36 +839,19 @@ void EEStartupHelper()
839
839
840
840
#ifdef PROFILING_SUPPORTED
841
841
// Initialize the profiling services.
842
+ // This must happen before Thread::HasStarted() that fires profiler notifications is called on the finalizer thread.
842
843
hr = ProfilingAPIUtility::InitializeProfiling ();
843
844
844
845
_ASSERTE (SUCCEEDED (hr));
845
846
IfFailGo (hr);
846
847
#endif // PROFILING_SUPPORTED
847
848
848
- InitializeExceptionHandling ();
849
-
850
- //
851
- // Install our global exception filter
852
- //
853
- if (!InstallUnhandledExceptionFilter ())
854
- {
855
- IfFailGo (E_FAIL);
856
- }
857
-
858
- // throws on error
859
- SetupThread ();
860
-
861
- #ifdef DEBUGGING_SUPPORTED
862
- // Notify debugger once the first thread is created to finish initialization.
863
- if (g_pDebugInterface != NULL )
864
- {
865
- g_pDebugInterface->StartupPhase2 (GetThread ());
866
- }
867
- #endif
868
-
869
- // This isn't done as part of InitializeGarbageCollector() above because
870
- // debugger must be initialized before creating EE thread objects
849
+ #ifdef TARGET_WINDOWS
850
+ // Create the finalizer thread on windows earlier, as we will need to wait for
851
+ // the completion of its initialization part that initializes COM as that has to be done
852
+ // before the first Thread is attached. Thus we want to give the thread a bit more time.
871
853
FinalizerThread::FinalizerThreadCreate ();
854
+ #endif
872
855
873
856
InitPreStubManager ();
874
857
@@ -882,8 +865,6 @@ void EEStartupHelper()
882
865
// of the JIT helpers.
883
866
InitJITHelpers1 ();
884
867
885
- SyncBlockCache::Attach ();
886
-
887
868
// Set up the sync block
888
869
SyncBlockCache::Start ();
889
870
@@ -898,6 +879,48 @@ void EEStartupHelper()
898
879
899
880
IfFailGo (hr);
900
881
882
+ InitializeExceptionHandling ();
883
+
884
+ //
885
+ // Install our global exception filter
886
+ //
887
+ if (!InstallUnhandledExceptionFilter ())
888
+ {
889
+ IfFailGo (E_FAIL);
890
+ }
891
+
892
+ #ifdef TARGET_WINDOWS
893
+ // g_pGCHeap->Initialize() above could take nontrivial time, so by now the finalizer thread
894
+ // should have initialized FLS slot for thread cleanup notifications.
895
+ // And ensured that COM is initialized (must happen before allocating FLS slot).
896
+ // Make sure that this was done before we start creating Thread objects
897
+ // Ex: The call to SetupThread below will create and attach a Thread object.
898
+ // Event pipe might also do that.
899
+ FinalizerThread::WaitForFinalizerThreadStart ();
900
+ #endif
901
+
902
+ // throws on error
903
+ _ASSERTE (GetThreadNULLOk () == NULL );
904
+ SetupThread ();
905
+
906
+ #ifdef DEBUGGING_SUPPORTED
907
+ // Notify debugger once the first thread is created to finish initialization.
908
+ if (g_pDebugInterface != NULL )
909
+ {
910
+ g_pDebugInterface->StartupPhase2 (GetThread ());
911
+ }
912
+ #endif
913
+
914
+ #ifndef TARGET_WINDOWS
915
+ // This isn't done as part of InitializeGarbageCollector() above because
916
+ // debugger must be initialized before creating EE thread objects
917
+ FinalizerThread::FinalizerThreadCreate ();
918
+ #else
919
+ // On windows the finalizer thread is already partially created and is waiting
920
+ // right before doing HasStarted(). We will release it now.
921
+ FinalizerThread::EnableFinalization ();
922
+ #endif
923
+
901
924
#ifdef FEATURE_PERFTRACING
902
925
// Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup.
903
926
// SampleProfiler needs to cooperate with the GC which hasn't fully finished setting up in the first part of the
@@ -957,12 +980,6 @@ void EEStartupHelper()
957
980
g_MiniMetaDataBuffMaxSize, MEM_COMMIT, PAGE_READWRITE);
958
981
#endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
959
982
960
- #ifdef TARGET_WINDOWS
961
- // By now finalizer thread should have initialized FLS slot for thread cleanup notifications.
962
- // And ensured that COM is initialized (must happen before allocating FLS slot).
963
- // Make sure that this was done.
964
- FinalizerThread::WaitForFinalizerThreadStart ();
965
- #endif
966
983
g_fEEStarted = TRUE ;
967
984
g_EEStartupStatus = S_OK;
968
985
hr = S_OK;
@@ -1764,6 +1781,8 @@ void InitFlsSlot()
1764
1781
// thread - thread to attach
1765
1782
static void OsAttachThread (void * thread)
1766
1783
{
1784
+ _ASSERTE (g_flsIndex != FLS_OUT_OF_INDEXES);
1785
+
1767
1786
if (t_flsState == FLS_STATE_INVOKED)
1768
1787
{
1769
1788
_ASSERTE_ALL_BUILDS (!" Attempt to execute managed code after the .NET runtime thread state has been destroyed." );
0 commit comments