Sync may31 release/8.0-tizen (#510)
[platform/upstream/dotnet/runtime.git] / src / coreclr / vm / ceemain.cpp
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 // ===========================================================================
4 // File: CEEMAIN.CPP
5 // ===========================================================================
6 //
7
8 //
9 //
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
12 //
13 //     \\clrmain\tools\installCLRAddins
14 //
15 //  After installing HyperAddin, your first run of VS should be as an administrator so HyperAddin can update
16 //  some registry information.
17 //
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
20 //
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.
25 //
26 // #StartHere
27 // #TableOfContents The .NET Runtime Table of contents
28 //
29 // This comment is mean to be a nexus that allows you to jump quickly to various interesting parts of the
30 // runtime.
31 //
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
35 //
36 //  Dev10 Bugs can be added with URLs like the following (for Dev10 bug 671409)
37 //     * http://tkbgitvstfat01:8090/wi.aspx?id=671409
38 //
39 //*************************************************************************************************
40 //
41 // * Introduction to the runtime file:../../Documentation/botr/botr-faq.md
42 //
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
53 //
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
59 //     * Partition III IL
60 //         http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20III%20CIL.doc
61 //
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
64 //
65 // * This is also a pretty nice overview of what the CLR is at
66 //     http://msdn2.microsoft.com/en-us/netframework/aa497266.aspx
67 //
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.
71 //
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.
74 //
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.
79 //
80 // * code:VirtualCallStubManager - This is the main class that implements interface dispatch
81 //
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.
85 //
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
89 //      NGEN image.
90 //
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
98 //       exception happens.
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.
111
112 // ----------------------------------------------------------------------------------------------------
113 // Features in the runtime that have been given hyperlinks
114 //
115 // * code:Nullable#NullableFeature - the Nullable<T> type has special runtime semantics associated with
116 //     boxing this describes this feature.
117
118 #include "common.h"
119
120 #include "vars.hpp"
121 #include "log.h"
122 #include "ceemain.h"
123 #include "clsload.hpp"
124 #include "object.h"
125 #include "hash.h"
126 #include "ecall.h"
127 #include "ceemain.h"
128 #include "dllimport.h"
129 #include "syncblk.h"
130 #include "eeconfig.h"
131 #include "stublink.h"
132 #include "method.hpp"
133 #include "codeman.h"
134 #include "frames.h"
135 #include "threads.h"
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"
147 #include "corhost.h"
148 #include "binder.h"
149 #include "olevariant.h"
150 #include "comcallablewrapper.h"
151 #include "../dlls/mscorrc/resource.h"
152 #include "util.hpp"
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"
163 #include "jithost.h"
164 #include "pgo.h"
165
166 #ifndef TARGET_UNIX
167 #include "dwreport.h"
168 #endif // !TARGET_UNIX
169
170 #include "stringarraylist.h"
171 #include "stubhelpers.h"
172
173 #ifdef FEATURE_COMINTEROP
174 #include "runtimecallablewrapper.h"
175 #include "mngstdinterfaces.h"
176 #include "interoplibinterface.h"
177 #endif // FEATURE_COMINTEROP
178
179 #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
180 #include "olecontexthelpers.h"
181 #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
182
183 #ifdef PROFILING_SUPPORTED
184 #include "proftoeeinterfaceimpl.h"
185 #include "profilinghelper.h"
186 #endif // PROFILING_SUPPORTED
187
188 #ifdef FEATURE_INTERPRETER
189 #include "interpreter.h"
190 #endif // FEATURE_INTERPRETER
191
192 #ifdef FEATURE_PERFMAP
193 #include "perfmap.h"
194 #endif
195
196 #include "diagnosticserveradapter.h"
197 #include "eventpipeadapter.h"
198
199 #ifndef TARGET_UNIX
200 // Included for referencing __security_cookie
201 #include "process.h"
202 #endif // !TARGET_UNIX
203
204 #ifdef FEATURE_GDBJIT
205 #include "gdbjit.h"
206 #endif // FEATURE_GDBJIT
207
208 #include "genanalysis.h"
209
210 static int GetThreadUICultureId(_Out_ LocaleIDValue* pLocale);  // TODO: This shouldn't use the LCID.  We should rely on name instead
211
212 static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames);
213
214 HRESULT EEStartup();
215
216
217 static void InitializeGarbageCollector();
218
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
224
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
231 #else
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
234 #endif
235
236 // Remember how the last startup of EE went.
237 HRESULT g_EEStartupStatus = S_OK;
238
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;
243
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;
246
247 // Event to synchronize EE shutdown.
248 static CLREvent * g_pEEShutDownEvent;
249
250 static DangerousNonHostedSpinLock g_EEStartupLock;
251
252 // ---------------------------------------------------------------------------
253 // %%Function: EnsureEEStarted()
254 //
255 // Description: Ensure the CLR is started.
256 // ---------------------------------------------------------------------------
257 HRESULT EnsureEEStarted()
258 {
259     CONTRACTL
260     {
261         NOTHROW;
262         GC_TRIGGERS;
263         MODE_PREEMPTIVE;
264         ENTRY_POINT;
265     }
266     CONTRACTL_END;
267
268     if (g_fEEShutDown)
269         return E_FAIL;
270
271     HRESULT hr = E_FAIL;
272
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.
278     //
279     // We do however want to make sure other threads block until the EE is started,
280     // which we will do further down.
281     if (!g_fEEStarted)
282     {
283         // Initialize our configuration.
284         CLRConfig::Initialize();
285
286         BOOL bStarted=FALSE;
287
288         {
289             DangerousNonHostedSpinLockHolder lockHolder(&g_EEStartupLock);
290
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))
296             {
297                 g_dwStartupThreadId = GetCurrentThreadId();
298
299                 EEStartup();
300                 bStarted=g_fEEStarted;
301                 hr = g_EEStartupStatus;
302
303                 g_dwStartupThreadId = 0;
304             }
305             else
306             {
307                 hr = g_EEStartupStatus;
308                 if (SUCCEEDED(g_EEStartupStatus))
309                 {
310                     hr = S_FALSE;
311                 }
312             }
313         }
314     }
315     else
316     {
317         //
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.
324         //
325         // We do not want to do this blocking if we are the thread currently performing EE startup.  So we check
326         // that first.
327         //
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.
332         //
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.
338         //
339         if (g_EEStartupLock.IsHeld() && g_dwStartupThreadId != GetCurrentThreadId())
340         {
341             DangerousNonHostedSpinLockHolder lockHolder(&g_EEStartupLock);
342         }
343
344         hr = g_EEStartupStatus;
345         if (SUCCEEDED(g_EEStartupStatus))
346         {
347             hr = S_FALSE;
348         }
349     }
350
351     return hr;
352 }
353
354
355
356 #ifndef TARGET_UNIX
357 // This is our Ctrl-C, Ctrl-Break, etc. handler.
358 static BOOL WINAPI DbgCtrlCHandler(DWORD dwCtrlType)
359 {
360     WRAPPER_NO_CONTRACT;
361
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))
370     {
371         return g_pDebugInterface->SendCtrlCToDebugger(dwCtrlType);
372     }
373     else
374 #endif // DEBUGGING_SUPPORTED
375     {
376         if (dwCtrlType == CTRL_CLOSE_EVENT || dwCtrlType == CTRL_SHUTDOWN_EVENT)
377         {
378             // Initiate shutdown so the ProcessExit handlers run
379             ForceEEShutdown(SCA_ReturnWhenShutdownComplete);
380         }
381
382         g_fInControlC = true;     // only for weakening assertions in checked build.
383         return FALSE;             // keep looking for a real handler.
384     }
385 }
386 #endif
387
388 // A host can specify that it only wants one version of hosting interface to be used.
389 BOOL g_singleVersionHosting;
390
391 #ifdef TARGET_WINDOWS
392 typedef BOOL(WINAPI* PINITIALIZECONTEXT2)(PVOID Buffer, DWORD ContextFlags, PCONTEXT* Context, PDWORD ContextLength, ULONG64 XStateCompactionMask);
393 PINITIALIZECONTEXT2 g_pfnInitializeContext2 = NULL;
394
395 #ifdef TARGET_X86
396 typedef VOID(__cdecl* PRTLRESTORECONTEXT)(PCONTEXT ContextRecord, struct _EXCEPTION_RECORD* ExceptionRecord);
397 PRTLRESTORECONTEXT g_pfnRtlRestoreContext = NULL;
398 #endif // TARGET_X86
399
400 void InitializeOptionalWindowsAPIPointers()
401 {
402     HMODULE hm = GetModuleHandleW(_T("kernel32.dll"));
403     g_pfnInitializeContext2 = (PINITIALIZECONTEXT2)GetProcAddress(hm, "InitializeContext2");
404
405 #ifdef TARGET_X86
406     hm = GetModuleHandleW(_T("ntdll.dll"));
407     g_pfnRtlRestoreContext = (PRTLRESTORECONTEXT)GetProcAddress(hm, "RtlRestoreContext");
408 #endif //TARGET_X86
409 }
410 #endif // TARGET_WINDOWS
411
412 void InitializeStartupFlags()
413 {
414     CONTRACTL {
415         NOTHROW;
416         GC_TRIGGERS;
417         MODE_ANY;
418     } CONTRACTL_END;
419
420     STARTUP_FLAGS flags = CorHost2::GetStartupFlags();
421
422
423     if (flags & STARTUP_CONCURRENT_GC)
424         g_IGCconcurrent = 1;
425     else
426         g_IGCconcurrent = 0;
427
428
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;
431 }
432
433 //-----------------------------------------------------------------------------
434
435 void InitGSCookie()
436 {
437     CONTRACTL
438     {
439         THROWS;
440         GC_NOTRIGGER;
441         MODE_ANY;
442     }
443     CONTRACTL_END;
444
445     volatile GSCookie * pGSCookiePtr = GetProcessGSCookiePtr();
446
447     // The GS cookie is stored in a read only data segment
448     DWORD oldProtection;
449     if(!ClrVirtualProtect((LPVOID)pGSCookiePtr, sizeof(GSCookie), PAGE_READWRITE, &oldProtection))
450     {
451         ThrowLastError();
452     }
453
454 #ifdef TARGET_UNIX
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
458
459 #ifndef 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));
463
464     // Forces VC cookie to be initialized.
465     void * pf = &__security_check_cookie;
466     pf = NULL;
467
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
473
474 #ifdef _DEBUG
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);
477 #endif
478
479     // To test if it is initialized. Also for ICorMethodInfo::getGSCookie()
480     if (val == 0)
481         val ++;
482     *pGSCookiePtr = val;
483
484     if(!ClrVirtualProtect((LPVOID)pGSCookiePtr, sizeof(GSCookie), oldProtection, &oldProtection))
485     {
486         ThrowLastError();
487     }
488 }
489
490 Volatile<BOOL> g_bIsGarbageCollectorFullyInitialized = FALSE;
491
492 void SetGarbageCollectorFullyInitialized()
493 {
494     LIMITED_METHOD_CONTRACT;
495
496     g_bIsGarbageCollectorFullyInitialized = TRUE;
497 }
498
499 // Tells whether the garbage collector is fully initialized
500 // Stronger than IsGCHeapInitialized
501 BOOL IsGarbageCollectorFullyInitialized()
502 {
503     LIMITED_METHOD_CONTRACT;
504
505     return g_bIsGarbageCollectorFullyInitialized;
506 }
507
508 // ---------------------------------------------------------------------------
509 // %%Function: EEStartupHelper
510 //
511 // Returns:
512 //  S_OK                    - On success
513 //
514 // Description:
515 //  Reserved to initialize the EE runtime engine explicitly.
516 // ---------------------------------------------------------------------------
517
518 #ifndef IfFailGotoLog
519 #define IfFailGotoLog(EXPR, LABEL) \
520 do { \
521     hr = (EXPR);\
522     if(FAILED(hr)) { \
523         STRESS_LOG2(LF_STARTUP, LL_ALWAYS, "%s failed with code %x", #EXPR, hr);\
524         goto LABEL; \
525     } \
526     else \
527        STRESS_LOG1(LF_STARTUP, LL_ALWAYS, "%s completed", #EXPR);\
528 } while (0)
529 #endif
530
531 #ifndef IfFailGoLog
532 #define IfFailGoLog(EXPR) IfFailGotoLog(EXPR, ErrExit)
533 #endif
534
535
536 #ifdef TARGET_UNIX
537 void EESocketCleanupHelper(bool isExecutingOnAltStack)
538 {
539     CONTRACTL
540     {
541         GC_NOTRIGGER;
542         MODE_ANY;
543     } CONTRACTL_END;
544
545     if (isExecutingOnAltStack)
546     {
547         GetThread()->SetExecutingOnAltStack();
548     }
549
550     // Close the debugger transport socket first
551     if (g_pDebugInterface != NULL)
552     {
553         g_pDebugInterface->CleanupTransportSocket();
554     }
555
556     // Close the diagnostic server socket.
557 #ifdef FEATURE_PERFTRACING
558     DiagnosticServerAdapter::Shutdown();
559 #endif // FEATURE_PERFTRACING
560 }
561 #endif // TARGET_UNIX
562
563 void FatalErrorHandler(UINT errorCode, LPCWSTR pszMessage)
564 {
565     EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(errorCode, pszMessage);
566 }
567
568 void EEStartupHelper()
569 {
570     CONTRACTL
571     {
572         THROWS;
573         GC_TRIGGERS;
574         MODE_ANY;
575     } CONTRACTL_END;
576
577 #ifdef ENABLE_CONTRACTS_IMPL
578     {
579         extern void ContractRegressionCheck();
580         ContractRegressionCheck();
581     }
582 #endif
583
584     HRESULT hr = S_OK;
585     static ConfigDWORD breakOnEELoad;
586     EX_TRY
587     {
588         g_fEEInit = true;
589
590
591         // We cache the SystemInfo for anyone to use throughout the life of the EE.
592         GetSystemInfo(&g_SystemInfo);
593
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);
599
600 #ifndef TARGET_UNIX
601         ::SetConsoleCtrlHandler(DbgCtrlCHandler, TRUE/*add*/);
602 #endif
603
604 #ifdef HOST_WINDOWS
605         InitializeOptionalWindowsAPIPointers();
606 #endif // HOST_WINDOWS
607
608         // SString initialization
609         // This needs to be done before config because config uses SString::Empty()
610         SString::Startup();
611
612         IfFailGo(EEConfig::Setup());
613
614
615 #ifdef HOST_WINDOWS
616         InitializeCrashDump();
617
618 #endif // HOST_WINDOWS
619 #ifndef TARGET_UNIX
620         CPUGroupInfo::EnsureInitialized();
621 #endif // !TARGET_UNIX
622
623         // Initialize global configuration settings based on startup flags
624         // This needs to be done before the EE has started
625         InitializeStartupFlags();
626
627         IfFailGo(ExecutableAllocator::StaticInitialize(FatalErrorHandler));
628
629         Thread::StaticInitialize();
630
631         JITInlineTrackingMap::StaticInitialize();
632         MethodDescBackpatchInfoTracker::StaticInitialize();
633         CodeVersionManager::StaticInitialize();
634         TieredCompilationManager::StaticInitialize();
635         CallCountingManager::StaticInitialize();
636         OnStackReplacementManager::StaticInitialize();
637
638 #ifdef TARGET_UNIX
639         ExecutableAllocator::InitPreferredRange();
640 #else
641         {
642             // Record coreclr.dll geometry
643             PEDecoder pe(GetClrModuleBase());
644
645             g_runtimeLoadedBaseAddress = (SIZE_T)pe.GetBase();
646             g_runtimeVirtualSize = (SIZE_T)pe.GetVirtualSize();
647             ExecutableAllocator::InitLazyPreferredRange(g_runtimeLoadedBaseAddress, g_runtimeVirtualSize, GetRandomInt(64));
648         }
649 #endif // !TARGET_UNIX
650
651         InitThreadManager();
652         STRESS_LOG0(LF_STARTUP, LL_ALWAYS, "Returned successfully from InitThreadManager");
653
654 #ifdef FEATURE_PERFTRACING
655         // Initialize the event pipe.
656         EventPipeAdapter::Initialize();
657 #endif // FEATURE_PERFTRACING
658
659 #ifdef TARGET_UNIX
660         PAL_SetShutdownCallback(EESocketCleanupHelper);
661 #endif // TARGET_UNIX
662
663 #ifdef STRESS_LOG
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;
672         }
673 #endif
674
675 #ifdef FEATURE_PERFTRACING
676         DiagnosticServerAdapter::Initialize();
677         DiagnosticServerAdapter::PauseForDiagnosticsMonitor();
678 #endif // FEATURE_PERFTRACING
679
680 #ifdef FEATURE_GDBJIT
681         // Initialize gdbjit
682         NotifyGdb::Initialize();
683 #endif // FEATURE_GDBJIT
684
685 #ifdef FEATURE_EVENT_TRACE
686         // Initialize event tracing early so we can trace CLR startup time events.
687         InitializeEventTracing();
688
689         // Fire the EE startup ETW event
690         ETWFireEvent(EEStartupStart_V1);
691 #endif // FEATURE_EVENT_TRACE
692
693         InitGSCookie();
694
695         Frame::Init();
696
697
698
699
700 #ifdef LOGGING
701         InitializeLogging();
702 #endif
703
704 #ifdef FEATURE_PERFMAP
705         PerfMap::Initialize();
706 #endif
707
708 #ifdef FEATURE_PGO
709         PgoManager::Initialize();
710 #endif
711
712         STRESS_LOG0(LF_STARTUP, LL_ALWAYS, "===================EEStartup Starting===================");
713
714 #ifndef TARGET_UNIX
715         IfFailGoLog(EnsureRtlFunctions());
716 #endif // !TARGET_UNIX
717         InitEventStore();
718
719         if (g_pConfig != NULL)
720         {
721             IfFailGoLog(g_pConfig->sync());
722         }
723
724         // Fire the runtime information ETW event
725         ETW::InfoLog::RuntimeInformation(ETW::InfoLog::InfoStructs::Normal);
726
727         if (breakOnEELoad.val(CLRConfig::UNSUPPORTED_BreakOnEELoad) == 1)
728         {
729 #ifdef _DEBUG
730             _ASSERTE(!"Start loading EE!");
731 #else
732             DebugBreak();
733 #endif
734         }
735
736 #ifdef ENABLE_STARTUP_DELAY
737         PREFIX_ASSUME(NULL != g_pConfig);
738         if (g_pConfig->StartupDelayMS())
739         {
740             ClrSleepEx(g_pConfig->StartupDelayMS(), FALSE);
741         }
742 #endif
743
744 #if USE_DISASSEMBLER
745         if ((g_pConfig->GetGCStressLevel() & (EEConfig::GCSTRESS_INSTR_JIT | EEConfig::GCSTRESS_INSTR_NGEN)) != 0)
746         {
747             Disassembler::StaticInitialize();
748             if (!Disassembler::IsAvailable())
749             {
750                 fprintf(stderr, "External disassembler is not available.\n");
751                 IfFailGo(E_FAIL);
752             }
753         }
754 #endif // USE_DISASSEMBLER
755
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();
759
760 #ifdef FEATURE_INTERPRETER
761         Interpreter::Initialize();
762 #endif // FEATURE_INTERPRETER
763
764         StubManager::InitializeStubManagers();
765
766         // Set up the cor handle map. This map is used to load assemblies in
767         // memory instead of using the normal system load
768         PEImage::Startup();
769
770         AccessCheckOptions::Startup();
771
772         CoreLibBinder::Startup();
773
774         Stub::Init();
775         StubLinkerCPU::Init();
776         StubPrecode::StaticInitialize();
777         FixupPrecode::StaticInitialize();
778
779         InitializeGarbageCollector();
780
781         if (!GCHandleUtilities::GetGCHandleManager()->Initialize())
782         {
783             IfFailGo(E_OUTOFMEMORY);
784         }
785
786         g_pEEShutDownEvent = new CLREvent();
787         g_pEEShutDownEvent->CreateManualEvent(FALSE);
788
789         VirtualCallStubManager::InitStatic();
790
791
792         // Setup the domains. Threads are started in a default domain.
793
794         // Static initialization
795         BaseDomain::Attach();
796         SystemDomain::Attach();
797
798         // Start up the EE initializing all the global variables
799         ECall::Init();
800
801         COMDelegate::Init();
802
803         ExecutionManager::Init();
804
805         JitHost::Init();
806
807
808 #ifndef TARGET_UNIX
809         if (!RegisterOutOfProcessWatsonCallbacks())
810         {
811             IfFailGo(E_FAIL);
812         }
813 #endif // !TARGET_UNIX
814
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
821
822 #ifdef PROFILING_SUPPORTED
823         // Initialize the profiling services.
824         hr = ProfilingAPIUtility::InitializeProfiling();
825
826         _ASSERTE(SUCCEEDED(hr));
827         IfFailGo(hr);
828 #endif // PROFILING_SUPPORTED
829
830         InitializeExceptionHandling();
831
832         //
833         // Install our global exception filter
834         //
835         if (!InstallUnhandledExceptionFilter())
836         {
837             IfFailGo(E_FAIL);
838         }
839
840         // throws on error
841         SetupThread();
842
843 #ifdef DEBUGGING_SUPPORTED
844         // Notify debugger once the first thread is created to finish initialization.
845         if (g_pDebugInterface != NULL)
846         {
847             g_pDebugInterface->StartupPhase2(GetThread());
848         }
849 #endif
850
851         InitPreStubManager();
852
853 #ifdef FEATURE_COMINTEROP
854         InitializeComInterop();
855 #endif // FEATURE_COMINTEROP
856
857         StubHelpers::Init();
858
859         // Before setting up the execution manager initialize the first part
860         // of the JIT helpers.
861         InitJITHelpers1();
862         InitJITHelpers2();
863
864         SyncBlockCache::Attach();
865
866         // Set up the sync block
867         SyncBlockCache::Start();
868
869         StackwalkCache::Init();
870
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();
875         if (FAILED(hr))
876         {
877             LogErrorToHost("GC heap initialization failed with error 0x%08X", hr);
878         }
879
880         IfFailGo(hr);
881
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();
889
890         // This isn't done as part of InitializeGarbageCollector() above because thread
891         // creation requires AppDomains to have been set up.
892         FinalizerThread::FinalizerThreadCreate();
893
894         // Now we really have fully initialized the garbage collector
895         SetGarbageCollectorFullyInitialized();
896
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());
905 #endif
906
907 #ifdef HAVE_GCCOVER
908         MethodDesc::Init();
909 #endif
910
911
912         Assembly::Initialize();
913
914         SystemDomain::System()->Init();
915
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>
921
922         SystemDomain::NotifyProfilerStartup();
923 #endif // PROFILING_SUPPORTED
924
925         g_fEEInit = false;
926
927         SystemDomain::System()->DefaultDomain()->LoadSystemAssemblies();
928
929         SystemDomain::System()->DefaultDomain()->SetupSharedStatics();
930
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
943
944         g_fEEStarted = TRUE;
945         g_EEStartupStatus = S_OK;
946         hr = S_OK;
947         STRESS_LOG0(LF_STARTUP, LL_ALWAYS, "===================EEStartup Completed===================");
948
949
950 #ifdef _DEBUG
951
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.
956         //
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())
961         {
962             SystemDomain::SystemModule()->ExpandAll();
963         }
964 #endif // _DEBUG
965
966
967 ErrExit: ;
968     }
969     EX_CATCH
970     {
971         hr = GET_EXCEPTION()->GetHR();
972     }
973     EX_END_CATCH(RethrowTerminalExceptionsWithInitCheck)
974
975     if (!g_fEEStarted) {
976         if (g_fEEInit)
977             g_fEEInit = false;
978
979         if (!FAILED(hr))
980             hr = E_FAIL;
981
982         g_EEStartupStatus = hr;
983     }
984
985     if (breakOnEELoad.val(CLRConfig::UNSUPPORTED_BreakOnEELoad) == 2)
986     {
987 #ifdef _DEBUG
988         _ASSERTE(!"Done loading EE!");
989 #else
990         DebugBreak();
991 #endif
992     }
993
994 }
995
996 LONG FilterStartupException(PEXCEPTION_POINTERS p, PVOID pv)
997 {
998     CONTRACTL
999     {
1000         NOTHROW;
1001         GC_NOTRIGGER;
1002         MODE_ANY;
1003         PRECONDITION(CheckPointer(p));
1004         PRECONDITION(CheckPointer(pv));
1005     } CONTRACTL_END;
1006
1007     g_EEStartupStatus = (HRESULT)p->ExceptionRecord->ExceptionInformation[0];
1008
1009     // Make sure we got a failure code in this case
1010     if (!FAILED(g_EEStartupStatus))
1011         g_EEStartupStatus = E_FAIL;
1012
1013     // Initializations has failed so reset the g_fEEInit flag.
1014     g_fEEInit = false;
1015
1016     if (p->ExceptionRecord->ExceptionCode == BOOTUP_EXCEPTION_COMPLUS)
1017     {
1018         // Don't ever handle the exception in a checked build
1019 #ifndef _DEBUG
1020         return EXCEPTION_EXECUTE_HANDLER;
1021 #endif
1022     }
1023
1024     return EXCEPTION_CONTINUE_SEARCH;
1025 }
1026
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 ...)
1031 //
1032 // see code:EEStartup#TableOfContents for more on the runtime in general.
1033 // see code:#EEShutdown for an analogous routine run during shutdown.
1034 //
1035 HRESULT EEStartup()
1036 {
1037     // Cannot use normal contracts here because of the PAL_TRY.
1038     STATIC_CONTRACT_NOTHROW;
1039
1040     _ASSERTE(!g_fEEStarted && !g_fEEInit && SUCCEEDED (g_EEStartupStatus));
1041
1042     PAL_TRY(PVOID, p, NULL)
1043     {
1044         InitializeClrNotifications();
1045 #ifdef TARGET_UNIX
1046         InitializeJITNotificationTable();
1047         DacGlobals::Initialize();
1048 #endif
1049
1050         EEStartupHelper();
1051     }
1052     PAL_EXCEPT_FILTER (FilterStartupException)
1053     {
1054         // The filter should have set g_EEStartupStatus to a failure HRESULT.
1055         _ASSERTE(FAILED(g_EEStartupStatus));
1056     }
1057     PAL_ENDTRY
1058
1059     return g_EEStartupStatus;
1060 }
1061
1062
1063
1064 // ---------------------------------------------------------------------------
1065 // %%Function: ForceEEShutdown()
1066 //
1067 // Description: Force the EE to shutdown now.
1068 //
1069 // Note: returns when sca is SCA_ReturnWhenShutdownComplete.
1070 // ---------------------------------------------------------------------------
1071 void ForceEEShutdown(ShutdownCompleteAction sca)
1072 {
1073     WRAPPER_NO_CONTRACT;
1074
1075     // Don't bother to take the lock for this case.
1076
1077     STRESS_LOG0(LF_STARTUP, INFO3, "EEShutdown invoked from ForceEEShutdown");
1078     EEPolicy::HandleExitProcess(sca);
1079 }
1080
1081 void WaitForEndOfShutdown()
1082 {
1083     CONTRACTL{
1084         NOTHROW;
1085         GC_NOTRIGGER;
1086         MODE_PREEMPTIVE;
1087     } CONTRACTL_END;
1088
1089     // We are shutting down.  GC triggers does not have any effect now.
1090     CONTRACT_VIOLATION(GCViolation);
1091
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.
1095     if (pThread)
1096     {
1097         _ASSERTE(!pThread->HasThreadStateNC(Thread::TSNC_BlockedForShutdown));
1098         pThread->SetThreadStateNC(Thread::TSNC_BlockedForShutdown);
1099     }
1100
1101     for (;;) g_pEEShutDownEvent->Wait(INFINITE, TRUE);
1102 }
1103
1104 // ---------------------------------------------------------------------------
1105 // Function: EEShutDownHelper(BOOL fIsDllUnloading)
1106 //
1107 // The real meat of shut down happens here.  See code:#EEShutDown for details, including
1108 // what fIsDllUnloading means.
1109 //
1110 void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
1111 {
1112     CONTRACTL
1113     {
1114         NOTHROW;
1115         GC_TRIGGERS;
1116         MODE_ANY;
1117     } CONTRACTL_END;
1118
1119     // Used later for a callback.
1120     CEEInfo ceeInf;
1121
1122 #ifdef FEATURE_PGO
1123     EX_TRY
1124     {
1125         PgoManager::Shutdown();
1126     }
1127     EX_CATCH
1128     {
1129     }
1130     EX_END_CATCH(SwallowAllExceptions);
1131 #endif
1132
1133     if (!fIsDllUnloading)
1134     {
1135         ETW::EnumerationLog::ProcessShutdown();
1136
1137 #ifdef FEATURE_PERFTRACING
1138         EventPipeAdapter::Shutdown();
1139         DiagnosticServerAdapter::Shutdown();
1140 #endif // FEATURE_PERFTRACING
1141     }
1142
1143 #if defined(FEATURE_COMINTEROP)
1144     // Get the current thread.
1145     Thread * pThisThread = GetThreadNULLOk();
1146 #endif
1147
1148     // If the process is detaching then set the global state.
1149     // This is used to get around FreeLibrary problems.
1150     if(fIsDllUnloading)
1151         g_fProcessDetach = true;
1152
1153     if (IsDbgHelperSpecialThread())
1154     {
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);
1158         return;
1159     }
1160
1161     STRESS_LOG1(LF_STARTUP, LL_INFO10, "EEShutDown entered unloading = %d", fIsDllUnloading);
1162
1163 #ifdef _DEBUG
1164     if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_BreakOnEEShutdown))
1165         _ASSERTE(!"Shutting down EE!");
1166 #endif
1167
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
1179
1180     EX_TRY
1181     {
1182         ClrFlsSetThreadType(ThreadType_Shutdown);
1183
1184         if (fIsDllUnloading && g_fEEShutDown)
1185         {
1186             // I'm in the final shutdown and the first part has already been run.
1187             goto part2;
1188         }
1189
1190         // Indicate the EE is the shut down phase.
1191         g_fEEShutDown |= ShutDown_Start;
1192
1193         if (!g_fProcessDetach && !g_fFastExitProcess)
1194         {
1195             g_fEEShutDown |= ShutDown_Finalize1;
1196
1197             // Wait for the finalizer thread to deliver process exit event
1198             GCX_PREEMP();
1199             FinalizerThread::RaiseShutdownEvents();
1200         }
1201
1202         // Ok.  Let's stop the EE.
1203         if (!g_fProcessDetach)
1204         {
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().
1208             //
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.
1213             //
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).
1216
1217             // Notify the debugger that we're going into shutdown to convert debugger-lock to shutdown.
1218             if (g_pDebugInterface != NULL)
1219             {
1220                 g_pDebugInterface->LockDebuggerForShutdown();
1221             }
1222
1223             // This call will convert the ThreadStoreLock into "shutdown" mode, just like the debugger lock above.
1224             g_fEEShutDown |= ShutDown_Finalize2;
1225         }
1226
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
1234
1235 #ifdef FEATURE_PERFMAP
1236         // Flush and close the perf map file.
1237         PerfMap::Disable();
1238 #endif
1239
1240         ceeInf.JitProcessShutdownWork();  // Do anything JIT-related that needs to happen at shutdown.
1241
1242 #ifdef FEATURE_INTERPRETER
1243         // This will check a flag and do nothing if not enabled.
1244         Interpreter::PrintPostMortemData();
1245 #endif // FEATURE_INTERPRETER
1246         VirtualCallStubManager::LogFinalStats();
1247         WriteJitHelperCountToSTRESSLOG();
1248
1249 #ifdef PROFILING_SUPPORTED
1250         // If profiling is enabled, then notify of shutdown first so that the
1251         // profiler can make any last calls it needs to.  Do this only if we
1252         // are not detaching
1253
1254         // NOTE: We haven't stopped other threads at this point and nothing is stopping
1255         // callbacks from coming into the profiler even after Shutdown() has been called.
1256         // See https://github.com/dotnet/runtime/issues/11885 for an example of how that
1257         // happens.
1258         //
1259         // To prevent issues when profilers are attached we intentionally skip freeing the
1260         // profiler here. Since there is no guarantee that the profiler won't be accessed after
1261         // we free it (e.g. through callbacks or ELT hooks), we can't safely free the profiler.
1262         if (CORProfilerPresent())
1263         {
1264             // Don't call back in to the profiler if we are being torn down, it might be unloaded
1265             if (!fIsDllUnloading)
1266             {
1267                 BEGIN_PROFILER_CALLBACK(CORProfilerPresent());
1268                 GCX_PREEMP();
1269                 (&g_profControlBlock)->Shutdown();
1270                 END_PROFILER_CALLBACK();
1271             }
1272
1273             g_fEEShutDown |= ShutDown_Profiler;
1274         }
1275 #endif // PROFILING_SUPPORTED
1276
1277
1278 #ifdef _DEBUG
1279         g_fEEShutDown |= ShutDown_SyncBlock;
1280 #endif
1281         {
1282             // From here on out we might call stuff that violates mode requirements, but we ignore these
1283             // because we are shutting down.
1284             CONTRACT_VIOLATION(ModeViolation);
1285
1286 #ifdef FEATURE_COMINTEROP
1287             // We need to call CoUninitialize in part one to ensure orderly shutdown of COM dlls.
1288             if (!g_fFastExitProcess)
1289             {
1290                 if (pThisThread!= NULL)
1291                 {
1292                     pThisThread->CoUninitialize();
1293                 }
1294             }
1295 #endif // FEATURE_COMINTEROP
1296         }
1297
1298         // This is the end of Part 1.
1299
1300 part2:
1301         // If process shutdown is in progress and Crst locks to be used in shutdown phase 2
1302         // are already in use, then skip phase 2. This will happen only when those locks
1303         // are orphaned. In Vista, the penalty for attempting to enter such locks is
1304         // instant process termination.
1305         if (g_fProcessDetach)
1306         {
1307             // The assert below is a bit too aggressive and has generally brought cases that have been race conditions
1308             // and not easily reproed to validate a bug. A typical race scenario is when there are two threads,
1309             // T1 and T2, with T2 having taken a lock (e.g. SystemDomain lock), the OS terminates
1310             // T2 for some reason. Later, when we enter the shutdown thread, we would assert on such
1311             // a lock leak, but there is not much we can do since the OS wont notify us prior to thread
1312             // termination. And this is not even a user bug.
1313             //
1314             // Converting it to a STRESS LOG to reduce noise, yet keep things in radar if they need
1315             // to be investigated.
1316             //_ASSERTE_MSG(g_ShutdownCrstUsageCount == 0, "Some locks to be taken during shutdown may already be orphaned!");
1317             if (g_ShutdownCrstUsageCount > 0)
1318             {
1319                 STRESS_LOG0(LF_STARTUP, LL_INFO10, "Some locks to be taken during shutdown may already be orphaned!");
1320                 goto lDone;
1321             }
1322         }
1323
1324         {
1325             CONTRACT_VIOLATION(ModeViolation);
1326
1327             // On the new plan, we only do the tear-down under the protection of the loader
1328             // lock -- after the OS has stopped all other threads.
1329             if (fIsDllUnloading && (g_fEEShutDown & ShutDown_Phase2) == 0)
1330             {
1331                 g_fEEShutDown |= ShutDown_Phase2;
1332
1333                 // Shutdown finalizer before we suspend all background threads. Otherwise we
1334                 // never get to finalize anything.
1335
1336                 // No longer process exceptions
1337                 g_fNoExceptions = true;
1338
1339                 // <TODO>@TODO: This does things which shouldn't occur in part 2.  Namely,
1340                 // calling managed dll main callbacks (AppDomain::SignalProcessDetach), and
1341                 // RemoveAppDomainFromIPC.
1342                 //
1343                 // (If we move those things to earlier, this can be called only if fShouldWeCleanup.)</TODO>
1344                 if (!g_fFastExitProcess)
1345                 {
1346                     SystemDomain::DetachBegin();
1347                 }
1348
1349
1350 #ifdef DEBUGGING_SUPPORTED
1351                 // Terminate the debugging services.
1352                 TerminateDebugger();
1353 #endif // DEBUGGING_SUPPORTED
1354
1355                 StubManager::TerminateStubManagers();
1356
1357 #ifdef FEATURE_INTERPRETER
1358                 Interpreter::Terminate();
1359 #endif // FEATURE_INTERPRETER
1360
1361                 // Unregister our vectored exception and continue handlers from the OS.
1362                 // This will ensure that if any other DLL unload (after ours) has an exception,
1363                 // we wont attempt to process that exception (which could lead to various
1364                 // issues including AV in the runtime).
1365                 //
1366                 // This should be done:
1367                 //
1368                 // 1) As the last action during the shutdown so that any unexpected AVs
1369                 //    in the runtime during shutdown do result in FailFast in VEH.
1370                 //
1371                 // 2) Only when the runtime is processing DLL_PROCESS_DETACH.
1372                 CLRRemoveVectoredHandlers();
1373
1374 #if USE_DISASSEMBLER
1375                 Disassembler::StaticClose();
1376 #endif // USE_DISASSEMBLER
1377
1378                 STRESS_LOG0(LF_STARTUP, LL_INFO10, "EEShutdown shutting down logging");
1379
1380 #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
1381                 if (!g_fFastExitProcess)
1382                     StressLog::Terminate(TRUE);
1383 #endif
1384
1385 #ifdef LOGGING
1386                 ShutdownLogging();
1387 #endif
1388                 GCHeapUtilities::GetGCHeap()->Shutdown();
1389             }
1390         }
1391
1392     lDone: ;
1393     }
1394     EX_CATCH
1395     {
1396     }
1397     EX_END_CATCH(SwallowAllExceptions);
1398
1399     ClrFlsClearThreadType(ThreadType_Shutdown);
1400     if (!g_fProcessDetach)
1401     {
1402         g_pEEShutDownEvent->Set();
1403     }
1404 }
1405
1406
1407 #ifdef FEATURE_COMINTEROP
1408
1409 BOOL IsThreadInSTA()
1410 {
1411     CONTRACTL
1412     {
1413         NOTHROW;
1414         GC_TRIGGERS;
1415         MODE_ANY;
1416     }
1417     CONTRACTL_END;
1418
1419     // If ole32.dll is not loaded
1420     if (WszGetModuleHandle(W("ole32.dll")) == NULL)
1421     {
1422         return FALSE;
1423     }
1424
1425     BOOL fInSTA = TRUE;
1426     // To be conservative, check if finalizer thread is around
1427     EX_TRY
1428     {
1429         Thread *pFinalizerThread = FinalizerThread::GetFinalizerThread();
1430         if (!pFinalizerThread || pFinalizerThread->Join(0, FALSE) != WAIT_TIMEOUT)
1431         {
1432             fInSTA = FALSE;
1433         }
1434     }
1435     EX_CATCH
1436     {
1437     }
1438     EX_END_CATCH(SwallowAllExceptions);
1439
1440     if (!fInSTA)
1441     {
1442         return FALSE;
1443     }
1444
1445     THDTYPE type;
1446     HRESULT hr = S_OK;
1447
1448     hr = GetCurrentThreadTypeNT5(&type);
1449     if (hr == S_OK)
1450     {
1451         fInSTA = (type == THDTYPE_PROCESSMESSAGES) ? TRUE : FALSE;
1452
1453         // If we get back THDTYPE_PROCESSMESSAGES, we are guaranteed to
1454         // be an STA thread. If not, we are an MTA thread, however
1455         // we can't know if the thread has been explicitly set to MTA
1456         // (via a call to CoInitializeEx) or if it has been implicitly
1457         // made MTA (if it hasn't been CoInitializeEx'd but CoInitialize
1458         // has already been called on some other thread in the process.
1459     }
1460     else
1461     {
1462         // CoInitialize hasn't been called in the process yet so assume the current thread
1463         // is MTA.
1464         fInSTA = FALSE;
1465     }
1466
1467     return fInSTA;
1468 }
1469 #endif
1470
1471 // #EEShutDown
1472 //
1473 // Function: EEShutDown(BOOL fIsDllUnloading)
1474 //
1475 // Parameters:
1476 //    BOOL fIsDllUnloading:
1477 //         * TRUE => Called from CLR's DllMain (DLL_PROCESS_DETACH). Not safe point for
1478 //             full cleanup
1479 //         * FALSE => Called some other way (e.g., end of the CLR's main). Safe to do
1480 //             full cleanup.
1481 //
1482 // Description:
1483 //
1484 //     All ee shutdown stuff should be done here. EEShutDown is generally called in one
1485 //     of two ways:
1486 //     * 1. From code:EEPolicy::HandleExitProcess (via HandleExitProcessHelper), with
1487 //         fIsDllUnloading == FALSE. This code path is typically invoked by the CLR's
1488 //         main just falling through to the end. Full cleanup can be performed when
1489 //         EEShutDown is called this way.
1490 //     * 2. From CLR's DllMain (DLL_PROCESS_DETACH), with fIsDllUnloading == TRUE. When
1491 //         called this way, much cleanup code is unsafe to run, and is thus skipped.
1492 //
1493 // Actual shut down logic is factored out to EEShutDownHelper which may be called
1494 // directly by EEShutDown, or indirectly on another thread (see code:#STAShutDown).
1495 //
1496 // In order that callees may also know the value of fIsDllUnloading, EEShutDownHelper
1497 // sets g_fProcessDetach = fIsDllUnloading, and g_fProcessDetach may then be retrieved
1498 // via code:IsAtProcessExit.
1499 //
1500 // NOTE 1: Actually, g_fProcessDetach is set to TRUE if fIsDllUnloading is TRUE. But
1501 // g_fProcessDetach doesn't appear to be explicitly set to FALSE. (Apparently
1502 // g_fProcessDetach is implicitly initialized to FALSE as clr.dll is loaded.)
1503 //
1504 // NOTE 2: EEDllMain(DLL_PROCESS_DETACH) already sets g_fProcessDetach to TRUE, so it
1505 // appears EEShutDownHelper doesn't have to.
1506 //
1507 void STDMETHODCALLTYPE EEShutDown(BOOL fIsDllUnloading)
1508 {
1509     CONTRACTL {
1510         NOTHROW;
1511         GC_TRIGGERS;
1512         MODE_ANY;
1513         PRECONDITION(g_fEEStarted);
1514     } CONTRACTL_END;
1515
1516     // If we have not started runtime successfully, it is not safe to call EEShutDown.
1517     if (!g_fEEStarted || g_fFastExitProcess == 2)
1518     {
1519         return;
1520     }
1521
1522     // We only do the first part of the shutdown once.
1523     static LONG OnlyOne = -1;
1524
1525     if (!fIsDllUnloading)
1526     {
1527         if (InterlockedIncrement(&OnlyOne) != 0)
1528         {
1529             // I'm in a regular shutdown -- but another thread got here first.
1530             // It's a race if I return from here -- I'll call ExitProcess next, and
1531             // rip things down while the first thread is half-way through a
1532             // nice cleanup.  Rather than do that, I should just wait until the
1533             // first thread calls ExitProcess().  I'll die a nice death when that
1534             // happens.
1535             GCX_PREEMP_NO_DTOR();
1536             WaitForEndOfShutdown();
1537             return;
1538         }
1539
1540 #ifdef FEATURE_MULTICOREJIT
1541         MulticoreJitManager::StopProfileAll();
1542 #endif
1543     }
1544
1545     if (GetThreadNULLOk())
1546     {
1547         GCX_COOP();
1548         EEShutDownHelper(fIsDllUnloading);
1549     }
1550     else
1551     {
1552         EEShutDownHelper(fIsDllUnloading);
1553     }
1554 }
1555
1556 // ---------------------------------------------------------------------------
1557 // %%Function: IsRuntimeActive()
1558 //
1559 // Parameters:
1560 //  none
1561 //
1562 // Returns:
1563 //  TRUE or FALSE
1564 //
1565 // Description: Indicates if the runtime is active or not. "Active" implies
1566 //              that the runtime has started and is in a position to run
1567 //              managed code.
1568 // ---------------------------------------------------------------------------
1569 BOOL IsRuntimeActive()
1570 {
1571     return (g_fEEStarted);
1572 }
1573
1574 //*****************************************************************************
1575 BOOL ExecuteDLL_ReturnOrThrow(HRESULT hr, BOOL fFromThunk)
1576 {
1577     CONTRACTL {
1578         if (fFromThunk) THROWS; else NOTHROW;
1579         WRAPPER(GC_TRIGGERS);
1580         MODE_ANY;
1581     } CONTRACTL_END;
1582
1583     // If we have a failure result, and we're called from a thunk,
1584     // then we need to throw an exception to communicate the error.
1585     if (FAILED(hr) && fFromThunk)
1586     {
1587         COMPlusThrowHR(hr);
1588     }
1589     return SUCCEEDED(hr);
1590 }
1591
1592 //
1593 // Initialize the Garbage Collector
1594 //
1595
1596 void InitializeGarbageCollector()
1597 {
1598     CONTRACTL{
1599         THROWS;
1600         GC_TRIGGERS;
1601         MODE_ANY;
1602     } CONTRACTL_END;
1603
1604     HRESULT hr;
1605
1606     // Build the special Free Object used by the Generational GC
1607     _ASSERT(g_pFreeObjectMethodTable == NULL);
1608     g_pFreeObjectMethodTable = (MethodTable *) new BYTE[sizeof(MethodTable)];
1609     ZeroMemory(g_pFreeObjectMethodTable, sizeof(MethodTable));
1610
1611     // As the flags in the method table indicate there are no pointers
1612     // in the object, there is no gc descriptor, and thus no need to adjust
1613     // the pointer to skip the gc descriptor.
1614
1615     g_pFreeObjectMethodTable->SetBaseSize(ARRAYBASE_BASESIZE);
1616     g_pFreeObjectMethodTable->SetComponentSize(1);
1617
1618     hr = GCHeapUtilities::LoadAndInitialize();
1619
1620     if (hr != S_OK)
1621     {
1622         LogErrorToHost("GC initialization failed with error 0x%08X", hr);
1623         ThrowHR(hr);
1624     }
1625
1626     // Apparently the Windows linker removes global variables if they are never
1627     // read from, which is a problem for g_gcDacGlobals since it's expected that
1628     // only the DAC will read from it. This forces the linker to include
1629     // g_gcDacGlobals.
1630     volatile void* _dummy = g_gcDacGlobals;
1631 }
1632
1633 /*****************************************************************************/
1634 /* This is here only so that if we get an exception we stop before we catch it */
1635 LONG DllMainFilter(PEXCEPTION_POINTERS p, PVOID pv)
1636 {
1637     LIMITED_METHOD_CONTRACT;
1638     _ASSERTE(!"Exception happened in mscorwks!DllMain!");
1639     return EXCEPTION_EXECUTE_HANDLER;
1640 }
1641
1642 #if !defined(CORECLR_EMBEDDED)
1643
1644 //*****************************************************************************
1645 // This is the part of the old-style DllMain that initializes the
1646 // stuff that the EE team works on. It's called from the real DllMain
1647 // up in MSCOREE land. Separating the DllMain tasks is simply for
1648 // convenience due to the dual build trees.
1649 //*****************************************************************************
1650 BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
1651     HINSTANCE   hInst,             // Instance handle of the loaded module.
1652     DWORD       dwReason,          // Reason for loading.
1653     LPVOID      lpReserved)        // Unused.
1654 {
1655     STATIC_CONTRACT_NOTHROW;
1656     STATIC_CONTRACT_GC_TRIGGERS;
1657
1658     // HRESULT hr;
1659     // BEGIN_EXTERNAL_ENTRYPOINT(&hr);
1660     // EE isn't spun up enough to use this macro
1661
1662     struct Param
1663     {
1664         HINSTANCE hInst;
1665         DWORD dwReason;
1666         LPVOID lpReserved;
1667     } param;
1668     param.hInst = hInst;
1669     param.dwReason = dwReason;
1670     param.lpReserved = lpReserved;
1671
1672     // Can't use PAL_TRY/EX_TRY here as they access the ClrDebugState which gets blown away as part of the
1673     // PROCESS_DETACH path. Must use special PAL_TRY_FOR_DLLMAIN, passing the reason were in the DllMain.
1674     PAL_TRY_FOR_DLLMAIN(Param *, pParam, &param, pParam->dwReason)
1675     {
1676
1677     switch (pParam->dwReason)
1678         {
1679             case DLL_PROCESS_DETACH:
1680             {
1681                 // lpReserved is NULL if we're here because someone called FreeLibrary
1682                 // and non-null if we're here because the process is exiting.
1683                 // Since nobody should ever be calling FreeLibrary on mscorwks.dll, lpReserved
1684                 // should always be non NULL.
1685                 _ASSERTE(pParam->lpReserved || !g_fEEStarted);
1686                 g_fProcessDetach = TRUE;
1687
1688                 if (g_fEEStarted)
1689                 {
1690                     if (GCHeapUtilities::IsGCInProgress())
1691                     {
1692                         g_fEEShutDown |= ShutDown_Phase2;
1693                         break;
1694                     }
1695
1696                     LOG((LF_STARTUP, INFO3, "EEShutDown invoked from EEDllMain"));
1697                     EEShutDown(TRUE); // shut down EE if it was started up
1698                 }
1699                 else
1700                 {
1701                     CLRRemoveVectoredHandlers();
1702                 }
1703                 break;
1704             }
1705         }
1706
1707     }
1708     PAL_EXCEPT_FILTER(DllMainFilter)
1709     {
1710     }
1711     PAL_ENDTRY;
1712
1713     return TRUE;
1714 }
1715
1716 #endif // !defined(CORECLR_EMBEDDED)
1717
1718 struct TlsDestructionMonitor
1719 {
1720     bool m_activated = false;
1721
1722     void Activate()
1723     {
1724         m_activated = true;
1725     }
1726
1727     ~TlsDestructionMonitor()
1728     {
1729         if (m_activated)
1730         {
1731             Thread* thread = GetThreadNULLOk();
1732             if (thread)
1733             {
1734 #ifdef FEATURE_COMINTEROP
1735                 // reset the CoInitialize state
1736                 // so we don't call CoUninitialize during thread detach
1737                 thread->ResetCoInitialized();
1738 #endif // FEATURE_COMINTEROP
1739                 // For case where thread calls ExitThread directly, we need to reset the
1740                 // frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
1741                 // We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
1742                 if (thread->m_pFrame != FRAME_TOP)
1743                 {
1744 #ifdef _DEBUG
1745                     thread->m_GCOnTransitionsOK = FALSE;
1746 #endif
1747                     GCX_COOP_NO_DTOR();
1748                     thread->m_pFrame = FRAME_TOP;
1749                     GCX_COOP_NO_DTOR_END();
1750                 }
1751                 thread->DetachThread(TRUE);
1752             }
1753
1754             ThreadDetaching();
1755         }
1756     }
1757 };
1758
1759 // This thread local object is used to detect thread shutdown. Its destructor
1760 // is called when a thread is being shut down.
1761 thread_local TlsDestructionMonitor tls_destructionMonitor;
1762
1763 void EnsureTlsDestructionMonitor()
1764 {
1765     tls_destructionMonitor.Activate();
1766 }
1767
1768 #ifdef DEBUGGING_SUPPORTED
1769 //
1770 // InitializeDebugger initialized the Runtime-side COM+ Debugging Services
1771 //
1772 static void InitializeDebugger(void)
1773 {
1774     CONTRACTL
1775     {
1776         THROWS;
1777         GC_TRIGGERS;
1778         MODE_ANY;
1779     }
1780     CONTRACTL_END;
1781
1782     // Ensure that if we throw, we'll call TerminateDebugger to cleanup.
1783     // This makes our Init more atomic by avoiding partially-init states.
1784     class EnsureCleanup {
1785         BOOL    fNeedCleanup;
1786     public:
1787         EnsureCleanup()
1788         {
1789             fNeedCleanup = TRUE;
1790         }
1791
1792         void SuppressCleanup()
1793         {
1794             fNeedCleanup  = FALSE;
1795         }
1796
1797         ~EnsureCleanup()
1798         {
1799              STATIC_CONTRACT_NOTHROW;
1800              STATIC_CONTRACT_GC_NOTRIGGER;
1801              STATIC_CONTRACT_MODE_ANY;
1802
1803             if (fNeedCleanup)
1804             {
1805                 TerminateDebugger();
1806             }
1807         }
1808     } hCleanup;
1809
1810     HRESULT hr = S_OK;
1811
1812     LOG((LF_CORDB, LL_INFO10, "Initializing left-side debugging services.\n"));
1813
1814     FARPROC gi = (FARPROC) &CorDBGetInterface;
1815
1816     // Init the interface the EE provides to the debugger,
1817     // ask the debugger for its interface, and if all goes
1818     // well call Startup on the debugger.
1819     EEDbgInterfaceImpl::Init();
1820     _ASSERTE(g_pEEDbgInterfaceImpl != NULL); // throws on OOM
1821
1822     // This allocates the Debugger object.
1823     typedef HRESULT __cdecl CORDBGETINTERFACE(DebugInterface**);
1824     hr = ((CORDBGETINTERFACE*)gi)(&g_pDebugInterface);
1825     IfFailThrow(hr);
1826
1827     g_pDebugInterface->SetEEInterface(g_pEEDbgInterfaceImpl);
1828
1829     {
1830         hr = g_pDebugInterface->Startup(); // throw on error
1831         _ASSERTE(SUCCEEDED(hr));
1832
1833         //
1834         // If the debug pack is not installed, Startup will return S_FALSE
1835         // and we should cleanup and proceed without debugging support.
1836         //
1837         if (hr != S_OK)
1838         {
1839             return;
1840         }
1841     }
1842
1843
1844     LOG((LF_CORDB, LL_INFO10, "Left-side debugging services setup.\n"));
1845
1846     hCleanup.SuppressCleanup();
1847
1848     return;
1849 }
1850
1851
1852 //
1853 // TerminateDebugger shuts down the Runtime-side COM+ Debugging Services
1854 // InitializeDebugger will call this if it fails.
1855 // This may be called even if the debugger is partially initialized.
1856 // This can be called multiple times.
1857 //
1858 static void TerminateDebugger(void)
1859 {
1860     CONTRACTL
1861     {
1862         NOTHROW;
1863         GC_NOTRIGGER;
1864         MODE_ANY;
1865     }
1866     CONTRACTL_END;
1867
1868     LOG((LF_CORDB, LL_INFO10, "Shutting down left-side debugger services.\n"));
1869
1870     // If initialized failed really early, then we didn't even get the Debugger object.
1871     if (g_pDebugInterface != NULL)
1872     {
1873         // Notify the out-of-process debugger that shutdown of the in-process debugging support has begun. This is only
1874         // really used in interop debugging scenarios.
1875         g_pDebugInterface->ShutdownBegun();
1876
1877         // This will kill the helper thread, delete the Debugger object, and free all resources.
1878         g_pDebugInterface->StopDebugger();
1879     }
1880
1881     g_CORDebuggerControlFlags = DBCF_NORMAL_OPERATION;
1882
1883 }
1884
1885 #endif // DEBUGGING_SUPPORTED
1886
1887 #ifndef LOCALE_SPARENT
1888 #define LOCALE_SPARENT 0x0000006d
1889 #endif
1890
1891 // ---------------------------------------------------------------------------
1892 // Impl for UtilLoadStringRC Callback: In VM, we let the thread decide culture
1893 // copy culture name into szBuffer and return length
1894 // ---------------------------------------------------------------------------
1895 extern BOOL g_fFatalErrorOccurredOnGCThread;
1896 static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames)
1897 {
1898     CONTRACTL
1899     {
1900         NOTHROW;
1901         GC_NOTRIGGER;
1902         MODE_ANY;
1903         PRECONDITION(CheckPointer(pCultureNames));
1904     }
1905     CONTRACTL_END;
1906
1907     HRESULT hr = S_OK;
1908
1909     EX_TRY
1910     {
1911         InlineSString<LOCALE_NAME_MAX_LENGTH> sCulture;
1912         InlineSString<LOCALE_NAME_MAX_LENGTH> sParentCulture;
1913
1914 #if 0 // Enable and test if/once the unmanaged runtime is localized
1915         Thread * pThread = GetThreadNULLOk();
1916
1917         // When fatal errors have occurred our invariants around GC modes may be broken and attempting to transition to co-op may hang
1918         // 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
1919         // getting localized with a non-default thread-specific culture.
1920         // A canonical stack trace that gets here is a fatal error in the GC that comes through:
1921         // coreclr.dll!GetThreadUICultureNames
1922         // coreclr.dll!CCompRC::LoadLibraryHelper
1923         // coreclr.dll!CCompRC::LoadLibrary
1924         // coreclr.dll!CCompRC::GetLibrary
1925         // coreclr.dll!CCompRC::LoadString
1926         // coreclr.dll!CCompRC::LoadString
1927         // coreclr.dll!SString::LoadResourceAndReturnHR
1928         // coreclr.dll!SString::LoadResourceAndReturnHR
1929         // coreclr.dll!SString::LoadResource
1930         // coreclr.dll!EventReporter::EventReporter
1931         // coreclr.dll!EEPolicy::LogFatalError
1932         // coreclr.dll!EEPolicy::HandleFatalError
1933         if (pThread != NULL && !g_fFatalErrorOccurredOnGCThread) {
1934
1935             // Switch to cooperative mode, since we'll be looking at managed objects
1936             // and we don't want them moving on us.
1937             GCX_COOP();
1938
1939             CULTUREINFOBASEREF pCurrentCulture = (CULTUREINFOBASEREF)Thread::GetCulture(TRUE);
1940
1941             if (pCurrentCulture != NULL)
1942             {
1943                 STRINGREF cultureName = pCurrentCulture->GetName();
1944
1945                 if (cultureName != NULL)
1946                 {
1947                     sCulture.Set(cultureName->GetBuffer(),cultureName->GetStringLength());
1948                 }
1949
1950                 CULTUREINFOBASEREF pParentCulture = pCurrentCulture->GetParent();
1951
1952                 if (pParentCulture != NULL)
1953                 {
1954                     STRINGREF parentCultureName = pParentCulture->GetName();
1955
1956                     if (parentCultureName != NULL)
1957                     {
1958                         sParentCulture.Set(parentCultureName->GetBuffer(),parentCultureName->GetStringLength());
1959                     }
1960
1961                 }
1962             }
1963         }
1964 #endif
1965
1966         // If the lazily-initialized cultureinfo structures aren't initialized yet, we'll
1967         // need to do the lookup the hard way.
1968         if (sCulture.IsEmpty() || sParentCulture.IsEmpty())
1969         {
1970             LocaleIDValue id ;
1971             int tmp; tmp = GetThreadUICultureId(&id);   // TODO: We should use the name instead
1972             _ASSERTE(tmp!=0 && id != UICULTUREID_DONTCARE);
1973             SIZE_T cchParentCultureName=LOCALE_NAME_MAX_LENGTH;
1974             sCulture.Set(id);
1975
1976 #ifndef TARGET_UNIX
1977             if (!::GetLocaleInfoEx((LPCWSTR)sCulture, LOCALE_SPARENT, sParentCulture.OpenUnicodeBuffer(static_cast<COUNT_T>(cchParentCultureName)),static_cast<int>(cchParentCultureName)))
1978             {
1979                 hr = HRESULT_FROM_GetLastError();
1980             }
1981             sParentCulture.CloseBuffer();
1982 #else // !TARGET_UNIX
1983             sParentCulture = sCulture;
1984 #endif // !TARGET_UNIX
1985         }
1986         // (LPCWSTR) to restrict the size to null terminated size
1987         pCultureNames->AppendIfNotThere((LPCWSTR)sCulture);
1988         // Disabling for Dev10 for consistency with managed resource lookup (see AppCompat bug notes in ResourceFallbackManager.cs)
1989         // Also, this is in the wrong order - put after the parent culture chain.
1990         //AddThreadPreferredUILanguages(pCultureNames);
1991         pCultureNames->AppendIfNotThere((LPCWSTR)sParentCulture);
1992         pCultureNames->Append(SString::Empty());
1993     }
1994     EX_CATCH
1995     {
1996         hr=E_OUTOFMEMORY;
1997     }
1998     EX_END_CATCH(SwallowAllExceptions);
1999
2000     return hr;
2001 }
2002
2003 // The exit code for the process is communicated in one of two ways.  If the
2004 // entrypoint returns an 'int' we take that.  Otherwise we take a latched
2005 // process exit code.  This can be modified by the app via System.SetExitCode().
2006 static INT32 LatchedExitCode;
2007
2008 void SetLatchedExitCode (INT32 code)
2009 {
2010     CONTRACTL
2011     {
2012         NOTHROW;
2013         GC_NOTRIGGER;
2014         MODE_ANY;
2015     }
2016     CONTRACTL_END;
2017
2018     STRESS_LOG1(LF_SYNC, LL_INFO10, "SetLatchedExitCode = %d\n", code);
2019     LatchedExitCode = code;
2020 }
2021
2022 INT32 GetLatchedExitCode (void)
2023 {
2024     LIMITED_METHOD_CONTRACT;
2025     return LatchedExitCode;
2026 }
2027
2028 // ---------------------------------------------------------------------------
2029 // Impl for UtilLoadStringRC Callback: In VM, we let the thread decide culture
2030 // Return an int uniquely describing which language this thread is using for ui.
2031 // ---------------------------------------------------------------------------
2032 static int GetThreadUICultureId(_Out_ LocaleIDValue* pLocale)
2033 {
2034     CONTRACTL{
2035         NOTHROW;
2036         GC_NOTRIGGER;
2037         MODE_ANY;
2038     } CONTRACTL_END;
2039
2040     _ASSERTE(sizeof(LocaleIDValue)/sizeof(WCHAR) >= LOCALE_NAME_MAX_LENGTH);
2041
2042     int Result = 0;
2043
2044     Thread * pThread = GetThreadNULLOk();
2045
2046 #if 0 // Enable and test if/once the unmanaged runtime is localized
2047     // When fatal errors have occurred our invariants around GC modes may be broken and attempting to transition to co-op may hang
2048     // 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
2049     // getting localized with a non-default thread-specific culture.
2050     // A canonical stack trace that gets here is a fatal error in the GC that comes through:
2051     // coreclr.dll!GetThreadUICultureNames
2052     // coreclr.dll!CCompRC::LoadLibraryHelper
2053     // coreclr.dll!CCompRC::LoadLibrary
2054     // coreclr.dll!CCompRC::GetLibrary
2055     // coreclr.dll!CCompRC::LoadString
2056     // coreclr.dll!CCompRC::LoadString
2057     // coreclr.dll!SString::LoadResourceAndReturnHR
2058     // coreclr.dll!SString::LoadResourceAndReturnHR
2059     // coreclr.dll!SString::LoadResource
2060     // coreclr.dll!EventReporter::EventReporter
2061     // coreclr.dll!EEPolicy::LogFatalError
2062     // coreclr.dll!EEPolicy::HandleFatalError
2063     if (pThread != NULL && !g_fFatalErrorOccurredOnGCThread)
2064     {
2065
2066         // Switch to cooperative mode, since we'll be looking at managed objects
2067         // and we don't want them moving on us.
2068         GCX_COOP();
2069
2070         CULTUREINFOBASEREF pCurrentCulture = (CULTUREINFOBASEREF)Thread::GetCulture(TRUE);
2071
2072         if (pCurrentCulture != NULL)
2073         {
2074             STRINGREF currentCultureName = pCurrentCulture->GetName();
2075
2076             if (currentCultureName != NULL)
2077             {
2078                 int cchCurrentCultureNameResult = currentCultureName->GetStringLength();
2079                 if (cchCurrentCultureNameResult < LOCALE_NAME_MAX_LENGTH)
2080                 {
2081                     memcpy(*pLocale, currentCultureName->GetBuffer(), cchCurrentCultureNameResult*sizeof(WCHAR));
2082                     (*pLocale)[cchCurrentCultureNameResult]='\0';
2083                     Result=cchCurrentCultureNameResult;
2084                 }
2085             }
2086         }
2087     }
2088 #endif
2089     if (Result == 0)
2090     {
2091 #ifndef TARGET_UNIX
2092         // This thread isn't set up to use a non-default culture. Let's grab the default
2093         // one and return that.
2094
2095         Result = ::GetUserDefaultLocaleName(*pLocale, LOCALE_NAME_MAX_LENGTH);
2096
2097         _ASSERTE(Result != 0);
2098 #else // !TARGET_UNIX
2099         static const WCHAR enUS[] = W("en-US");
2100         memcpy(*pLocale, enUS, sizeof(enUS));
2101         Result = sizeof(enUS);
2102 #endif // !TARGET_UNIX
2103     }
2104     return Result;
2105 }
2106
2107 #ifdef ENABLE_CONTRACTS_IMPL
2108
2109 // Returns TRUE if any contract violation suppressions are in effect.
2110 BOOL AreAnyViolationBitsOn()
2111 {
2112     CONTRACTL
2113     {
2114         NOTHROW;
2115         GC_NOTRIGGER;
2116         MODE_ANY;
2117     }
2118     CONTRACTL_END;
2119     UINT_PTR violationMask = GetClrDebugState()->ViolationMask();
2120     violationMask &= ~((UINT_PTR)CanFreeMe);  //CanFreeMe is a borrowed bit and has nothing to do with violations
2121     if (violationMask & ((UINT_PTR)BadDebugState))
2122     {
2123         return FALSE;
2124     }
2125
2126     return violationMask != 0;
2127 }
2128
2129
2130 // This function is intentionally invoked inside a big CONTRACT_VIOLATION that turns on every violation
2131 // bit on the map. The dynamic contract at the beginning *should* turn off those violation bits.
2132 // The body of this function tests to see that it did exactly that. This is to prevent the VSWhidbey B#564831 fiasco
2133 // from ever recurring.
2134 void ContractRegressionCheckInner()
2135 {
2136     // DO NOT TURN THIS CONTRACT INTO A STATIC CONTRACT!!! The very purpose of this function
2137     // is to ensure that dynamic contracts disable outstanding contract violation bits.
2138     // This code only runs once at process startup so it's not going pooch the checked build perf.
2139     CONTRACTL
2140     {
2141         NOTHROW;
2142         GC_NOTRIGGER;
2143         FORBID_FAULT;
2144         LOADS_TYPE(CLASS_LOAD_BEGIN);
2145         CANNOT_TAKE_LOCK;
2146     }
2147     CONTRACTL_END
2148
2149     if (AreAnyViolationBitsOn())
2150     {
2151         // If we got here, the contract above FAILED to turn off one or more violation bits. This is a
2152         // huge diagnostics hole and must be fixed immediately.
2153         _ASSERTE(!("WARNING: mscorwks has detected an internal error that may indicate contracts are"
2154                    " being silently disabled across the runtime. Do not ignore this assert!"));
2155     }
2156 }
2157
2158 // This function executes once per process to ensure our CONTRACT_VIOLATION() mechanism
2159 // is properly scope-limited by nested contracts.
2160 void ContractRegressionCheck()
2161 {
2162     CONTRACTL
2163     {
2164         NOTHROW;
2165         GC_NOTRIGGER;
2166         MODE_ANY;
2167     }
2168     CONTRACTL_END;
2169
2170     {
2171         // DO NOT "FIX" THIS CONTRACT_VIOLATION!!!
2172         // The existence of this CONTRACT_VIOLATION is not a bug. This is debug-only code specifically written
2173         // to test the CONTRACT_VIOLATION mechanism itself. This is needed to prevent a regression of
2174         // B#564831 (which left a huge swath of contracts silently disabled for over six months)
2175         PERMANENT_CONTRACT_VIOLATION(ThrowsViolation
2176                                    | GCViolation
2177                                    | FaultViolation
2178                                    | LoadsTypeViolation
2179                                    | TakesLockViolation
2180                                    , ReasonContractInfrastructure
2181                                     );
2182         {
2183             FAULT_NOT_FATAL();
2184             ContractRegressionCheckInner();
2185         }
2186     }
2187
2188     if (AreAnyViolationBitsOn())
2189     {
2190         // If we got here, the CONTRACT_VIOLATION() holder left one or more violation bits turned ON
2191         // after we left its scope. This is a huge diagnostic hole and must be fixed immediately.
2192         _ASSERTE(!("WARNING: mscorwks has detected an internal error that may indicate contracts are"
2193                    " being silently disabled across the runtime. Do not ignore this assert!"));
2194     }
2195
2196 }
2197
2198 #endif // ENABLE_CONTRACTS_IMPL
2199