Delete CoreDllMain, remove DLL_THREAD_DETACH from EEDllMain, just rely on thread...
authorVladimir Sadov <vsadov@microsoft.com>
Thu, 15 Oct 2020 18:42:51 +0000 (11:42 -0700)
committerGitHub <noreply@github.com>
Thu, 15 Oct 2020 18:42:51 +0000 (18:42 +0000)
src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt
src/coreclr/src/dlls/mscoree/mscoree.cpp
src/coreclr/src/vm/ceemain.cpp

index 67cbf59..049622f 100644 (file)
@@ -10,8 +10,6 @@ if (CLR_CMAKE_HOST_WIN32)
 
     list(APPEND CLR_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/coreclr.def)
 
-    add_linker_flag("/ENTRY:CoreDllMain")
-
     # Incremental linking results in the linker inserting extra padding and routing function calls via thunks that can break the
     # invariants (e.g. size of region between Jit_PatchedCodeLast-Jit_PatchCodeStart needs to fit in a page).
     add_linker_flag("/INCREMENTAL:NO")
index f9e1e3d..e32041c 100644 (file)
@@ -34,65 +34,9 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
 #include <shlwapi.h>
 
 #ifdef TARGET_WINDOWS
-
-#include <process.h> // for __security_init_cookie()
-
-extern "C" BOOL WINAPI _CRT_INIT(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved);
 extern "C" BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved);
-
-// For the CoreClr, this is the real DLL entrypoint. We make ourselves the first entrypoint as
-// we need to capture coreclr's hInstance before the C runtime initializes. This function
-// will capture hInstance, let the C runtime initialize and then invoke the "classic"
-// DllMain that initializes everything else.
-extern "C" BOOL WINAPI CoreDllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
-{
-    STATIC_CONTRACT_NOTHROW;
-
-    BOOL result;
-    switch (dwReason)
-    {
-        case DLL_PROCESS_ATTACH:
-            // Make sure the /GS security cookie is initialized before we call anything else.
-            // BinScope detects the call to __security_init_cookie in its "Has Non-GS-friendly
-            // Initialization" check and makes it pass.
-            __security_init_cookie();
-
-            // It's critical that we initialize g_hmodCoreCLR before the CRT initializes.
-            // We have a lot of global ctors that will break if we let the CRT initialize without
-            // this step having been done.
-
-            g_hmodCoreCLR = (HINSTANCE)hInstance;
-
-            if (!(result = _CRT_INIT(hInstance, dwReason, lpReserved)))
-            {
-                // CRT_INIT may fail to initialize the CRT heap. Make sure we don't continue
-                // down a path that would trigger an AV and tear down the host process
-                break;
-            }
-            result = DllMain(hInstance, dwReason, lpReserved);
-            break;
-
-        case DLL_THREAD_ATTACH:
-            _CRT_INIT(hInstance, dwReason, lpReserved);
-            result = DllMain(hInstance, dwReason, lpReserved);
-            break;
-
-        case DLL_PROCESS_DETACH: // intentional fallthru
-        case DLL_THREAD_DETACH:
-            result = DllMain(hInstance, dwReason, lpReserved);
-            _CRT_INIT(hInstance, dwReason, lpReserved);
-            break;
-
-        default:
-            result = FALSE;  // it'd be an OS bug if we got here - not much we can do.
-            break;
-    }
-    return result;
-}
-
 #endif // TARGET_WINDOWS
 
-
 extern "C"
 #ifdef TARGET_UNIX
 DLLEXPORT // For Win32 PAL LoadLibrary emulation
@@ -101,42 +45,7 @@ BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
 {
     STATIC_CONTRACT_NOTHROW;
 
-    switch (dwReason)
-    {
-    case DLL_PROCESS_ATTACH:
-        {
-#ifndef TARGET_WINDOWS
-            g_hmodCoreCLR = (HINSTANCE)hInstance;
-#endif
-
-            // Save the module handle.
-            g_hThisInst = (HINSTANCE)hInstance;
-
-            // Prevent buffer-overruns
-            // If buffer is overrun, it is possible the saved callback has been trashed.
-            // The callback is unsafe.
-            //SetBufferOverrunHandler();
-            if (!EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved))
-            {
-                return FALSE;
-            }
-        }
-        break;
-
-    case DLL_PROCESS_DETACH:
-        {
-            EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved);
-        }
-        break;
-
-    case DLL_THREAD_DETACH:
-        {
-            EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved);
-        }
-        break;
-    }
-
-    return TRUE;
+    return EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved);
 }
 
 #endif // CROSSGEN_COMPILE
