@@ -862,36 +862,19 @@ void EEStartupHelper()
862
862
863
863
#ifdef PROFILING_SUPPORTED
864
864
// Initialize the profiling services.
865
+ // This must happen before Thread::HasStarted() that fires profiler notifications is called on the finalizer thread.
865
866
hr = ProfilingAPIUtility::InitializeProfiling ();
866
867
867
868
_ASSERTE (SUCCEEDED (hr));
868
869
IfFailGo (hr);
869
870
#endif // PROFILING_SUPPORTED
870
871
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.
894
876
FinalizerThread::FinalizerThreadCreate ();
877
+ #endif
895
878
896
879
InitPreStubManager ();
897
880
@@ -906,8 +889,6 @@ void EEStartupHelper()
906
889
InitJITHelpers1 ();
907
890
InitJITHelpers2 ();
908
891
909
- SyncBlockCache::Attach ();
910
-
911
892
// Set up the sync block
912
893
SyncBlockCache::Start ();
913
894
@@ -922,6 +903,48 @@ void EEStartupHelper()
922
903
923
904
IfFailGo (hr);
924
905
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
+
925
948
#ifdef FEATURE_PERFTRACING
926
949
// Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup.
927
950
// 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()
982
1005
g_MiniMetaDataBuffMaxSize, MEM_COMMIT, PAGE_READWRITE);
983
1006
#endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
984
1007
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
991
1008
g_fEEStarted = TRUE ;
992
1009
g_EEStartupStatus = S_OK;
993
1010
hr = S_OK;
@@ -1794,6 +1811,8 @@ void InitFlsSlot()
1794
1811
// thread - thread to attach
1795
1812
static void OsAttachThread (void * thread)
1796
1813
{
1814
+ _ASSERTE (g_flsIndex != FLS_OUT_OF_INDEXES);
1815
+
1797
1816
if (t_flsState == FLS_STATE_INVOKED)
1798
1817
{
1799
1818
_ASSERTE_ALL_BUILDS (!" Attempt to execute managed code after the .NET runtime thread state has been destroyed." );
0 commit comments