Skip to content

Commit 8ebd56d

Browse files
authored
Delete CoreDllMain, remove DLL_THREAD_DETACH from EEDllMain, just rely on thread local destructor (#43423)
1 parent 346c434 commit 8ebd56d

3 files changed

Lines changed: 50 additions & 136 deletions

File tree

src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ if (CLR_CMAKE_HOST_WIN32)
1010

1111
list(APPEND CLR_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/coreclr.def)
1212

13-
add_linker_flag("/ENTRY:CoreDllMain")
14-
1513
# Incremental linking results in the linker inserting extra padding and routing function calls via thunks that can break the
1614
# invariants (e.g. size of region between Jit_PatchedCodeLast-Jit_PatchCodeStart needs to fit in a page).
1715
add_linker_flag("/INCREMENTAL:NO")

src/coreclr/src/dlls/mscoree/mscoree.cpp

Lines changed: 1 addition & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -34,65 +34,9 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
3434
#include <shlwapi.h>
3535

3636
#ifdef TARGET_WINDOWS
37-
38-
#include <process.h> // for __security_init_cookie()
39-
40-
extern "C" BOOL WINAPI _CRT_INIT(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved);
4137
extern "C" BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved);
42-
43-
// For the CoreClr, this is the real DLL entrypoint. We make ourselves the first entrypoint as
44-
// we need to capture coreclr's hInstance before the C runtime initializes. This function
45-
// will capture hInstance, let the C runtime initialize and then invoke the "classic"
46-
// DllMain that initializes everything else.
47-
extern "C" BOOL WINAPI CoreDllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
48-
{
49-
STATIC_CONTRACT_NOTHROW;
50-
51-
BOOL result;
52-
switch (dwReason)
53-
{
54-
case DLL_PROCESS_ATTACH:
55-
// Make sure the /GS security cookie is initialized before we call anything else.
56-
// BinScope detects the call to __security_init_cookie in its "Has Non-GS-friendly
57-
// Initialization" check and makes it pass.
58-
__security_init_cookie();
59-
60-
// It's critical that we initialize g_hmodCoreCLR before the CRT initializes.
61-
// We have a lot of global ctors that will break if we let the CRT initialize without
62-
// this step having been done.
63-
64-
g_hmodCoreCLR = (HINSTANCE)hInstance;
65-
66-
if (!(result = _CRT_INIT(hInstance, dwReason, lpReserved)))
67-
{
68-
// CRT_INIT may fail to initialize the CRT heap. Make sure we don't continue
69-
// down a path that would trigger an AV and tear down the host process
70-
break;
71-
}
72-
result = DllMain(hInstance, dwReason, lpReserved);
73-
break;
74-
75-
case DLL_THREAD_ATTACH:
76-
_CRT_INIT(hInstance, dwReason, lpReserved);
77-
result = DllMain(hInstance, dwReason, lpReserved);
78-
break;
79-
80-
case DLL_PROCESS_DETACH: // intentional fallthru
81-
case DLL_THREAD_DETACH:
82-
result = DllMain(hInstance, dwReason, lpReserved);
83-
_CRT_INIT(hInstance, dwReason, lpReserved);
84-
break;
85-
86-
default:
87-
result = FALSE; // it'd be an OS bug if we got here - not much we can do.
88-
break;
89-
}
90-
return result;
91-
}
92-
9338
#endif // TARGET_WINDOWS
9439

95-
9640
extern "C"
9741
#ifdef TARGET_UNIX
9842
DLLEXPORT // For Win32 PAL LoadLibrary emulation
@@ -101,42 +45,7 @@ BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
10145
{
10246
STATIC_CONTRACT_NOTHROW;
10347

104-
switch (dwReason)
105-
{
106-
case DLL_PROCESS_ATTACH:
107-
{
108-
#ifndef TARGET_WINDOWS
109-
g_hmodCoreCLR = (HINSTANCE)hInstance;
110-
#endif
111-
112-
// Save the module handle.
113-
g_hThisInst = (HINSTANCE)hInstance;
114-
115-
// Prevent buffer-overruns
116-
// If buffer is overrun, it is possible the saved callback has been trashed.
117-
// The callback is unsafe.
118-
//SetBufferOverrunHandler();
119-
if (!EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved))
120-
{
121-
return FALSE;
122-
}
123-
}
124-
break;
125-
126-
case DLL_PROCESS_DETACH:
127-
{
128-
EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved);
129-
}
130-
break;
131-
132-
case DLL_THREAD_DETACH:
133-
{
134-
EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved);
135-
}
136-
break;
137-
}
138-
139-
return TRUE;
48+
return EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved);
14049
}
14150

14251
#endif // CROSSGEN_COMPILE