index 3526d9f..c729cd6 100644 (file)
@@ -635,6 +635,15 @@ void EEStartupHelper()
 
 #ifndef CROSSGEN_COMPILE
 
+        // We cache the SystemInfo for anyone to use throughout the life of the EE.
+        GetSystemInfo(&g_SystemInfo);
+
+        // Set callbacks so that LoadStringRC knows which language our
+        // threads are in so that it can return the proper localized string.
+    // TODO: This shouldn't rely on the LCID (id), but only the name
+        SetResourceCultureCallbacks(GetThreadUICultureNames,
+        GetThreadUICultureId);
+
 #ifndef TARGET_UNIX
         ::SetConsoleCtrlHandler(DbgCtrlCHandler, TRUE/*add*/);
 #endif
@@ -1820,16 +1829,9 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
         {
             case DLL_PROCESS_ATTACH:
             {
-                // We cache the SystemInfo for anyone to use throughout the
-                // life of the DLL.
-                GetSystemInfo(&g_SystemInfo);
-
-                // Set callbacks so that LoadStringRC knows which language our
-                // threads are in so that it can return the proper localized string.
-            // TODO: This shouldn't rely on the LCID (id), but only the name
-                SetResourceCultureCallbacks(GetThreadUICultureNames,
-                                            GetThreadUICultureId);
-
+                g_hmodCoreCLR = pParam->hInst;
+                // Save the module handle.
+                g_hThisInst = pParam->hInst;
                 break;
             }
 
@@ -1859,35 +1861,6 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
                 }
                 break;
             }
-
-            case DLL_THREAD_DETACH:
-            {
-                // Don't destroy threads here if we're in shutdown (shutdown will
-                // clean up for us instead).
-
-                Thread* thread = GetThread();
-                if (thread)
-                {
-#ifdef FEATURE_COMINTEROP
-                    // reset the CoInitialize state
-                    // so we don't call CoUninitialize during thread detach
-                    thread->ResetCoInitialized();
-#endif // FEATURE_COMINTEROP
-                    // For case where thread calls ExitThread directly, we need to reset the
-                    // frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
-                    // We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
-                    if (thread->m_pFrame != FRAME_TOP)
-                    {
-#ifdef _DEBUG
-                        thread->m_GCOnTransitionsOK = FALSE;
-#endif
-                        GCX_COOP_NO_DTOR();
-                        thread->m_pFrame = FRAME_TOP;
-                        GCX_COOP_NO_DTOR_END();
-                    }
-                    thread->DetachThread(TRUE);
-                }
-            }
         }
 
     }
@@ -1896,12 +1869,46 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
     }
     PAL_ENDTRY;
 
-    if (dwReason == DLL_THREAD_DETACH || dwReason == DLL_PROCESS_DETACH)
+    return TRUE;
+}
+
+struct TlsDestructionMonitor
+{
+    ~TlsDestructionMonitor()
     {
+        // Don't destroy threads here if we're in shutdown (shutdown will
+        // clean up for us instead).
+
+        Thread* thread = GetThread();
+        if (thread)
+        {
+#ifdef FEATURE_COMINTEROP
+            // reset the CoInitialize state
+            // so we don't call CoUninitialize during thread detach
+            thread->ResetCoInitialized();
+#endif // FEATURE_COMINTEROP
+            // For case where thread calls ExitThread directly, we need to reset the
+            // frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
+            // We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
+            if (thread->m_pFrame != FRAME_TOP)
+            {
+#ifdef _DEBUG
+                thread->m_GCOnTransitionsOK = FALSE;
+#endif
+                GCX_COOP_NO_DTOR();
+                thread->m_pFrame = FRAME_TOP;
+                GCX_COOP_NO_DTOR_END();
+            }
+            thread->DetachThread(TRUE);
+        }
+
         ThreadDetaching();
     }
-    return TRUE;
-}
+};
+
+// This thread local object is used to detect thread shutdown. Its destructor
+// is called when a thread is being shut down.
+thread_local TlsDestructionMonitor tls_destructionMonitor;
 
 #ifdef DEBUGGING_SUPPORTED
 //