1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // ===========================================================================
5 // ===========================================================================
10 // The CLR code base uses a hyperlink feature of the HyperAddin plugin for Visual Studio. If you don't see
11 // 'HyperAddin' in your Visual Studio menu bar you don't have this support. To get it type
13 // \\clrmain\tools\installCLRAddins
15 // After installing HyperAddin, your first run of VS should be as an administrator so HyperAddin can update
16 // some registry information.
18 // At this point the code: prefixes become hyperlinks in Visual Studio and life is good. See
19 // http://mswikis/clr/dev/Pages/CLR%20Team%20Commenting.aspx for more information
21 // There is a bug associated with Visual Studio where it does not recognise the hyperlink if there is a ::
22 // preceding it on the same line. Since C++ uses :: as a namespace separator, this can often mean that the
23 // second hyperlink on a line does not work. To work around this it is better to use '.' instead of :: as
24 // the namespace separators in code: hyperlinks.
27 // #TableOfContents The .NET Runtime Table of contents
29 // This comment is mean to be a nexus that allows you to jump quickly to various interesting parts of the
32 // You can refer to product studio bugs using urls like the following
33 // * http://bugcheck/bugs/DevDivBugs/2320.asp
34 // * http://bugcheck/bugs/VSWhidbey/601210.asp
36 // Dev10 Bugs can be added with URLs like the following (for Dev10 bug 671409)
37 // * http://tkbgitvstfat01:8090/wi.aspx?id=671409
39 //*************************************************************************************************
41 // * Introduction to the runtime file:../../Documentation/botr/botr-faq.md
43 // #MajorDataStructures. The major data structures associated with the runtime are
44 // * code:Thread (see file:threads.h#ThreadClass) - the additional thread state the runtime needs.
45 // * code:AppDomain - The managed version of a process
46 // * code:Assembly - The unit of deployment and versioning (may be several DLLs but often is only one).
47 // * code:Module - represents a Module (DLL or EXE).
48 // * code:MethodTable - represents the 'hot' part of a type (needed during normal execution)
49 // * code:EEClass - represents the 'cold' part of a type (used during compilation, interop, ...)
50 // * code:MethodDesc - represents a Method
51 // * code:FieldDesc - represents a Field.
52 // * code:Object - represents a object on the GC heap allocated with code:Alloc
54 // * ECMA specifications
55 // * Partition I Concepts
56 // http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20I%20Architecture.doc
57 // * Partition II Meta Data
58 // http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20II%20Metadata.doc
60 // http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20III%20CIL.doc
62 // * Serge Liden (worked on the CLR and owned ILASM / ILDASM for a long time wrote a good book on IL
63 // * Expert .NET 2.0 IL Assembler http://www.amazon.com/Expert-NET-2-0-IL-Assembler/dp/1590596463
65 // * This is also a pretty nice overview of what the CLR is at
66 // http://msdn2.microsoft.com/en-us/netframework/aa497266.aspx
68 // * code:EEStartup - This routine must be called before any interesting runtime services are used. It is
69 // invoked as part of mscorwks's DllMain logic.
70 // * code:#EEShutDown - Code called before we shut down the EE.
72 // * file:..\inc\corhdr.h#ManagedHeader - From a data structure point of view, this is the entry point into
73 // the runtime. This is how all other data in the EXE are found.
75 // * code:ICorJitCompiler#EEToJitInterface - This is the interface from the EE to the Just in time (JIT)
76 // compiler. The interface to the JIT is relatively simple (compileMethod), however the EE provides a
77 // rich set of callbacks so the JIT can get all the information it needs. See also
78 // file:../../Documentation/botr/ryujit-overview.md for general information on the JIT.
80 // * code:VirtualCallStubManager - This is the main class that implements interface dispatch
82 // * Precode - Every method needs entry point for other code to call even if that native code does not
83 // actually exist yet. To support this methods can have code:Precode that is an entry point that exists
84 // and will call the JIT compiler if the code does not yet exist.
86 // * NGEN - NGen stands for Native code GENeration and it is the runtime way of precompiling IL and IL
87 // Meta-data into native code and runtime data structures. At compilation time the most
88 // fundamental data structures is the code:ZapNode which represents something that needs to go into the
91 // * What is cooperative / preemtive mode ? file:threads.h#CooperativeMode and
92 // file:threads.h#SuspendingTheRuntime and file:../../Documentation/botr/threading.md
93 // * Garbage collection - file:gc.cpp#Overview and file:../../Documentation/botr/garbage-collection.md
94 // * code:AppDomain - The managed version of a process.
95 // * Calling Into the runtime (FCALLs QCalls) file:../../Documentation/botr/corelib.md
96 // * Exceptions - file:../../Documentation/botr/exceptions.md. The most important routine to start
97 // with is code:COMPlusFrameHandler which is the routine that we hook up to get called when an unmanaged
99 // * Assembly Loading file:../../Documentation/botr/type-loader.md
100 // * Profiling file:../../Documentation/botr/profiling.md and file:../../Documentation/botr/profilability.md
101 // * FCALLS QCALLS (calling into the runtime from managed code)
102 // file:../../Documentation/botr/corelib.md
103 // * Event Tracing for Windows
104 // * file:../inc/eventtrace.h#EventTracing -
105 // * This is the main file dealing with event tracing in CLR
106 // * The implementation of this class is available in file:eventtrace.cpp
107 // * file:../inc/eventtrace.h#CEtwTracer - This is the main class dealing with event tracing in CLR.
108 // Follow the link for more information on how this feature has been implemented
109 // * http://mswikis/clr/dev/Pages/CLR%20ETW%20Events%20Wiki.aspx - Follow the link for more information on how to
110 // use this instrumentation feature.
112 // ----------------------------------------------------------------------------------------------------
113 // Features in the runtime that have been given hyperlinks
115 // * code:Nullable#NullableFeature - the Nullable<T> type has special runtime semantics associated with
116 // boxing this describes this feature.
123 #include "clsload.hpp"
128 #include "dllimport.h"
130 #include "eeconfig.h"
131 #include "stublink.h"
132 #include "method.hpp"
136 #include "stackwalk.h"
137 #include "gcheaputilities.h"
138 #include "interoputil.h"
139 #include "fieldmarshaler.h"
140 #include "dbginterface.h"
141 #include "eedbginterfaceimpl.h"
142 #include "debugdebugger.h"
143 #include "cordbpriv.h"
144 #include "comdelegate.h"
145 #include "appdomain.hpp"
146 #include "eventtrace.h"
149 #include "olevariant.h"
150 #include "comcallablewrapper.h"
151 #include "../dlls/mscorrc/resource.h"
153 #include "shimload.h"
154 #include "comthreadpool.h"
155 #include "posterror.h"
156 #include "virtualcallstub.h"
157 #include "strongnameinternal.h"
158 #include "syncclean.hpp"
159 #include "debuginfostore.h"
160 #include "finalizerthread.h"
161 #include "threadsuspend.h"
162 #include "disassembler.h"
167 #include "dwreport.h"
168 #endif // !TARGET_UNIX
170 #include "stringarraylist.h"
171 #include "stubhelpers.h"
173 #ifdef FEATURE_COMINTEROP
174 #include "runtimecallablewrapper.h"
175 #include "mngstdinterfaces.h"
176 #include "interoplibinterface.h"
177 #endif // FEATURE_COMINTEROP
179 #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
180 #include "olecontexthelpers.h"
181 #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
183 #ifdef PROFILING_SUPPORTED
184 #include "proftoeeinterfaceimpl.h"
185 #include "profilinghelper.h"
186 #endif // PROFILING_SUPPORTED
188 #ifdef FEATURE_INTERPRETER
189 #include "interpreter.h"
190 #endif // FEATURE_INTERPRETER
192 #ifdef FEATURE_PERFMAP
196 #include "diagnosticserveradapter.h"
197 #include "eventpipeadapter.h"
200 // Included for referencing __security_cookie
202 #endif // !TARGET_UNIX
204 #ifdef FEATURE_GDBJIT
206 #endif // FEATURE_GDBJIT
208 #include "genanalysis.h"
210 static int GetThreadUICultureId(_Out_ LocaleIDValue* pLocale); // TODO: This shouldn't use the LCID. We should rely on name instead
212 static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames);
217 static void InitializeGarbageCollector();
219 #ifdef DEBUGGING_SUPPORTED
220 static void InitializeDebugger(void);
221 static void TerminateDebugger(void);
222 extern "C" HRESULT __cdecl CorDBGetInterface(DebugInterface** rcInterface);
223 #endif // DEBUGGING_SUPPORTED
225 // g_coreclr_embedded indicates that coreclr is linked directly into the program
226 // g_hostpolicy_embedded indicates that the hostpolicy library is linked directly into the executable
227 // Note: that it can happen that the hostpolicy is embedded but coreclr isn't (on Windows singlefilehost is built that way)
228 #ifdef CORECLR_EMBEDDED
229 bool g_coreclr_embedded = true;
230 bool g_hostpolicy_embedded = true; // We always embed hostpolicy if coreclr is also embedded
232 bool g_coreclr_embedded = false;
233 bool g_hostpolicy_embedded = false; // In this case the value may come from a runtime property and may change
236 // Remember how the last startup of EE went.
237 HRESULT g_EEStartupStatus = S_OK;
239 // Flag indicating if the EE has been started. This is set prior to initializing the default AppDomain, and so does not indicate that
240 // the EE is fully able to execute arbitrary managed code. To ensure the EE is fully started, call EnsureEEStarted rather than just
241 // checking this flag.
242 Volatile<BOOL> g_fEEStarted = FALSE;
244 // The OS thread ID of the thread currently performing EE startup, or 0 if there is no such thread.
245 DWORD g_dwStartupThreadId = 0;
247 // Event to synchronize EE shutdown.
248 static CLREvent * g_pEEShutDownEvent;
250 static DangerousNonHostedSpinLock g_EEStartupLock;
252 // ---------------------------------------------------------------------------
253 // %%Function: EnsureEEStarted()
255 // Description: Ensure the CLR is started.
256 // ---------------------------------------------------------------------------
257 HRESULT EnsureEEStarted()
273 // On non x86 platforms, when we load CoreLib during EEStartup, we will
274 // re-enter _CorDllMain with a DLL_PROCESS_ATTACH for CoreLib. We are
275 // far enough in startup that this is allowed, however we don't want to
276 // re-start the startup code so we need to check to see if startup has
277 // been initiated or completed before we call EEStartup.
279 // We do however want to make sure other threads block until the EE is started,
280 // which we will do further down.
283 // Initialize our configuration.
284 CLRConfig::Initialize();
289 DangerousNonHostedSpinLockHolder lockHolder(&g_EEStartupLock);
291 // Now that we've acquired the lock, check again to make sure we aren't in
292 // the process of starting the CLR or that it hasn't already been fully started.
293 // At this point, if startup has been inited we don't have anything more to do.
294 // And if EEStartup already failed before, we don't do it again.
295 if (!g_fEEStarted && !g_fEEInit && SUCCEEDED (g_EEStartupStatus))
297 g_dwStartupThreadId = GetCurrentThreadId();
300 bStarted=g_fEEStarted;
301 hr = g_EEStartupStatus;
303 g_dwStartupThreadId = 0;
307 hr = g_EEStartupStatus;
308 if (SUCCEEDED(g_EEStartupStatus))
318 // g_fEEStarted is TRUE, but startup may not be complete since we initialize the default AppDomain
319 // *after* setting that flag. g_fEEStarted is set inside of g_EEStartupLock, and that lock is
320 // not released until the EE is really started - so we can quickly check whether the EE is definitely
321 // started by checking if that lock is currently held. If it is not, then we know the other thread
322 // (that is actually doing the startup) has finished startup. If it is currently held, then we
323 // need to wait for the other thread to release it, which we do by simply acquiring the lock ourselves.
325 // We do not want to do this blocking if we are the thread currently performing EE startup. So we check
328 // Note that the call to IsHeld here is an "acquire" barrier, as is acquiring the lock. And the release of
329 // the lock by the other thread is a "release" barrier, due to the volatile semantics in the lock's
330 // implementation. This assures us that once we observe the lock having been released, we are guaranteed
331 // to observe a fully-initialized EE.
333 // A note about thread affinity here: we're using the OS thread ID of the current thread without
334 // asking the host to pin us to this thread, as we did above. We can get away with this, because we are
335 // only interested in a particular thread ID (that of the "startup" thread) and *that* particular thread
336 // is already affinitized by the code above. So if we get that particular OS thread ID, we know for sure
337 // we are really the startup thread.
339 if (g_EEStartupLock.IsHeld() && g_dwStartupThreadId != GetCurrentThreadId())
341 DangerousNonHostedSpinLockHolder lockHolder(&g_EEStartupLock);
344 hr = g_EEStartupStatus;
345 if (SUCCEEDED(g_EEStartupStatus))
357 // This is our Ctrl-C, Ctrl-Break, etc. handler.
358 static BOOL WINAPI DbgCtrlCHandler(DWORD dwCtrlType)
362 #if defined(DEBUGGING_SUPPORTED)
363 // Note that if a managed-debugger is attached, it's actually attached with the native
364 // debugging pipeline and it will get a control-c notifications via native debug events.
365 // However, if we let the native debugging pipeline handle the event and send the notification
366 // to the debugger, then we break pre-V4 behaviour because we intercept handlers registered
367 // in-process. See Dev10 Bug 846455 for more information.
368 if (CORDebuggerAttached() &&
369 (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT))
371 return g_pDebugInterface->SendCtrlCToDebugger(dwCtrlType);
374 #endif // DEBUGGING_SUPPORTED
376 if (dwCtrlType == CTRL_CLOSE_EVENT || dwCtrlType == CTRL_SHUTDOWN_EVENT)
378 // Initiate shutdown so the ProcessExit handlers run
379 ForceEEShutdown(SCA_ReturnWhenShutdownComplete);
382 g_fInControlC = true; // only for weakening assertions in checked build.
383 return FALSE; // keep looking for a real handler.
388 // A host can specify that it only wants one version of hosting interface to be used.
389 BOOL g_singleVersionHosting;
391 #ifdef TARGET_WINDOWS
392 typedef BOOL(WINAPI* PINITIALIZECONTEXT2)(PVOID Buffer, DWORD ContextFlags, PCONTEXT* Context, PDWORD ContextLength, ULONG64 XStateCompactionMask);
393 PINITIALIZECONTEXT2 g_pfnInitializeContext2 = NULL;
396 typedef VOID(__cdecl* PRTLRESTORECONTEXT)(PCONTEXT ContextRecord, struct _EXCEPTION_RECORD* ExceptionRecord);
397 PRTLRESTORECONTEXT g_pfnRtlRestoreContext = NULL;
400 void InitializeOptionalWindowsAPIPointers()
402 HMODULE hm = GetModuleHandleW(_T("kernel32.dll"));
403 g_pfnInitializeContext2 = (PINITIALIZECONTEXT2)GetProcAddress(hm, "InitializeContext2");
406 hm = GetModuleHandleW(_T("ntdll.dll"));
407 g_pfnRtlRestoreContext = (PRTLRESTORECONTEXT)GetProcAddress(hm, "RtlRestoreContext");
410 #endif // TARGET_WINDOWS
412 void InitializeStartupFlags()
420 STARTUP_FLAGS flags = CorHost2::GetStartupFlags();
423 if (flags & STARTUP_CONCURRENT_GC)
429 g_heap_type = ((flags & STARTUP_SERVER_GC) && GetCurrentProcessCpuCount() > 1) ? GC_HEAP_SVR : GC_HEAP_WKS;
430 g_IGCHoardVM = (flags & STARTUP_HOARD_GC_VM) == 0 ? 0 : 1;
433 //-----------------------------------------------------------------------------
445 volatile GSCookie * pGSCookiePtr = GetProcessGSCookiePtr();
447 // The GS cookie is stored in a read only data segment
449 if(!ClrVirtualProtect((LPVOID)pGSCookiePtr, sizeof(GSCookie), PAGE_READWRITE, &oldProtection))
455 // PAL layer is unable to extract old protection for regions that were not allocated using VirtualAlloc
456 oldProtection = PAGE_READONLY;
457 #endif // TARGET_UNIX
460 // The GSCookie cannot be in a writeable page
461 assert(((oldProtection & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|
462 PAGE_EXECUTE_WRITECOPY|PAGE_WRITECOMBINE)) == 0));
464 // Forces VC cookie to be initialized.
465 void * pf = &__security_check_cookie;
468 GSCookie val = (GSCookie)(__security_cookie ^ GetTickCount());
469 #else // !TARGET_UNIX
470 // REVIEW: Need something better for PAL...
471 GSCookie val = (GSCookie)GetTickCount();
472 #endif // !TARGET_UNIX
475 // In _DEBUG, always use the same value to make it easier to search for the cookie
476 val = (GSCookie) BIT64_ONLY(0x9ABCDEF012345678) NOT_BIT64(0x12345678);
479 // To test if it is initialized. Also for ICorMethodInfo::getGSCookie()
484 if(!ClrVirtualProtect((LPVOID)pGSCookiePtr, sizeof(GSCookie), oldProtection, &oldProtection))
490 Volatile<BOOL> g_bIsGarbageCollectorFullyInitialized = FALSE;
492 void SetGarbageCollectorFullyInitialized()
494 LIMITED_METHOD_CONTRACT;
496 g_bIsGarbageCollectorFullyInitialized = TRUE;
499 // Tells whether the garbage collector is fully initialized
500 // Stronger than IsGCHeapInitialized
501 BOOL IsGarbageCollectorFullyInitialized()
503 LIMITED_METHOD_CONTRACT;
505 return g_bIsGarbageCollectorFullyInitialized;
508 // ---------------------------------------------------------------------------
509 // %%Function: EEStartupHelper
515 // Reserved to initialize the EE runtime engine explicitly.
516 // ---------------------------------------------------------------------------
518 #ifndef IfFailGotoLog
519 #define IfFailGotoLog(EXPR, LABEL) \
523 STRESS_LOG2(LF_STARTUP, LL_ALWAYS, "%s failed with code %x", #EXPR, hr);\
527 STRESS_LOG1(LF_STARTUP, LL_ALWAYS, "%s completed", #EXPR);\
532 #define IfFailGoLog(EXPR) IfFailGotoLog(EXPR, ErrExit)
537 void EESocketCleanupHelper(bool isExecutingOnAltStack)
545 if (isExecutingOnAltStack)
547 GetThread()->SetExecutingOnAltStack();
550 // Close the debugger transport socket first
551 if (g_pDebugInterface != NULL)
553 g_pDebugInterface->CleanupTransportSocket();
556 // Close the diagnostic server socket.
557 #ifdef FEATURE_PERFTRACING
558 DiagnosticServerAdapter::Shutdown();
559 #endif // FEATURE_PERFTRACING
561 #endif // TARGET_UNIX
563 void FatalErrorHandler(UINT errorCode, LPCWSTR pszMessage)
565 EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(errorCode, pszMessage);
568 void EEStartupHelper()
577 #ifdef ENABLE_CONTRACTS_IMPL
579 extern void ContractRegressionCheck();
580 ContractRegressionCheck();
585 static ConfigDWORD breakOnEELoad;
591 // We cache the SystemInfo for anyone to use throughout the life of the EE.
592 GetSystemInfo(&g_SystemInfo);
594 // Set callbacks so that LoadStringRC knows which language our
595 // threads are in so that it can return the proper localized string.
596 // TODO: This shouldn't rely on the LCID (id), but only the name
597 SetResourceCultureCallbacks(GetThreadUICultureNames,
598 GetThreadUICultureId);
601 ::SetConsoleCtrlHandler(DbgCtrlCHandler, TRUE/*add*/);
605 InitializeOptionalWindowsAPIPointers();
606 #endif // HOST_WINDOWS
608 // SString initialization
609 // This needs to be done before config because config uses SString::Empty()
612 IfFailGo(EEConfig::Setup());
616 InitializeCrashDump();
618 #endif // HOST_WINDOWS
620 CPUGroupInfo::EnsureInitialized();
621 #endif // !TARGET_UNIX
623 // Initialize global configuration settings based on startup flags
624 // This needs to be done before the EE has started
625 InitializeStartupFlags();
627 IfFailGo(ExecutableAllocator::StaticInitialize(FatalErrorHandler));
629 Thread::StaticInitialize();
631 JITInlineTrackingMap::StaticInitialize();
632 MethodDescBackpatchInfoTracker::StaticInitialize();
633 CodeVersionManager::StaticInitialize();
634 TieredCompilationManager::StaticInitialize();
635 CallCountingManager::StaticInitialize();
636 OnStackReplacementManager::StaticInitialize();
639 ExecutableAllocator::InitPreferredRange();
642 // Record coreclr.dll geometry
643 PEDecoder pe(GetClrModuleBase());
645 g_runtimeLoadedBaseAddress = (SIZE_T)pe.GetBase();
646 g_runtimeVirtualSize = (SIZE_T)pe.GetVirtualSize();
647 ExecutableAllocator::InitLazyPreferredRange(g_runtimeLoadedBaseAddress, g_runtimeVirtualSize, GetRandomInt(64));
649 #endif // !TARGET_UNIX
652 STRESS_LOG0(LF_STARTUP, LL_ALWAYS, "Returned successfully from InitThreadManager");
654 #ifdef FEATURE_PERFTRACING
655 // Initialize the event pipe.
656 EventPipeAdapter::Initialize();
657 #endif // FEATURE_PERFTRACING
660 PAL_SetShutdownCallback(EESocketCleanupHelper);
661 #endif // TARGET_UNIX
664 if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_StressLog, g_pConfig->StressLog()) != 0) {
665 unsigned facilities = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_LogFacility, LF_ALL);
666 unsigned level = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_LogLevel, LL_INFO1000);
667 unsigned bytesPerThread = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_StressLogSize, STRESSLOG_CHUNK_SIZE * 4);
668 unsigned totalBytes = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TotalStressLogSize, STRESSLOG_CHUNK_SIZE * 1024);
669 CLRConfigStringHolder logFilename = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_StressLogFilename);
670 StressLog::Initialize(facilities, level, bytesPerThread, totalBytes, GetClrModuleBase(), logFilename);
671 g_pStressLog = &StressLog::theLog;
675 #ifdef FEATURE_PERFTRACING
676 DiagnosticServerAdapter::Initialize();
677 DiagnosticServerAdapter::PauseForDiagnosticsMonitor();
678 #endif // FEATURE_PERFTRACING
680 #ifdef FEATURE_GDBJIT
682 NotifyGdb::Initialize();
683 #endif // FEATURE_GDBJIT
685 #ifdef FEATURE_EVENT_TRACE
686 // Initialize event tracing early so we can trace CLR startup time events.
687 InitializeEventTracing();
689 // Fire the EE startup ETW event
690 ETWFireEvent(EEStartupStart_V1);
691 #endif // FEATURE_EVENT_TRACE
704 #ifdef FEATURE_PERFMAP
705 PerfMap::Initialize();
709 PgoManager::Initialize();
712 STRESS_LOG0(LF_STARTUP, LL_ALWAYS, "===================EEStartup Starting===================");
715 IfFailGoLog(EnsureRtlFunctions());
716 #endif // !TARGET_UNIX
719 if (g_pConfig != NULL)
721 IfFailGoLog(g_pConfig->sync());
724 // Fire the runtime information ETW event
725 ETW::InfoLog::RuntimeInformation(ETW::InfoLog::InfoStructs::Normal);
727 if (breakOnEELoad.val(CLRConfig::UNSUPPORTED_BreakOnEELoad) == 1)
730 _ASSERTE(!"Start loading EE!");
736 #ifdef ENABLE_STARTUP_DELAY
737 PREFIX_ASSUME(NULL != g_pConfig);
738 if (g_pConfig->StartupDelayMS())
740 ClrSleepEx(g_pConfig->StartupDelayMS(), FALSE);
745 if ((g_pConfig->GetGCStressLevel() & (EEConfig::GCSTRESS_INSTR_JIT | EEConfig::GCSTRESS_INSTR_NGEN)) != 0)
747 Disassembler::StaticInitialize();
748 if (!Disassembler::IsAvailable())
750 fprintf(stderr, "External disassembler is not available.\n");
754 #endif // USE_DISASSEMBLER
756 // Monitors, Crsts, and SimpleRWLocks all use the same spin heuristics
757 // Cache the (potentially user-overridden) values now so they are accessible from asm routines
758 InitializeSpinConstants();
760 #ifdef FEATURE_INTERPRETER
761 Interpreter::Initialize();
762 #endif // FEATURE_INTERPRETER
764 StubManager::InitializeStubManagers();
766 // Set up the cor handle map. This map is used to load assemblies in
767 // memory instead of using the normal system load
770 AccessCheckOptions::Startup();
772 CoreLibBinder::Startup();
775 StubLinkerCPU::Init();
776 StubPrecode::StaticInitialize();
777 FixupPrecode::StaticInitialize();
779 InitializeGarbageCollector();
781 if (!GCHandleUtilities::GetGCHandleManager()->Initialize())
783 IfFailGo(E_OUTOFMEMORY);
786 g_pEEShutDownEvent = new CLREvent();
787 g_pEEShutDownEvent->CreateManualEvent(FALSE);
789 VirtualCallStubManager::InitStatic();
792 // Setup the domains. Threads are started in a default domain.
794 // Static initialization
795 BaseDomain::Attach();
796 SystemDomain::Attach();
798 // Start up the EE initializing all the global variables
803 ExecutionManager::Init();
809 if (!RegisterOutOfProcessWatsonCallbacks())
813 #endif // !TARGET_UNIX
815 #ifdef DEBUGGING_SUPPORTED
816 // Initialize the debugging services. This must be done before any
817 // EE thread objects are created, and before any classes or
818 // modules are loaded.
819 InitializeDebugger(); // throws on error
820 #endif // DEBUGGING_SUPPORTED
822 #ifdef PROFILING_SUPPORTED
823 // Initialize the profiling services.
824 hr = ProfilingAPIUtility::InitializeProfiling();
826 _ASSERTE(SUCCEEDED(hr));
828 #endif // PROFILING_SUPPORTED
830 InitializeExceptionHandling();
833 // Install our global exception filter
835 if (!InstallUnhandledExceptionFilter())
843 #ifdef DEBUGGING_SUPPORTED
844 // Notify debugger once the first thread is created to finish initialization.
845 if (g_pDebugInterface != NULL)
847 g_pDebugInterface->StartupPhase2(GetThread());
851 InitPreStubManager();
853 #ifdef FEATURE_COMINTEROP
854 InitializeComInterop();
855 #endif // FEATURE_COMINTEROP
859 // Before setting up the execution manager initialize the first part
860 // of the JIT helpers.
864 SyncBlockCache::Attach();
866 // Set up the sync block
867 SyncBlockCache::Start();
869 StackwalkCache::Init();
871 // This isn't done as part of InitializeGarbageCollector() above because it
872 // requires write barriers to have been set up on x86, which happens as part
873 // of InitJITHelpers1.
874 hr = g_pGCHeap->Initialize();
877 LogErrorToHost("GC heap initialization failed with error 0x%08X", hr);
882 #ifdef FEATURE_PERFTRACING
883 // Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup.
884 // SampleProfiler needs to cooperate with the GC which hasn't fully finished setting up in the first part of the
885 // EventPipe initialization, so this is done after the GC has been fully initialized.
886 EventPipeAdapter::FinishInitialize();
887 #endif // FEATURE_PERFTRACING
888 GenAnalysis::Initialize();
890 // This isn't done as part of InitializeGarbageCollector() above because thread
891 // creation requires AppDomains to have been set up.
892 FinalizerThread::FinalizerThreadCreate();
894 // Now we really have fully initialized the garbage collector
895 SetGarbageCollectorFullyInitialized();
897 #ifdef DEBUGGING_SUPPORTED
898 // Make a call to publish the DefaultDomain for the debugger
899 // This should be done before assemblies/modules are loaded into it (i.e. SystemDomain::Init)
900 // and after its OK to switch GC modes and synchronize for sending events to the debugger.
901 // @dbgtodo synchronization: this can probably be simplified in V3
902 LOG((LF_CORDB | LF_SYNC | LF_STARTUP, LL_INFO1000, "EEStartup: adding default domain 0x%x\n",
903 SystemDomain::System()->DefaultDomain()));
904 SystemDomain::System()->PublishAppDomainAndInformDebugger(SystemDomain::System()->DefaultDomain());
912 Assembly::Initialize();
914 SystemDomain::System()->Init();
916 #ifdef PROFILING_SUPPORTED
917 // <TODO>This is to compensate for the DefaultDomain workaround contained in
918 // SystemDomain::Attach in which the first user domain is created before profiling
919 // services can be initialized. Profiling services cannot be moved to before the
920 // workaround because it needs SetupThread to be called.</TODO>
922 SystemDomain::NotifyProfilerStartup();
923 #endif // PROFILING_SUPPORTED
927 SystemDomain::System()->DefaultDomain()->LoadSystemAssemblies();
929 SystemDomain::System()->DefaultDomain()->SetupSharedStatics();
931 #ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
932 // retrieve configured max size for the mini-metadata buffer (defaults to 64KB)
933 g_MiniMetaDataBuffMaxSize = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MiniMdBufferCapacity);
934 // align up to GetOsPageSize(), with a maximum of 1 MB
935 g_MiniMetaDataBuffMaxSize = (DWORD) min(ALIGN_UP(g_MiniMetaDataBuffMaxSize, GetOsPageSize()), 1024 * 1024);
936 // allocate the buffer. this is never touched while the process is running, so it doesn't
937 // contribute to the process' working set. it is needed only as a "shadow" for a mini-metadata
938 // buffer that will be set up and reported / updated in the Watson process (the
939 // DacStreamsManager class coordinates this)
940 g_MiniMetaDataBuffAddress = (TADDR) ClrVirtualAlloc(NULL,
941 g_MiniMetaDataBuffMaxSize, MEM_COMMIT, PAGE_READWRITE);
942 #endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
945 g_EEStartupStatus = S_OK;
947 STRESS_LOG0(LF_STARTUP, LL_ALWAYS, "===================EEStartup Completed===================");
952 //if g_fEEStarted was false when we loaded the System Module, we did not run ExpandAll on it. In
953 //this case, make sure we run ExpandAll here. The rationale is that if we Jit before g_fEEStarted
954 //is true, we can't initialize Com, so we can't jit anything that uses Com types. Also, it's
955 //probably not safe to Jit while g_fEEStarted is false.
957 //Also, if you run this it's possible we'll call CoInitialize, which defaults to MTA. This might
958 //mess up an application that uses STA. However, this mode is only supported for certain limited
959 //jit testing scenarios, so it can live with the limitation.
960 if (g_pConfig->ExpandModulesOnLoad())
962 SystemDomain::SystemModule()->ExpandAll();
971 hr = GET_EXCEPTION()->GetHR();
973 EX_END_CATCH(RethrowTerminalExceptionsWithInitCheck)
982 g_EEStartupStatus = hr;
985 if (breakOnEELoad.val(CLRConfig::UNSUPPORTED_BreakOnEELoad) == 2)
988 _ASSERTE(!"Done loading EE!");
996 LONG FilterStartupException(PEXCEPTION_POINTERS p, PVOID pv)
1003 PRECONDITION(CheckPointer(p));
1004 PRECONDITION(CheckPointer(pv));
1007 g_EEStartupStatus = (HRESULT)p->ExceptionRecord->ExceptionInformation[0];
1009 // Make sure we got a failure code in this case
1010 if (!FAILED(g_EEStartupStatus))
1011 g_EEStartupStatus = E_FAIL;
1013 // Initializations has failed so reset the g_fEEInit flag.
1016 if (p->ExceptionRecord->ExceptionCode == BOOTUP_EXCEPTION_COMPLUS)
1018 // Don't ever handle the exception in a checked build
1020 return EXCEPTION_EXECUTE_HANDLER;
1024 return EXCEPTION_CONTINUE_SEARCH;
1027 // EEStartup is responsible for all the one time initialization of the runtime. Some of the highlights of
1028 // what it does include
1029 // * Creates the default and shared, appdomains.
1030 // * Loads System.Private.CoreLib and loads up the fundamental types (System.Object ...)
1032 // see code:EEStartup#TableOfContents for more on the runtime in general.
1033 // see code:#EEShutdown for an analogous routine run during shutdown.
1037 // Cannot use normal contracts here because of the PAL_TRY.
1038 STATIC_CONTRACT_NOTHROW;
1040 _ASSERTE(!g_fEEStarted && !g_fEEInit && SUCCEEDED (g_EEStartupStatus));
1042 PAL_TRY(PVOID, p, NULL)
1044 InitializeClrNotifications();
1046 InitializeJITNotificationTable();
1047 DacGlobals::Initialize();
1052 PAL_EXCEPT_FILTER (FilterStartupException)
1054 // The filter should have set g_EEStartupStatus to a failure HRESULT.
1055 _ASSERTE(FAILED(g_EEStartupStatus));
1059 return g_EEStartupStatus;
1064 // ---------------------------------------------------------------------------
1065 // %%Function: ForceEEShutdown()
1067 // Description: Force the EE to shutdown now.
1069 // Note: returns when sca is SCA_ReturnWhenShutdownComplete.
1070 // ---------------------------------------------------------------------------
1071 void ForceEEShutdown(ShutdownCompleteAction sca)
1073 WRAPPER_NO_CONTRACT;
1075 // Don't bother to take the lock for this case.
1077 STRESS_LOG0(LF_STARTUP, INFO3, "EEShutdown invoked from ForceEEShutdown");
1078 EEPolicy::HandleExitProcess(sca);
1081 void WaitForEndOfShutdown()
1089 // We are shutting down. GC triggers does not have any effect now.
1090 CONTRACT_VIOLATION(GCViolation);
1092 Thread *pThread = GetThreadNULLOk();
1093 // After a thread is blocked in WaitForEndOfShutdown, the thread should not enter runtime again,
1094 // and block at WaitForEndOfShutdown again.
1097 _ASSERTE(!pThread->HasThreadStateNC(Thread::TSNC_BlockedForShutdown));
1098 pThread->SetThreadStateNC(Thread::TSNC_BlockedForShutdown);
1101 for (;;) g_pEEShutDownEvent->Wait(INFINITE, TRUE);
1104 // ---------------------------------------------------------------------------
1105 // Function: EEShutDownHelper(BOOL fIsDllUnloading)
1107 // The real meat of shut down happens here. See code:#EEShutDown for details, including
1108 // what fIsDllUnloading means.
1110 void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
1119 // Used later for a callback.
1125 PgoManager::Shutdown();
1130 EX_END_CATCH(SwallowAllExceptions);
1133 if (!fIsDllUnloading)
1135 ETW::EnumerationLog::ProcessShutdown();
1137 #ifdef FEATURE_PERFTRACING
1138 EventPipeAdapter::Shutdown();
1139 DiagnosticServerAdapter::Shutdown();
1140 #endif // FEATURE_PERFTRACING
1143 #if defined(FEATURE_COMINTEROP)
1144 // Get the current thread.
1145 Thread * pThisThread = GetThreadNULLOk();
1148 // If the process is detaching then set the global state.
1149 // This is used to get around FreeLibrary problems.
1151 g_fProcessDetach = true;
1153 if (IsDbgHelperSpecialThread())
1155 // Our debugger helper thread does not allow Thread object to be set up.
1156 // We should not run shutdown code on debugger helper thread.
1157 _ASSERTE(fIsDllUnloading);
1161 STRESS_LOG1(LF_STARTUP, LL_INFO10, "EEShutDown entered unloading = %d", fIsDllUnloading);
1164 if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_BreakOnEEShutdown))
1165 _ASSERTE(!"Shutting down EE!");
1168 #ifdef DEBUGGING_SUPPORTED
1169 // This is a nasty, terrible, horrible thing. If we're being
1170 // called from our DLL main, then the odds are good that our DLL
1171 // main has been called as the result of some person calling
1172 // ExitProcess. That rips the debugger helper thread away very
1173 // ungracefully. This check is an attempt to recognize that case
1174 // and avoid the impending hang when attempting to get the helper
1175 // thread to do things for us.
1176 if ((g_pDebugInterface != NULL) && g_fProcessDetach)
1177 g_pDebugInterface->EarlyHelperThreadDeath();
1178 #endif // DEBUGGING_SUPPORTED
1182 ClrFlsSetThreadType(ThreadType_Shutdown);
1184 if (fIsDllUnloading && g_fEEShutDown)
1186 // I'm in the final shutdown and the first part has already been run.
1190 // Indicate the EE is the shut down phase.
1191 g_fEEShutDown |= ShutDown_Start;
1193 if (!g_fProcessDetach && !g_fFastExitProcess)
1195 g_fEEShutDown |= ShutDown_Finalize1;
1197 // Wait for the finalizer thread to deliver process exit event
1199 FinalizerThread::RaiseShutdownEvents();
1202 // Ok. Let's stop the EE.
1203 if (!g_fProcessDetach)
1205 // Convert key locks into "shutdown" mode. A lock in shutdown mode means:
1206 // - Only the finalizer/helper/shutdown threads will be able to take the lock.
1207 // - Any other thread that tries takes it will just get redirected to an endless WaitForEndOfShutdown().
1209 // The only managed code that should run after this point is the finalizers for shutdown.
1210 // We convert locks needed for running + debugging such finalizers. Since such locks may need to be
1211 // juggled between multiple threads (finalizer/helper/shutdown), no single thread can take the
1212 // lock and not give it up.
1214 // Each lock needs its own shutdown flag (they can't all be converted at once).
1215 // To avoid deadlocks, we need to convert locks in order of crst level (biggest first).
1217 // Notify the debugger that we're going into shutdown to convert debugger-lock to shutdown.
1218 if (g_pDebugInterface != NULL)
1220 g_pDebugInterface->LockDebuggerForShutdown();
1223 // This call will convert the ThreadStoreLock into "shutdown" mode, just like the debugger lock above.
1224 g_fEEShutDown |= ShutDown_Finalize2;
1227 #ifdef FEATURE_EVENT_TRACE
1228 // Flush managed object allocation logging data.
1229 // We do this after finalization is complete and returning threads have been trapped, so that
1230 // no there will be no more managed allocations and no more GCs which will manipulate the
1231 // allocation sampling data structures.
1232 ETW::TypeSystemLog::FlushObjectAllocationEvents();
1233 #endif // FEATURE_EVENT_TRACE
1235 #ifdef FEATURE_PERFMAP
1236 // Flush and close the perf map file.
1240 ceeInf.JitProcessShutdownWork(); // Do anything JIT-related that needs to happen at shutdown.
1242 #ifdef FEATURE_INTERPRETER
1243 // This will check a flag and do nothing if not enabled.
1244 Interpreter::PrintPostMortemData();
1245 #endif // FEATURE_INTERPRETER
1247 #ifdef PROFILING_SUPPORTED
1248 // If profiling is enabled, then notify of shutdown first so that the
1249 // profiler can make any last calls it needs to. Do this only if we
1250 // are not detaching
1252 // NOTE: We haven't stopped other threads at this point and nothing is stopping
1253 // callbacks from coming into the profiler even after Shutdown() has been called.
1254 // See https://github.com/dotnet/runtime/issues/11885 for an example of how that
1257 // To prevent issues when profilers are attached we intentionally skip freeing the
1258 // profiler here. Since there is no guarantee that the profiler won't be accessed after
1259 // we free it (e.g. through callbacks or ELT hooks), we can't safely free the profiler.
1260 if (CORProfilerPresent())
1262 // Don't call back in to the profiler if we are being torn down, it might be unloaded
1263 if (!fIsDllUnloading)
1265 BEGIN_PROFILER_CALLBACK(CORProfilerPresent());
1267 (&g_profControlBlock)->Shutdown();
1268 END_PROFILER_CALLBACK();
1271 g_fEEShutDown |= ShutDown_Profiler;
1273 #endif // PROFILING_SUPPORTED
1277 g_fEEShutDown |= ShutDown_SyncBlock;
1280 // From here on out we might call stuff that violates mode requirements, but we ignore these
1281 // because we are shutting down.
1282 CONTRACT_VIOLATION(ModeViolation);
1284 #ifdef FEATURE_COMINTEROP
1285 // We need to call CoUninitialize in part one to ensure orderly shutdown of COM dlls.
1286 if (!g_fFastExitProcess)
1288 if (pThisThread!= NULL)
1290 pThisThread->CoUninitialize();
1293 #endif // FEATURE_COMINTEROP
1296 // This is the end of Part 1.
1299 // If process shutdown is in progress and Crst locks to be used in shutdown phase 2
1300 // are already in use, then skip phase 2. This will happen only when those locks
1301 // are orphaned. In Vista, the penalty for attempting to enter such locks is
1302 // instant process termination.
1303 if (g_fProcessDetach)
1305 // The assert below is a bit too aggressive and has generally brought cases that have been race conditions
1306 // and not easily reproed to validate a bug. A typical race scenario is when there are two threads,
1307 // T1 and T2, with T2 having taken a lock (e.g. SystemDomain lock), the OS terminates
1308 // T2 for some reason. Later, when we enter the shutdown thread, we would assert on such
1309 // a lock leak, but there is not much we can do since the OS wont notify us prior to thread
1310 // termination. And this is not even a user bug.
1312 // Converting it to a STRESS LOG to reduce noise, yet keep things in radar if they need
1313 // to be investigated.
1314 //_ASSERTE_MSG(g_ShutdownCrstUsageCount == 0, "Some locks to be taken during shutdown may already be orphaned!");
1315 if (g_ShutdownCrstUsageCount > 0)
1317 STRESS_LOG0(LF_STARTUP, LL_INFO10, "Some locks to be taken during shutdown may already be orphaned!");
1323 CONTRACT_VIOLATION(ModeViolation);
1325 // On the new plan, we only do the tear-down under the protection of the loader
1326 // lock -- after the OS has stopped all other threads.
1327 if (fIsDllUnloading && (g_fEEShutDown & ShutDown_Phase2) == 0)
1329 g_fEEShutDown |= ShutDown_Phase2;
1331 // Shutdown finalizer before we suspend all background threads. Otherwise we
1332 // never get to finalize anything.
1334 // No longer process exceptions
1335 g_fNoExceptions = true;
1337 // <TODO>@TODO: This does things which shouldn't occur in part 2. Namely,
1338 // calling managed dll main callbacks (AppDomain::SignalProcessDetach), and
1339 // RemoveAppDomainFromIPC.
1341 // (If we move those things to earlier, this can be called only if fShouldWeCleanup.)</TODO>
1342 if (!g_fFastExitProcess)
1344 SystemDomain::DetachBegin();
1348 #ifdef DEBUGGING_SUPPORTED
1349 // Terminate the debugging services.
1350 TerminateDebugger();
1351 #endif // DEBUGGING_SUPPORTED
1353 StubManager::TerminateStubManagers();
1355 #ifdef FEATURE_INTERPRETER
1356 Interpreter::Terminate();
1357 #endif // FEATURE_INTERPRETER
1359 //@TODO: find the right place for this
1360 VirtualCallStubManager::UninitStatic();
1362 // Unregister our vectored exception and continue handlers from the OS.
1363 // This will ensure that if any other DLL unload (after ours) has an exception,
1364 // we wont attempt to process that exception (which could lead to various
1365 // issues including AV in the runtime).
1367 // This should be done:
1369 // 1) As the last action during the shutdown so that any unexpected AVs
1370 // in the runtime during shutdown do result in FailFast in VEH.
1372 // 2) Only when the runtime is processing DLL_PROCESS_DETACH.
1373 CLRRemoveVectoredHandlers();
1375 #if USE_DISASSEMBLER
1376 Disassembler::StaticClose();
1377 #endif // USE_DISASSEMBLER
1379 WriteJitHelperCountToSTRESSLOG();
1381 STRESS_LOG0(LF_STARTUP, LL_INFO10, "EEShutdown shutting down logging");
1383 #if 0 // Dont clean up the stress log, so that even at process exit we have a log (after all the process is going away
1384 if (!g_fFastExitProcess)
1385 StressLog::Terminate(TRUE);
1391 GCHeapUtilities::GetGCHeap()->Shutdown();
1400 EX_END_CATCH(SwallowAllExceptions);
1402 ClrFlsClearThreadType(ThreadType_Shutdown);
1403 if (!g_fProcessDetach)
1405 g_pEEShutDownEvent->Set();
1410 #ifdef FEATURE_COMINTEROP
1412 BOOL IsThreadInSTA()
1422 // If ole32.dll is not loaded
1423 if (WszGetModuleHandle(W("ole32.dll")) == NULL)
1429 // To be conservative, check if finalizer thread is around
1432 Thread *pFinalizerThread = FinalizerThread::GetFinalizerThread();
1433 if (!pFinalizerThread || pFinalizerThread->Join(0, FALSE) != WAIT_TIMEOUT)
1441 EX_END_CATCH(SwallowAllExceptions);
1451 hr = GetCurrentThreadTypeNT5(&type);
1454 fInSTA = (type == THDTYPE_PROCESSMESSAGES) ? TRUE : FALSE;
1456 // If we get back THDTYPE_PROCESSMESSAGES, we are guaranteed to
1457 // be an STA thread. If not, we are an MTA thread, however
1458 // we can't know if the thread has been explicitly set to MTA
1459 // (via a call to CoInitializeEx) or if it has been implicitly
1460 // made MTA (if it hasn't been CoInitializeEx'd but CoInitialize
1461 // has already been called on some other thread in the process.
1465 // CoInitialize hasn't been called in the process yet so assume the current thread
1476 // Function: EEShutDown(BOOL fIsDllUnloading)
1479 // BOOL fIsDllUnloading:
1480 // * TRUE => Called from CLR's DllMain (DLL_PROCESS_DETACH). Not safe point for
1482 // * FALSE => Called some other way (e.g., end of the CLR's main). Safe to do
1487 // All ee shutdown stuff should be done here. EEShutDown is generally called in one
1489 // * 1. From code:EEPolicy::HandleExitProcess (via HandleExitProcessHelper), with
1490 // fIsDllUnloading == FALSE. This code path is typically invoked by the CLR's
1491 // main just falling through to the end. Full cleanup can be performed when
1492 // EEShutDown is called this way.
1493 // * 2. From CLR's DllMain (DLL_PROCESS_DETACH), with fIsDllUnloading == TRUE. When
1494 // called this way, much cleanup code is unsafe to run, and is thus skipped.
1496 // Actual shut down logic is factored out to EEShutDownHelper which may be called
1497 // directly by EEShutDown, or indirectly on another thread (see code:#STAShutDown).
1499 // In order that callees may also know the value of fIsDllUnloading, EEShutDownHelper
1500 // sets g_fProcessDetach = fIsDllUnloading, and g_fProcessDetach may then be retrieved
1501 // via code:IsAtProcessExit.
1503 // NOTE 1: Actually, g_fProcessDetach is set to TRUE if fIsDllUnloading is TRUE. But
1504 // g_fProcessDetach doesn't appear to be explicitly set to FALSE. (Apparently
1505 // g_fProcessDetach is implicitly initialized to FALSE as clr.dll is loaded.)
1507 // NOTE 2: EEDllMain(DLL_PROCESS_DETACH) already sets g_fProcessDetach to TRUE, so it
1508 // appears EEShutDownHelper doesn't have to.
1510 void STDMETHODCALLTYPE EEShutDown(BOOL fIsDllUnloading)
1516 PRECONDITION(g_fEEStarted);
1519 // If we have not started runtime successfully, it is not safe to call EEShutDown.
1520 if (!g_fEEStarted || g_fFastExitProcess == 2)
1525 // We only do the first part of the shutdown once.
1526 static LONG OnlyOne = -1;
1528 if (!fIsDllUnloading)
1530 if (InterlockedIncrement(&OnlyOne) != 0)
1532 // I'm in a regular shutdown -- but another thread got here first.
1533 // It's a race if I return from here -- I'll call ExitProcess next, and
1534 // rip things down while the first thread is half-way through a
1535 // nice cleanup. Rather than do that, I should just wait until the
1536 // first thread calls ExitProcess(). I'll die a nice death when that
1538 GCX_PREEMP_NO_DTOR();
1539 WaitForEndOfShutdown();
1543 #ifdef FEATURE_MULTICOREJIT
1544 MulticoreJitManager::StopProfileAll();
1548 if (GetThreadNULLOk())
1551 EEShutDownHelper(fIsDllUnloading);
1555 EEShutDownHelper(fIsDllUnloading);
1559 // ---------------------------------------------------------------------------
1560 // %%Function: IsRuntimeActive()
1568 // Description: Indicates if the runtime is active or not. "Active" implies
1569 // that the runtime has started and is in a position to run
1571 // ---------------------------------------------------------------------------
1572 BOOL IsRuntimeActive()
1574 return (g_fEEStarted);
1577 //*****************************************************************************
1578 BOOL ExecuteDLL_ReturnOrThrow(HRESULT hr, BOOL fFromThunk)
1581 if (fFromThunk) THROWS; else NOTHROW;
1582 WRAPPER(GC_TRIGGERS);
1586 // If we have a failure result, and we're called from a thunk,
1587 // then we need to throw an exception to communicate the error.
1588 if (FAILED(hr) && fFromThunk)
1592 return SUCCEEDED(hr);
1596 // Initialize the Garbage Collector
1599 void InitializeGarbageCollector()
1609 // Build the special Free Object used by the Generational GC
1610 _ASSERT(g_pFreeObjectMethodTable == NULL);
1611 g_pFreeObjectMethodTable = (MethodTable *) new BYTE[sizeof(MethodTable)];
1612 ZeroMemory(g_pFreeObjectMethodTable, sizeof(MethodTable));
1614 // As the flags in the method table indicate there are no pointers
1615 // in the object, there is no gc descriptor, and thus no need to adjust
1616 // the pointer to skip the gc descriptor.
1618 g_pFreeObjectMethodTable->SetBaseSize(ARRAYBASE_BASESIZE);
1619 g_pFreeObjectMethodTable->SetComponentSize(1);
1621 hr = GCHeapUtilities::LoadAndInitialize();
1625 LogErrorToHost("GC initialization failed with error 0x%08X", hr);
1629 // Apparently the Windows linker removes global variables if they are never
1630 // read from, which is a problem for g_gcDacGlobals since it's expected that
1631 // only the DAC will read from it. This forces the linker to include
1633 volatile void* _dummy = g_gcDacGlobals;
1636 /*****************************************************************************/
1637 /* This is here only so that if we get an exception we stop before we catch it */
1638 LONG DllMainFilter(PEXCEPTION_POINTERS p, PVOID pv)
1640 LIMITED_METHOD_CONTRACT;
1641 _ASSERTE(!"Exception happened in mscorwks!DllMain!");
1642 return EXCEPTION_EXECUTE_HANDLER;
1645 #if !defined(CORECLR_EMBEDDED)
1647 //*****************************************************************************
1648 // This is the part of the old-style DllMain that initializes the
1649 // stuff that the EE team works on. It's called from the real DllMain
1650 // up in MSCOREE land. Separating the DllMain tasks is simply for
1651 // convenience due to the dual build trees.
1652 //*****************************************************************************
1653 BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
1654 HINSTANCE hInst, // Instance handle of the loaded module.
1655 DWORD dwReason, // Reason for loading.
1656 LPVOID lpReserved) // Unused.
1658 STATIC_CONTRACT_NOTHROW;
1659 STATIC_CONTRACT_GC_TRIGGERS;
1662 // BEGIN_EXTERNAL_ENTRYPOINT(&hr);
1663 // EE isn't spun up enough to use this macro
1671 param.hInst = hInst;
1672 param.dwReason = dwReason;
1673 param.lpReserved = lpReserved;
1675 // Can't use PAL_TRY/EX_TRY here as they access the ClrDebugState which gets blown away as part of the
1676 // PROCESS_DETACH path. Must use special PAL_TRY_FOR_DLLMAIN, passing the reason were in the DllMain.
1677 PAL_TRY_FOR_DLLMAIN(Param *, pParam, ¶m, pParam->dwReason)
1680 switch (pParam->dwReason)
1682 case DLL_PROCESS_DETACH:
1684 // lpReserved is NULL if we're here because someone called FreeLibrary
1685 // and non-null if we're here because the process is exiting.
1686 // Since nobody should ever be calling FreeLibrary on mscorwks.dll, lpReserved
1687 // should always be non NULL.
1688 _ASSERTE(pParam->lpReserved || !g_fEEStarted);
1689 g_fProcessDetach = TRUE;
1693 if (GCHeapUtilities::IsGCInProgress())
1695 g_fEEShutDown |= ShutDown_Phase2;
1699 LOG((LF_STARTUP, INFO3, "EEShutDown invoked from EEDllMain"));
1700 EEShutDown(TRUE); // shut down EE if it was started up
1704 CLRRemoveVectoredHandlers();
1711 PAL_EXCEPT_FILTER(DllMainFilter)
1719 #endif // !defined(CORECLR_EMBEDDED)
1721 struct TlsDestructionMonitor
1723 bool m_activated = false;
1730 ~TlsDestructionMonitor()
1734 Thread* thread = GetThreadNULLOk();
1737 #ifdef FEATURE_COMINTEROP
1738 // reset the CoInitialize state
1739 // so we don't call CoUninitialize during thread detach
1740 thread->ResetCoInitialized();
1741 #endif // FEATURE_COMINTEROP
1742 // For case where thread calls ExitThread directly, we need to reset the
1743 // frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
1744 // We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
1745 if (thread->m_pFrame != FRAME_TOP)
1748 thread->m_GCOnTransitionsOK = FALSE;
1751 thread->m_pFrame = FRAME_TOP;
1752 GCX_COOP_NO_DTOR_END();
1754 thread->DetachThread(TRUE);
1762 // This thread local object is used to detect thread shutdown. Its destructor
1763 // is called when a thread is being shut down.
1764 thread_local TlsDestructionMonitor tls_destructionMonitor;
1766 void EnsureTlsDestructionMonitor()
1768 tls_destructionMonitor.Activate();
1771 #ifdef DEBUGGING_SUPPORTED
1773 // InitializeDebugger initialized the Runtime-side COM+ Debugging Services
1775 static void InitializeDebugger(void)
1785 // Ensure that if we throw, we'll call TerminateDebugger to cleanup.
1786 // This makes our Init more atomic by avoiding partially-init states.
1787 class EnsureCleanup {
1792 fNeedCleanup = TRUE;
1795 void SuppressCleanup()
1797 fNeedCleanup = FALSE;
1802 STATIC_CONTRACT_NOTHROW;
1803 STATIC_CONTRACT_GC_NOTRIGGER;
1804 STATIC_CONTRACT_MODE_ANY;
1808 TerminateDebugger();
1815 LOG((LF_CORDB, LL_INFO10, "Initializing left-side debugging services.\n"));
1817 FARPROC gi = (FARPROC) &CorDBGetInterface;
1819 // Init the interface the EE provides to the debugger,
1820 // ask the debugger for its interface, and if all goes
1821 // well call Startup on the debugger.
1822 EEDbgInterfaceImpl::Init();
1823 _ASSERTE(g_pEEDbgInterfaceImpl != NULL); // throws on OOM
1825 // This allocates the Debugger object.
1826 typedef HRESULT __cdecl CORDBGETINTERFACE(DebugInterface**);
1827 hr = ((CORDBGETINTERFACE*)gi)(&g_pDebugInterface);
1830 g_pDebugInterface->SetEEInterface(g_pEEDbgInterfaceImpl);
1833 hr = g_pDebugInterface->Startup(); // throw on error
1834 _ASSERTE(SUCCEEDED(hr));
1837 // If the debug pack is not installed, Startup will return S_FALSE
1838 // and we should cleanup and proceed without debugging support.
1847 LOG((LF_CORDB, LL_INFO10, "Left-side debugging services setup.\n"));
1849 hCleanup.SuppressCleanup();
1856 // TerminateDebugger shuts down the Runtime-side COM+ Debugging Services
1857 // InitializeDebugger will call this if it fails.
1858 // This may be called even if the debugger is partially initialized.
1859 // This can be called multiple times.
1861 static void TerminateDebugger(void)
1871 LOG((LF_CORDB, LL_INFO10, "Shutting down left-side debugger services.\n"));
1873 // If initialized failed really early, then we didn't even get the Debugger object.
1874 if (g_pDebugInterface != NULL)
1876 // Notify the out-of-process debugger that shutdown of the in-process debugging support has begun. This is only
1877 // really used in interop debugging scenarios.
1878 g_pDebugInterface->ShutdownBegun();
1880 // This will kill the helper thread, delete the Debugger object, and free all resources.
1881 g_pDebugInterface->StopDebugger();
1884 g_CORDebuggerControlFlags = DBCF_NORMAL_OPERATION;
1888 #endif // DEBUGGING_SUPPORTED
1890 #ifndef LOCALE_SPARENT
1891 #define LOCALE_SPARENT 0x0000006d
1894 // ---------------------------------------------------------------------------
1895 // Impl for UtilLoadStringRC Callback: In VM, we let the thread decide culture
1896 // copy culture name into szBuffer and return length
1897 // ---------------------------------------------------------------------------
1898 extern BOOL g_fFatalErrorOccurredOnGCThread;
1899 static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames)
1906 PRECONDITION(CheckPointer(pCultureNames));
1914 InlineSString<LOCALE_NAME_MAX_LENGTH> sCulture;
1915 InlineSString<LOCALE_NAME_MAX_LENGTH> sParentCulture;
1917 #if 0 // Enable and test if/once the unmanaged runtime is localized
1918 Thread * pThread = GetThreadNULLOk();
1920 // When fatal errors have occurred our invariants around GC modes may be broken and attempting to transition to co-op may hang
1921 // indefinitely. We want to ensure a clean exit so rather than take the risk of hang we take a risk of the error resource not
1922 // getting localized with a non-default thread-specific culture.
1923 // A canonical stack trace that gets here is a fatal error in the GC that comes through:
1924 // coreclr.dll!GetThreadUICultureNames
1925 // coreclr.dll!CCompRC::LoadLibraryHelper
1926 // coreclr.dll!CCompRC::LoadLibrary
1927 // coreclr.dll!CCompRC::GetLibrary
1928 // coreclr.dll!CCompRC::LoadString
1929 // coreclr.dll!CCompRC::LoadString
1930 // coreclr.dll!SString::LoadResourceAndReturnHR
1931 // coreclr.dll!SString::LoadResourceAndReturnHR
1932 // coreclr.dll!SString::LoadResource
1933 // coreclr.dll!EventReporter::EventReporter
1934 // coreclr.dll!EEPolicy::LogFatalError
1935 // coreclr.dll!EEPolicy::HandleFatalError
1936 if (pThread != NULL && !g_fFatalErrorOccurredOnGCThread) {
1938 // Switch to cooperative mode, since we'll be looking at managed objects
1939 // and we don't want them moving on us.
1942 CULTUREINFOBASEREF pCurrentCulture = (CULTUREINFOBASEREF)Thread::GetCulture(TRUE);
1944 if (pCurrentCulture != NULL)
1946 STRINGREF cultureName = pCurrentCulture->GetName();
1948 if (cultureName != NULL)
1950 sCulture.Set(cultureName->GetBuffer(),cultureName->GetStringLength());
1953 CULTUREINFOBASEREF pParentCulture = pCurrentCulture->GetParent();
1955 if (pParentCulture != NULL)
1957 STRINGREF parentCultureName = pParentCulture->GetName();
1959 if (parentCultureName != NULL)
1961 sParentCulture.Set(parentCultureName->GetBuffer(),parentCultureName->GetStringLength());
1969 // If the lazily-initialized cultureinfo structures aren't initialized yet, we'll
1970 // need to do the lookup the hard way.
1971 if (sCulture.IsEmpty() || sParentCulture.IsEmpty())
1974 int tmp; tmp = GetThreadUICultureId(&id); // TODO: We should use the name instead
1975 _ASSERTE(tmp!=0 && id != UICULTUREID_DONTCARE);
1976 SIZE_T cchParentCultureName=LOCALE_NAME_MAX_LENGTH;
1980 if (!::GetLocaleInfoEx((LPCWSTR)sCulture, LOCALE_SPARENT, sParentCulture.OpenUnicodeBuffer(static_cast<COUNT_T>(cchParentCultureName)),static_cast<int>(cchParentCultureName)))
1982 hr = HRESULT_FROM_GetLastError();
1984 sParentCulture.CloseBuffer();
1985 #else // !TARGET_UNIX
1986 sParentCulture = sCulture;
1987 #endif // !TARGET_UNIX
1989 // (LPCWSTR) to restrict the size to null terminated size
1990 pCultureNames->AppendIfNotThere((LPCWSTR)sCulture);
1991 // Disabling for Dev10 for consistency with managed resource lookup (see AppCompat bug notes in ResourceFallbackManager.cs)
1992 // Also, this is in the wrong order - put after the parent culture chain.
1993 //AddThreadPreferredUILanguages(pCultureNames);
1994 pCultureNames->AppendIfNotThere((LPCWSTR)sParentCulture);
1995 pCultureNames->Append(SString::Empty());
2001 EX_END_CATCH(SwallowAllExceptions);
2006 // The exit code for the process is communicated in one of two ways. If the
2007 // entrypoint returns an 'int' we take that. Otherwise we take a latched
2008 // process exit code. This can be modified by the app via System.SetExitCode().
2009 static INT32 LatchedExitCode;
2011 void SetLatchedExitCode (INT32 code)
2021 STRESS_LOG1(LF_SYNC, LL_INFO10, "SetLatchedExitCode = %d\n", code);
2022 LatchedExitCode = code;
2025 INT32 GetLatchedExitCode (void)
2027 LIMITED_METHOD_CONTRACT;
2028 return LatchedExitCode;
2031 // ---------------------------------------------------------------------------
2032 // Impl for UtilLoadStringRC Callback: In VM, we let the thread decide culture
2033 // Return an int uniquely describing which language this thread is using for ui.
2034 // ---------------------------------------------------------------------------
2035 static int GetThreadUICultureId(_Out_ LocaleIDValue* pLocale)
2043 _ASSERTE(sizeof(LocaleIDValue)/sizeof(WCHAR) >= LOCALE_NAME_MAX_LENGTH);
2047 Thread * pThread = GetThreadNULLOk();
2049 #if 0 // Enable and test if/once the unmanaged runtime is localized
2050 // When fatal errors have occurred our invariants around GC modes may be broken and attempting to transition to co-op may hang
2051 // indefinitely. We want to ensure a clean exit so rather than take the risk of hang we take a risk of the error resource not
2052 // getting localized with a non-default thread-specific culture.
2053 // A canonical stack trace that gets here is a fatal error in the GC that comes through:
2054 // coreclr.dll!GetThreadUICultureNames
2055 // coreclr.dll!CCompRC::LoadLibraryHelper
2056 // coreclr.dll!CCompRC::LoadLibrary
2057 // coreclr.dll!CCompRC::GetLibrary
2058 // coreclr.dll!CCompRC::LoadString
2059 // coreclr.dll!CCompRC::LoadString
2060 // coreclr.dll!SString::LoadResourceAndReturnHR
2061 // coreclr.dll!SString::LoadResourceAndReturnHR
2062 // coreclr.dll!SString::LoadResource
2063 // coreclr.dll!EventReporter::EventReporter
2064 // coreclr.dll!EEPolicy::LogFatalError
2065 // coreclr.dll!EEPolicy::HandleFatalError
2066 if (pThread != NULL && !g_fFatalErrorOccurredOnGCThread)
2069 // Switch to cooperative mode, since we'll be looking at managed objects
2070 // and we don't want them moving on us.
2073 CULTUREINFOBASEREF pCurrentCulture = (CULTUREINFOBASEREF)Thread::GetCulture(TRUE);
2075 if (pCurrentCulture != NULL)
2077 STRINGREF currentCultureName = pCurrentCulture->GetName();
2079 if (currentCultureName != NULL)
2081 int cchCurrentCultureNameResult = currentCultureName->GetStringLength();
2082 if (cchCurrentCultureNameResult < LOCALE_NAME_MAX_LENGTH)
2084 memcpy(*pLocale, currentCultureName->GetBuffer(), cchCurrentCultureNameResult*sizeof(WCHAR));
2085 (*pLocale)[cchCurrentCultureNameResult]='\0';
2086 Result=cchCurrentCultureNameResult;
2095 // This thread isn't set up to use a non-default culture. Let's grab the default
2096 // one and return that.
2098 Result = ::GetUserDefaultLocaleName(*pLocale, LOCALE_NAME_MAX_LENGTH);
2100 _ASSERTE(Result != 0);
2101 #else // !TARGET_UNIX
2102 static const WCHAR enUS[] = W("en-US");
2103 memcpy(*pLocale, enUS, sizeof(enUS));
2104 Result = sizeof(enUS);
2105 #endif // !TARGET_UNIX
2110 #ifdef ENABLE_CONTRACTS_IMPL
2112 // Returns TRUE if any contract violation suppressions are in effect.
2113 BOOL AreAnyViolationBitsOn()
2122 UINT_PTR violationMask = GetClrDebugState()->ViolationMask();
2123 violationMask &= ~((UINT_PTR)CanFreeMe); //CanFreeMe is a borrowed bit and has nothing to do with violations
2124 if (violationMask & ((UINT_PTR)BadDebugState))
2129 return violationMask != 0;
2133 // This function is intentionally invoked inside a big CONTRACT_VIOLATION that turns on every violation
2134 // bit on the map. The dynamic contract at the beginning *should* turn off those violation bits.
2135 // The body of this function tests to see that it did exactly that. This is to prevent the VSWhidbey B#564831 fiasco
2136 // from ever recurring.
2137 void ContractRegressionCheckInner()
2139 // DO NOT TURN THIS CONTRACT INTO A STATIC CONTRACT!!! The very purpose of this function
2140 // is to ensure that dynamic contracts disable outstanding contract violation bits.
2141 // This code only runs once at process startup so it's not going pooch the checked build perf.
2147 LOADS_TYPE(CLASS_LOAD_BEGIN);
2152 if (AreAnyViolationBitsOn())
2154 // If we got here, the contract above FAILED to turn off one or more violation bits. This is a
2155 // huge diagnostics hole and must be fixed immediately.
2156 _ASSERTE(!("WARNING: mscorwks has detected an internal error that may indicate contracts are"
2157 " being silently disabled across the runtime. Do not ignore this assert!"));
2161 // This function executes once per process to ensure our CONTRACT_VIOLATION() mechanism
2162 // is properly scope-limited by nested contracts.
2163 void ContractRegressionCheck()
2174 // DO NOT "FIX" THIS CONTRACT_VIOLATION!!!
2175 // The existence of this CONTRACT_VIOLATION is not a bug. This is debug-only code specifically written
2176 // to test the CONTRACT_VIOLATION mechanism itself. This is needed to prevent a regression of
2177 // B#564831 (which left a huge swath of contracts silently disabled for over six months)
2178 PERMANENT_CONTRACT_VIOLATION(ThrowsViolation
2181 | LoadsTypeViolation
2182 | TakesLockViolation
2183 , ReasonContractInfrastructure
2187 ContractRegressionCheckInner();
2191 if (AreAnyViolationBitsOn())
2193 // If we got here, the CONTRACT_VIOLATION() holder left one or more violation bits turned ON
2194 // after we left its scope. This is a huge diagnostic hole and must be fixed immediately.
2195 _ASSERTE(!("WARNING: mscorwks has detected an internal error that may indicate contracts are"
2196 " being silently disabled across the runtime. Do not ignore this assert!"));
2201 #endif // ENABLE_CONTRACTS_IMPL