src/coreclr/src/vm/ceemain.cpp

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,15 @@ void EEStartupHelper()
635635

636636
#ifndef CROSSGEN_COMPILE
637637

638+
// We cache the SystemInfo for anyone to use throughout the life of the EE.
639+
GetSystemInfo(&g_SystemInfo);
640+
641+
// Set callbacks so that LoadStringRC knows which language our
642+
// threads are in so that it can return the proper localized string.
643+
// TODO: This shouldn't rely on the LCID (id), but only the name
644+
SetResourceCultureCallbacks(GetThreadUICultureNames,
645+
GetThreadUICultureId);
646+
638647
#ifndef TARGET_UNIX
639648
::SetConsoleCtrlHandler(DbgCtrlCHandler, TRUE/*add*/);
640649
#endif
@@ -1820,16 +1829,9 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
18201829
{
18211830
case DLL_PROCESS_ATTACH:
18221831
{
1823-
// We cache the SystemInfo for anyone to use throughout the
1824-
// life of the DLL.
1825-
GetSystemInfo(&g_SystemInfo);
1826-
1827-
// Set callbacks so that LoadStringRC knows which language our
1828-
// threads are in so that it can return the proper localized string.
1829-
// TODO: This shouldn't rely on the LCID (id), but only the name
1830-
SetResourceCultureCallbacks(GetThreadUICultureNames,
1831-
GetThreadUICultureId);
1832-
1832+
g_hmodCoreCLR = pParam->hInst;
1833+
// Save the module handle.
1834+
g_hThisInst = pParam->hInst;
18331835
break;
18341836
}
18351837

@@ -1859,35 +1861,6 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
18591861
}
18601862
break;
18611863
}
1862-
1863-
case DLL_THREAD_DETACH:
1864-
{
1865-
// Don't destroy threads here if we're in shutdown (shutdown will
1866-
// clean up for us instead).
1867-
1868-
Thread* thread = GetThread();
1869-
if (thread)
1870-
{
1871-
#ifdef FEATURE_COMINTEROP
1872-
// reset the CoInitialize state
1873-
// so we don't call CoUninitialize during thread detach
1874-
thread->ResetCoInitialized();
1875-
#endif // FEATURE_COMINTEROP
1876-
// For case where thread calls ExitThread directly, we need to reset the
1877-
// frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
1878-
// We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
1879-
if (thread->m_pFrame != FRAME_TOP)
1880-
{
1881-
#ifdef _DEBUG
1882-
thread->m_GCOnTransitionsOK = FALSE;
1883-
#endif
1884-
GCX_COOP_NO_DTOR();
1885-
thread->m_pFrame = FRAME_TOP;
1886-
GCX_COOP_NO_DTOR_END();
1887-
}
1888-
thread->DetachThread(TRUE);
1889-
}
1890-
}
18911864
}
18921865

18931866
}
@@ -1896,12 +1869,46 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
18961869
}
18971870
PAL_ENDTRY;
18981871

1899-
if (dwReason == DLL_THREAD_DETACH || dwReason == DLL_PROCESS_DETACH)
1872+
return TRUE;
1873+
}
1874+
1875+
struct TlsDestructionMonitor
1876+
{
1877+
~TlsDestructionMonitor()
19001878
{
1879+
// Don't destroy threads here if we're in shutdown (shutdown will
1880+
// clean up for us instead).
1881+
1882+
Thread* thread = GetThread();
1883+
if (thread)
1884+
{
1885+
#ifdef FEATURE_COMINTEROP
1886+
// reset the CoInitialize state
1887+
// so we don't call CoUninitialize during thread detach
1888+
thread->ResetCoInitialized();
1889+
#endif // FEATURE_COMINTEROP
1890+
// For case where thread calls ExitThread directly, we need to reset the
1891+
// frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
1892+
// We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
1893+
if (thread->m_pFrame != FRAME_TOP)
1894+
{
1895+
#ifdef _DEBUG
1896+
thread->m_GCOnTransitionsOK = FALSE;
1897+
#endif
1898+
GCX_COOP_NO_DTOR();
1899+
thread->m_pFrame = FRAME_TOP;
1900+
GCX_COOP_NO_DTOR_END();
1901+
}
1902+
thread->DetachThread(TRUE);
1903+
}
1904+
19011905
ThreadDetaching();
19021906
}
1903-
return TRUE;
1904-
}
1907+
};
1908+
1909+
// This thread local object is used to detect thread shutdown. Its destructor
1910+
// is called when a thread is being shut down.
1911+
thread_local TlsDestructionMonitor tls_destructionMonitor;
19051912

19061913
#ifdef DEBUGGING_SUPPORTED
19071914
//

0 commit comments

Comments
 (0)