e5267cf1311aaeeda62082cc7aca266535b5a909
[platform/upstream/coreclr.git] / src / 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 // See the LICENSE file in the project root for more information.
4 // ===========================================================================
5 // File: CEEMAIN.CPP
6 // ===========================================================================
7 //
8
9 // 
10 //
11 // The CLR code base uses a hyperlink feature of the HyperAddin plugin for Visual Studio. If you don't see
12 // 'HyperAddin' in your Visual Studio menu bar you don't have this support. To get it type 
13 // 
14 //     \\clrmain\tools\installCLRAddins
15 //     
16 //  After installing HyperAddin, your first run of VS should be as an administrator so HyperAddin can update 
17 //  some registry information.
18 //     
19 //  At this point the code: prefixes become hyperlinks in Visual Studio and life is good. See
20 //  http://mswikis/clr/dev/Pages/CLR%20Team%20Commenting.aspx for more information
21 //  
22 //  There is a bug associated with Visual Studio where it does not recognise the hyperlink if there is a ::
23 //  preceeding it on the same line. Since C++ uses :: as a namespace separator, this can often mean that the
24 //  second hyperlink on a line does not work. To work around this it is better to use '.' instead of :: as
25 //  the namespace separators in code: hyperlinks.
26 // 
27 // #StartHere
28 // #TableOfContents The .NET Runtime Table of contents
29 // 
30 // This comment is mean to be a nexus that allows you to jump quickly to various interesting parts of the
31 // runtime.
32 // 
33 // You can refer to product studio bugs using urls like the following
34 //     * http://bugcheck/bugs/DevDivBugs/2320.asp
35 //     * http://bugcheck/bugs/VSWhidbey/601210.asp
36 //     
37 //  Dev10 Bugs can be added with URLs like the following (for Dev10 bug 671409)
38 //     * http://tkbgitvstfat01:8090/wi.aspx?id=671409
39 // 
40 //*************************************************************************************************
41 //
42 // * Introduction to the runtime file:../../Documentation/botr/botr-faq.md
43 //
44 // #MajorDataStructures. The major data structures associated with the runtime are
45 //     * code:Thread (see file:threads.h#ThreadClass) - the additional thread state the runtime needs.
46 //     * code:AppDomain - The managed version of a process
47 //     * code:Assembly - The unit of deployment and versioning (may be several DLLs but often is only one).
48 //     * code:Module - represents a Module (DLL or EXE).
49 //     * code:MethodTable - represents the 'hot' part of a type (needed during normal execution)
50 //     * code:EEClass - represents the 'cold' part of a type (used during compilation, interop, ...)
51 //     * code:MethodDesc - represents a Method
52 //     * code:FieldDesc - represents a Field.
53 //     * code:Object - represents a object on the GC heap allocated with code:Alloc 
54 // 
55 // * ECMA specifications
56 //     * Partition I Concepts
57 //         http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20I%20Architecture.doc
58 //     * Partition II Meta Data
59 //         http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20II%20Metadata.doc
60 //     * Partition III IL
61 //         http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20III%20CIL.doc
62 //  
63 //  * Serge Liden (worked on the CLR and owned ILASM / ILDASM for a long time wrote a good book on IL
64 //     * Expert .NET 2.0 IL Assembler  http://www.amazon.com/Expert-NET-2-0-IL-Assembler/dp/1590596463
65 // 
66 // * This is also a pretty nice overview of what the CLR is at
67 //     http://msdn2.microsoft.com/en-us/netframework/aa497266.aspx
68 // 
69 // * code:EEStartup - This routine must be called before any interesting runtime services are used. It is
70 //     invoked as part of mscorwks's DllMain logic.
71 // * code:#EEShutDown - Code called before we shut down the EE.
72 //     
73 // * file:..\inc\corhdr.h#ManagedHeader - From a data structure point of view, this is the entry point into
74 //     the runtime. This is how all other data in the EXE are found.
75 //  
76 // * code:ICorJitCompiler#EEToJitInterface - This is the interface from the the EE to the Just in time (JIT)
77 //     compiler. The interface to the JIT is relatively simple (compileMethod), however the EE provides a
78 //     rich set of callbacks so the JIT can get all the information it needs. See also
79 //     file:../../Documentation/botr/ryujit-overview.md for general information on the JIT.
80 // 
81 // * code:VirtualCallStubManager - This is the main class that implements interface dispatch
82 // 
83 // * Precode - Every method needs entry point for other code to call even if that native code does not
84 //     actually exist yet. To support this methods can have code:Precode that is an entry point that exists
85 //     and will call the JIT compiler if the code does not yet exist.
86 //     
87 //  * NGEN - NGen stands for Native code GENeration and it is the runtime way of precompiling IL and IL
88 //      Meta-data into native code and runtime data structures. At compilation time the most
89 //      fundamental data structures is the code:ZapNode which represents something that needs to go into the
90 //      NGEN image.
91 //      
92 //   * What is cooperative / preemtive mode ? file:threads.h#CooperativeMode and
93 //       file:threads.h#SuspendingTheRuntime and file:../../Documentation/botr/threading.md
94 //   * Garbage collection - file:gc.cpp#Overview and file:../../Documentation/botr/garbage-collection.md
95 //   * code:AppDomain - The managed version of a process.
96 //   * Calling Into the runtime (FCALLs QCalls) file:../../Documentation/botr/mscorlib.md
97 //   * Exceptions - file:../../Documentation/botr/exceptions.md. The most important routine to start
98 //       with is code:COMPlusFrameHandler which is the routine that we hook up to get called when an unmanaged
99 //       exception happens.
100 //   * Assembly Loading file:../../Documentation/botr/type-loader.md
101 //   * Profiling file:../../Documentation/botr/profiling.md and file:../../Documentation/botr/profilability.md
102 //   * FCALLS QCALLS (calling into the runtime from managed code)
103 //       file:../../Documentation/botr/mscorlib.md
104 //   * Event Tracing for Windows
105 //     * file:../inc/eventtrace.h#EventTracing -
106 //     * This is the main file dealing with event tracing in CLR
107 //     * The implementation of this class is available in file:eventtrace.cpp
108 //     * file:../inc/eventtrace.h#CEtwTracer - This is the main class dealing with event tracing in CLR.
109 //         Follow the link for more information on how this feature has been implemented
110 //     * http://mswikis/clr/dev/Pages/CLR%20ETW%20Events%20Wiki.aspx - Follow the link for more information on how to
111 //         use this instrumentation feature.
112
113 // ----------------------------------------------------------------------------------------------------
114 // Features in the runtime that have been given hyperlinks
115 // 
116 // * code:Nullable#NullableFeature - the Nullable<T> type has special runtime semantics associated with
117 //     boxing this describes this feature.
118
119 #include "common.h"
120
121 #include "vars.hpp"
122 #include "log.h"
123 #include "ceemain.h"
124 #include "clsload.hpp"
125 #include "object.h"
126 #include "hash.h"
127 #include "ecall.h"
128 #include "ceemain.h"
129 #include "dllimport.h"
130 #include "syncblk.h"
131 #include "eeconfig.h"
132 #include "stublink.h"
133 #include "method.hpp"
134 #include "codeman.h"
135 #include "frames.h"
136 #include "threads.h"
137 #include "stackwalk.h"
138 #include "gcheaputilities.h"
139 #include "interoputil.h"
140 #include "fieldmarshaler.h"
141 #include "dbginterface.h"
142 #include "eedbginterfaceimpl.h"
143 #include "debugdebugger.h"
144 #include "cordbpriv.h"
145 #include "comdelegate.h"
146 #include "appdomain.hpp"
147 #include "eventtrace.h"
148 #include "corhost.h"
149 #include "binder.h"
150 #include "olevariant.h"
151 #include "comcallablewrapper.h"
152 #include "apithreadstress.h"
153 #include "perflog.h"
154 #include "../dlls/mscorrc/resource.h"
155 #include "util.hpp"
156 #include "shimload.h"
157 #include "comthreadpool.h"
158 #include "posterror.h"
159 #include "virtualcallstub.h"
160 #include "strongnameinternal.h"
161 #include "syncclean.hpp"
162 #include "typeparse.h"
163 #include "debuginfostore.h"
164 #include "mdaassistants.h"
165 #include "eemessagebox.h"
166 #include "finalizerthread.h"
167 #include "threadsuspend.h"
168 #include "disassembler.h"
169 #include "jithost.h"
170
171 #ifndef FEATURE_PAL
172 #include "dwreport.h"
173 #endif // !FEATURE_PAL
174
175 #include "stringarraylist.h"
176 #include "stubhelpers.h"
177
178 #ifdef FEATURE_STACK_SAMPLING
179 #include "stacksampler.h"
180 #endif
181
182 #include <shlwapi.h>
183
184 #include "bbsweep.h"
185
186
187 #ifdef FEATURE_COMINTEROP
188 #include "runtimecallablewrapper.h"
189 #include "notifyexternals.h"
190 #include "mngstdinterfaces.h"
191 #include "rcwwalker.h"
192 #endif // FEATURE_COMINTEROP
193
194 #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
195 #include "olecontexthelpers.h"
196 #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
197
198 #ifdef PROFILING_SUPPORTED
199 #include "proftoeeinterfaceimpl.h"
200 #include "profilinghelper.h"
201 #endif // PROFILING_SUPPORTED
202
203 #ifdef FEATURE_COMINTEROP
204 #include "synchronizationcontextnative.h"       // For SynchronizationContextNative::Cleanup
205 #endif
206
207 #ifdef FEATURE_INTERPRETER
208 #include "interpreter.h"
209 #endif // FEATURE_INTERPRETER
210
211 #include "../binder/inc/coreclrbindercommon.h"
212
213
214 #ifdef FEATURE_PERFMAP
215 #include "perfmap.h"
216 #endif
217
218 #include "eventpipe.h"
219
220 #ifndef FEATURE_PAL
221 // Included for referencing __security_cookie
222 #include "process.h"
223 #endif // !FEATURE_PAL
224
225 #ifdef FEATURE_GDBJIT
226 #include "gdbjit.h"
227 #endif // FEATURE_GDBJIT
228
229 #ifndef CROSSGEN_COMPILE
230 static int GetThreadUICultureId(__out LocaleIDValue* pLocale);  // TODO: This shouldn't use the LCID.  We should rely on name instead
231
232 static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames);
233 #endif // !CROSSGEN_COMPILE
234
235 HRESULT EEStartup(COINITIEE fFlags);
236
237
238 #ifndef CROSSGEN_COMPILE
239 static void InitializeGarbageCollector();
240
241 #ifdef DEBUGGING_SUPPORTED
242 static void InitializeDebugger(void);
243 static void TerminateDebugger(void);
244 extern "C" HRESULT __cdecl CorDBGetInterface(DebugInterface** rcInterface);
245 #endif // DEBUGGING_SUPPORTED
246 #endif // !CROSSGEN_COMPILE
247
248
249
250
251 // Remember how the last startup of EE went.
252 HRESULT g_EEStartupStatus = S_OK;
253
254 // Flag indicating if the EE has been started.  This is set prior to initializing the default AppDomain, and so does not indicate that
255 // the EE is fully able to execute arbitrary managed code.  To ensure the EE is fully started, call EnsureEEStarted rather than just
256 // checking this flag.
257 Volatile<BOOL> g_fEEStarted = FALSE;
258
259 // Flag indicating if the EE should be suspended on shutdown.
260 BOOL    g_fSuspendOnShutdown = FALSE;
261
262 // Flag indicating if the finalizer thread should be suspended on shutdown.
263 BOOL    g_fSuspendFinalizerOnShutdown = FALSE;
264
265 // Flag indicating if the EE was started up by COM.
266 extern BOOL g_fEEComActivatedStartup;
267
268 // flag indicating that EE was not started up by IJW, Hosted, COM or my managed exe. 
269 extern BOOL g_fEEOtherStartup;
270
271 // The OS thread ID of the thread currently performing EE startup, or 0 if there is no such thread.
272 DWORD   g_dwStartupThreadId = 0;
273
274 // Event to synchronize EE shutdown.
275 static CLREvent * g_pEEShutDownEvent;
276
277 static DangerousNonHostedSpinLock g_EEStartupLock;
278
279 HRESULT InitializeEE(COINITIEE flags)
280 {
281     WRAPPER_NO_CONTRACT;
282 #ifdef FEATURE_EVENT_TRACE
283     if(!g_fEEComActivatedStartup)
284         g_fEEOtherStartup = TRUE;
285 #endif // FEATURE_EVENT_TRACE
286     return EnsureEEStarted(flags);
287 }
288
289 // ---------------------------------------------------------------------------
290 // %%Function: EnsureEEStarted()
291 //
292 // Description: Ensure the CLR is started.
293 // ---------------------------------------------------------------------------
294 HRESULT EnsureEEStarted(COINITIEE flags)
295 {
296     CONTRACTL
297     {
298         NOTHROW;
299         GC_TRIGGERS;
300         MODE_PREEMPTIVE;
301         ENTRY_POINT;
302     }
303     CONTRACTL_END;
304
305     if (g_fEEShutDown)
306         return E_FAIL;
307
308     HRESULT hr = E_FAIL;
309
310     // On non x86 platforms, when we load mscorlib.dll during EEStartup, we will
311     // re-enter _CorDllMain with a DLL_PROCESS_ATTACH for mscorlib.dll. We are
312     // far enough in startup that this is allowed, however we don't want to
313     // re-start the startup code so we need to check to see if startup has
314     // been initiated or completed before we call EEStartup. 
315     //
316     // We do however want to make sure other threads block until the EE is started,
317     // which we will do further down.
318     if (!g_fEEStarted)
319     {
320         BEGIN_ENTRYPOINT_NOTHROW;
321
322 #if defined(FEATURE_APPX) && !defined(CROSSGEN_COMPILE)
323         STARTUP_FLAGS startupFlags = CorHost2::GetStartupFlags();
324         // On CoreCLR, the host is in charge of determining whether the process is AppX or not.
325         AppX::SetIsAppXProcess(!!(startupFlags & STARTUP_APPX_APP_MODEL));
326 #endif
327
328 #ifndef FEATURE_PAL
329         // The sooner we do this, the sooner we avoid probing registry entries.
330         // (Perf Optimization for VSWhidbey:113373.)
331         REGUTIL::InitOptionalConfigCache();
332 #endif
333
334
335         BOOL bStarted=FALSE;
336
337         {
338             DangerousNonHostedSpinLockHolder lockHolder(&g_EEStartupLock);
339
340             // Now that we've acquired the lock, check again to make sure we aren't in
341             // the process of starting the CLR or that it hasn't already been fully started.
342             // At this point, if startup has been inited we don't have anything more to do.
343             // And if EEStartup already failed before, we don't do it again.
344             if (!g_fEEStarted && !g_fEEInit && SUCCEEDED (g_EEStartupStatus))
345             {
346                 g_dwStartupThreadId = GetCurrentThreadId();
347
348                 EEStartup(flags);
349                 bStarted=g_fEEStarted;
350                 hr = g_EEStartupStatus;
351
352                 g_dwStartupThreadId = 0;
353             }
354             else
355             {
356                 hr = g_EEStartupStatus;
357                 if (SUCCEEDED(g_EEStartupStatus))
358                 {
359                     hr = S_FALSE;
360                 }
361             }
362         }
363
364 #ifdef FEATURE_TESTHOOKS        
365         if(bStarted)
366             TESTHOOKCALL(RuntimeStarted(RTS_INITIALIZED));
367 #endif        
368         END_ENTRYPOINT_NOTHROW;
369     }
370     else
371     {
372         //
373         // g_fEEStarted is TRUE, but startup may not be complete since we initialize the default AppDomain
374         // *after* setting that flag.  g_fEEStarted is set inside of g_EEStartupLock, and that lock is
375         // not released until the EE is really started - so we can quickly check whether the EE is definitely
376         // started by checking if that lock is currently held.  If it is not, then we know the other thread
377         // (that is actually doing the startup) has finished startup.  If it is currently held, then we
378         // need to wait for the other thread to release it, which we do by simply acquiring the lock ourselves.
379         //
380         // We do not want to do this blocking if we are the thread currently performing EE startup.  So we check
381         // that first.
382         //
383         // Note that the call to IsHeld here is an "acquire" barrier, as is acquiring the lock.  And the release of 
384         // the lock by the other thread is a "release" barrier, due to the volatile semantics in the lock's 
385         // implementation.  This assures us that once we observe the lock having been released, we are guaranteed 
386         // to observe a fully-initialized EE.
387         //
388         // A note about thread affinity here: we're using the OS thread ID of the current thread without
389         // asking the host to pin us to this thread, as we did above.  We can get away with this, because we are
390         // only interested in a particular thread ID (that of the "startup" thread) and *that* particular thread
391         // is already affinitized by the code above.  So if we get that particular OS thread ID, we know for sure
392         // we are really the startup thread.
393         //
394         if (g_EEStartupLock.IsHeld() && g_dwStartupThreadId != GetCurrentThreadId())
395         {
396             DangerousNonHostedSpinLockHolder lockHolder(&g_EEStartupLock);
397         }
398
399         hr = g_EEStartupStatus;
400         if (SUCCEEDED(g_EEStartupStatus))
401         {
402             hr = S_FALSE;
403         }
404     }
405
406     return hr;
407 }
408
409
410 #ifndef CROSSGEN_COMPILE
411
412 #ifndef FEATURE_PAL
413 // This is our Ctrl-C, Ctrl-Break, etc. handler.
414 static BOOL WINAPI DbgCtrlCHandler(DWORD dwCtrlType)
415 {
416     WRAPPER_NO_CONTRACT;
417
418 #if defined(DEBUGGING_SUPPORTED)
419     // Note that if a managed-debugger is attached, it's actually attached with the native
420     // debugging pipeline and it will get a control-c notifications via native debug events.
421     // However, if we let the native debugging pipeline handle the event and send the notification
422     // to the debugger, then we break pre-V4 behaviour because we intercept handlers registered
423     // in-process.  See Dev10 Bug 846455 for more information. 
424     if (CORDebuggerAttached() &&
425         (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT))
426     {
427         return g_pDebugInterface->SendCtrlCToDebugger(dwCtrlType);
428     }
429     else
430 #endif // DEBUGGING_SUPPORTED
431     {
432         if (dwCtrlType == CTRL_CLOSE_EVENT)
433         {
434             // Initiate shutdown so the ProcessExit handlers run
435             ForceEEShutdown(SCA_ReturnWhenShutdownComplete);
436         }
437
438         g_fInControlC = true;     // only for weakening assertions in checked build.
439         return FALSE;             // keep looking for a real handler.
440     }
441 }
442 #endif
443
444 // A host can specify that it only wants one version of hosting interface to be used.
445 BOOL g_singleVersionHosting;
446
447
448
449 void InitializeStartupFlags()
450 {
451     CONTRACTL {
452         NOTHROW;
453         GC_TRIGGERS;
454         MODE_ANY;
455     } CONTRACTL_END;
456
457     STARTUP_FLAGS flags = CorHost2::GetStartupFlags();
458
459
460     if (flags & STARTUP_CONCURRENT_GC)
461         g_IGCconcurrent = 1;
462     else
463         g_IGCconcurrent = 0;
464
465
466     g_heap_type = (flags & STARTUP_SERVER_GC) == 0 ? GC_HEAP_WKS : GC_HEAP_SVR;
467     g_IGCHoardVM = (flags & STARTUP_HOARD_GC_VM) == 0 ? 0 : 1;
468 }
469 #endif // CROSSGEN_COMPILE
470
471
472 #ifdef FEATURE_PREJIT
473 // BBSweepStartFunction is the first function to execute in the BBT sweeper thread.
474 // It calls WatchForSweepEvent where we wait until a sweep occurs.
475 DWORD __stdcall BBSweepStartFunction(LPVOID lpArgs)
476 {
477     CONTRACTL
478     {
479         THROWS;
480         GC_TRIGGERS;
481         MODE_PREEMPTIVE;
482     }
483     CONTRACTL_END;
484
485     class CLRBBSweepCallback : public ICLRBBSweepCallback
486     {
487         virtual HRESULT WriteProfileData()
488         {
489             BEGIN_ENTRYPOINT_NOTHROW
490             WRAPPER_NO_CONTRACT;
491             Module::WriteAllModuleProfileData(false);
492             END_ENTRYPOINT_NOTHROW;
493             return S_OK;
494         }
495     } clrCallback;
496
497     EX_TRY
498     {
499         g_BBSweep.WatchForSweepEvents(&clrCallback);
500     }
501     EX_CATCH
502     {
503     }
504     EX_END_CATCH(RethrowTerminalExceptions)
505
506     return 0;
507 }
508 #endif // FEATURE_PREJIT
509
510
511 //-----------------------------------------------------------------------------
512
513 void InitGSCookie()
514 {
515     CONTRACTL
516     {
517         THROWS;
518         GC_NOTRIGGER;
519         MODE_ANY;
520     }
521     CONTRACTL_END;
522
523     GSCookie * pGSCookiePtr = GetProcessGSCookiePtr();
524
525     DWORD oldProtection;
526     if(!ClrVirtualProtect((LPVOID)pGSCookiePtr, sizeof(GSCookie), PAGE_EXECUTE_READWRITE, &oldProtection))
527     {
528         ThrowLastError();
529     }
530
531 #ifndef FEATURE_PAL
532     // The GSCookie cannot be in a writeable page
533     assert(((oldProtection & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|
534                               PAGE_EXECUTE_WRITECOPY|PAGE_WRITECOMBINE)) == 0));
535
536     // Forces VC cookie to be initialized.
537     void * pf = &__security_check_cookie;
538     pf = NULL;
539
540     GSCookie val = (GSCookie)(__security_cookie ^ GetTickCount());
541 #else // !FEATURE_PAL
542     // REVIEW: Need something better for PAL...
543     GSCookie val = (GSCookie)GetTickCount();
544 #endif // !FEATURE_PAL
545
546 #ifdef _DEBUG
547     // In _DEBUG, always use the same value to make it easier to search for the cookie
548     val = (GSCookie) WIN64_ONLY(0x9ABCDEF012345678) NOT_WIN64(0x12345678);
549 #endif
550
551     // To test if it is initialized. Also for ICorMethodInfo::getGSCookie()
552     if (val == 0)
553         val ++;
554     *pGSCookiePtr = val;
555
556     if(!ClrVirtualProtect((LPVOID)pGSCookiePtr, sizeof(GSCookie), oldProtection, &oldProtection))
557     {
558         ThrowLastError();
559     }
560 }
561
562 Volatile<BOOL> g_bIsGarbageCollectorFullyInitialized = FALSE;
563
564 void SetGarbageCollectorFullyInitialized()
565 {
566     LIMITED_METHOD_CONTRACT;
567
568     g_bIsGarbageCollectorFullyInitialized = TRUE;
569 }
570
571 // Tells whether the garbage collector is fully initialized
572 // Stronger than IsGCHeapInitialized
573 BOOL IsGarbageCollectorFullyInitialized()
574 {
575     LIMITED_METHOD_CONTRACT;
576
577     return g_bIsGarbageCollectorFullyInitialized;
578 }
579
580 // ---------------------------------------------------------------------------
581 // %%Function: EEStartupHelper
582 //
583 // Parameters:
584 //  fFlags                  - Initialization flags for the engine.  See the
585 //                              EEStartupFlags enumerator for valid values.
586 //
587 // Returns:
588 //  S_OK                    - On success
589 //
590 // Description:
591 //  Reserved to initialize the EE runtime engine explicitly.
592 // ---------------------------------------------------------------------------
593
594 #ifndef IfFailGotoLog
595 #define IfFailGotoLog(EXPR, LABEL) \
596 do { \
597     hr = (EXPR);\
598     if(FAILED(hr)) { \
599         STRESS_LOG2(LF_STARTUP, LL_ALWAYS, "%s failed with code %x", #EXPR, hr);\
600         goto LABEL; \
601     } \
602     else \
603        STRESS_LOG1(LF_STARTUP, LL_ALWAYS, "%s completed", #EXPR);\
604 } while (0)
605 #endif
606
607 #ifndef IfFailGoLog
608 #define IfFailGoLog(EXPR) IfFailGotoLog(EXPR, ErrExit)
609 #endif
610
611 void EEStartupHelper(COINITIEE fFlags)
612 {
613     CONTRACTL
614     {
615         THROWS;
616         GC_TRIGGERS;
617         MODE_ANY;
618     } CONTRACTL_END;
619
620 #ifdef ENABLE_CONTRACTS_IMPL
621     {
622         extern void ContractRegressionCheck();
623         ContractRegressionCheck();
624     }
625 #endif
626
627     HRESULT hr = S_OK;
628     static ConfigDWORD breakOnEELoad;
629     EX_TRY
630     {
631         g_fEEInit = true;
632
633 #ifndef CROSSGEN_COMPILE
634
635 #ifndef FEATURE_PAL
636         ::SetConsoleCtrlHandler(DbgCtrlCHandler, TRUE/*add*/);
637 #endif
638
639 #endif // CROSSGEN_COMPILE
640
641         // SString initialization
642         // This needs to be done before config because config uses SString::Empty()
643         SString::Startup();
644
645         // Initialize EEConfig
646         if (!g_pConfig)
647         {
648             IfFailGo(EEConfig::Setup());
649         }
650
651 #ifndef CROSSGEN_COMPILE
652         // Initialize Numa and CPU group information
653         // Need to do this as early as possible. Used by creating object handle
654         // table inside Ref_Initialization() before GC is initialized.
655         NumaNodeInfo::InitNumaNodeInfo();
656         CPUGroupInfo::EnsureInitialized();
657
658
659         // Initialize global configuration settings based on startup flags
660         // This needs to be done before the EE has started
661         InitializeStartupFlags();
662
663         MethodDescBackpatchInfoTracker::StaticInitialize();
664
665         InitThreadManager();
666         STRESS_LOG0(LF_STARTUP, LL_ALWAYS, "Returned successfully from InitThreadManager");
667
668 #ifdef FEATURE_PERFTRACING
669         // Initialize the event pipe.
670         EventPipe::Initialize();
671 #endif // FEATURE_PERFTRACING
672
673 #ifdef FEATURE_GDBJIT
674         // Initialize gdbjit
675         NotifyGdb::Initialize();
676 #endif // FEATURE_GDBJIT
677
678 #ifdef FEATURE_EVENT_TRACE        
679         // Initialize event tracing early so we can trace CLR startup time events.
680         InitializeEventTracing();
681
682         // Fire the EE startup ETW event
683         ETWFireEvent(EEStartupStart_V1);
684 #endif // FEATURE_EVENT_TRACE
685
686         InitGSCookie();
687
688         Frame::Init();
689
690 #ifdef FEATURE_TESTHOOKS
691         IfFailGo(CLRTestHookManager::CheckConfig());
692 #endif
693
694 #endif // CROSSGEN_COMPILE
695
696
697 #ifdef STRESS_LOG
698         if (REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLog, g_pConfig->StressLog ()) != 0) {
699             unsigned facilities = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_LogFacility, LF_ALL);
700             unsigned level = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_LogLevel, LL_INFO1000);
701             unsigned bytesPerThread = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLogSize, STRESSLOG_CHUNK_SIZE * 4);
702             unsigned totalBytes = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_TotalStressLogSize, STRESSLOG_CHUNK_SIZE * 1024);
703             StressLog::Initialize(facilities, level, bytesPerThread, totalBytes, GetModuleInst());
704             g_pStressLog = &StressLog::theLog;
705         }
706 #endif
707
708 #ifdef LOGGING
709         InitializeLogging();
710 #endif
711
712 #ifdef ENABLE_PERF_LOG
713         PerfLog::PerfLogInitialize();
714 #endif //ENABLE_PERF_LOG
715
716 #ifdef FEATURE_PERFMAP
717         PerfMap::Initialize();
718 #endif
719
720         STRESS_LOG0(LF_STARTUP, LL_ALWAYS, "===================EEStartup Starting===================");
721
722 #ifndef CROSSGEN_COMPILE
723 #ifndef FEATURE_PAL
724         IfFailGoLog(EnsureRtlFunctions());
725 #endif // !FEATURE_PAL
726         InitEventStore();
727 #endif
728
729         // Fusion
730         // Initialize the general Assembly Binder infrastructure
731         IfFailGoLog(CCoreCLRBinderHelper::Init());
732
733         if (g_pConfig != NULL)
734         {
735             IfFailGoLog(g_pConfig->sync());        
736         }
737
738         // Fire the runtime information ETW event
739         ETW::InfoLog::RuntimeInformation(ETW::InfoLog::InfoStructs::Normal);
740
741         if (breakOnEELoad.val(CLRConfig::UNSUPPORTED_BreakOnEELoad) == 1)
742         {
743 #ifdef _DEBUG
744             _ASSERTE(!"Start loading EE!");
745 #else
746             DebugBreak();
747 #endif
748         }
749
750 #ifdef ENABLE_STARTUP_DELAY
751         PREFIX_ASSUME(NULL != g_pConfig);
752         if (g_pConfig->StartupDelayMS())
753         {
754             ClrSleepEx(g_pConfig->StartupDelayMS(), FALSE);
755         }
756 #endif
757         
758 #if USE_DISASSEMBLER
759         if ((g_pConfig->GetGCStressLevel() & (EEConfig::GCSTRESS_INSTR_JIT | EEConfig::GCSTRESS_INSTR_NGEN)) != 0)
760         {
761             Disassembler::StaticInitialize();
762             if (!Disassembler::IsAvailable())
763             {
764                 fprintf(stderr, "External disassembler is not available.\n");
765                 IfFailGo(E_FAIL);
766             }
767         }
768 #endif // USE_DISASSEMBLER
769
770         // Monitors, Crsts, and SimpleRWLocks all use the same spin heuristics
771         // Cache the (potentially user-overridden) values now so they are accessible from asm routines
772         InitializeSpinConstants();
773
774 #ifndef CROSSGEN_COMPILE
775
776
777 #ifdef FEATURE_PREJIT
778         // Initialize the sweeper thread.
779         if (g_pConfig->GetZapBBInstr() != NULL)
780         {
781             DWORD threadID;
782             HANDLE hBBSweepThread = ::CreateThread(NULL,
783                                                    0,
784                                                    (LPTHREAD_START_ROUTINE) BBSweepStartFunction,
785                                                    NULL,
786                                                    0,
787                                                    &threadID);
788             _ASSERTE(hBBSweepThread);
789             g_BBSweep.SetBBSweepThreadHandle(hBBSweepThread);
790         }
791 #endif // FEATURE_PREJIT
792
793 #ifdef FEATURE_INTERPRETER
794         Interpreter::Initialize();
795 #endif // FEATURE_INTERPRETER
796
797         StubManager::InitializeStubManagers();
798
799 #ifndef FEATURE_PAL
800         {
801             // Record mscorwks geometry
802             PEDecoder pe(g_pMSCorEE);
803
804             g_runtimeLoadedBaseAddress = (SIZE_T)pe.GetBase();
805             g_runtimeVirtualSize = (SIZE_T)pe.GetVirtualSize();
806             InitCodeAllocHint(g_runtimeLoadedBaseAddress, g_runtimeVirtualSize, GetRandomInt(64));
807         }
808 #endif // !FEATURE_PAL
809
810 #endif // CROSSGEN_COMPILE
811
812         // Set up the cor handle map. This map is used to load assemblies in
813         // memory instead of using the normal system load
814         PEImage::Startup();
815
816         AccessCheckOptions::Startup();
817
818         MscorlibBinder::Startup();
819
820         Stub::Init();
821         StubLinkerCPU::Init();
822
823 #ifndef CROSSGEN_COMPILE
824
825         InitializeGarbageCollector();
826
827         // Initialize remoting
828
829         if (!GCHandleUtilities::GetGCHandleManager()->Initialize())
830         {
831             IfFailGo(E_OUTOFMEMORY);
832         }
833
834         g_pEEShutDownEvent = new CLREvent();
835         g_pEEShutDownEvent->CreateManualEvent(FALSE);
836
837         VirtualCallStubManager::InitStatic();
838
839         GCInterface::m_MemoryPressureLock.Init(CrstGCMemoryPressure);
840
841 #endif // CROSSGEN_COMPILE
842
843         // Setup the domains. Threads are started in a default domain.
844
845         // Static initialization
846         PEAssembly::Attach();
847         BaseDomain::Attach();
848         SystemDomain::Attach();
849
850         // Start up the EE intializing all the global variables
851         ECall::Init();
852
853         COMDelegate::Init();
854
855         ExecutionManager::Init();
856
857         JitHost::Init();
858
859 #ifndef CROSSGEN_COMPILE
860
861 #ifndef FEATURE_PAL      
862         if (!RegisterOutOfProcessWatsonCallbacks())
863         {
864             IfFailGo(E_FAIL);
865         }
866 #endif // !FEATURE_PAL
867
868 #ifdef DEBUGGING_SUPPORTED
869         if(!NingenEnabled())
870         {
871             // Initialize the debugging services. This must be done before any
872             // EE thread objects are created, and before any classes or
873             // modules are loaded.
874             InitializeDebugger(); // throws on error
875         }
876 #endif // DEBUGGING_SUPPORTED
877
878 #ifdef MDA_SUPPORTED
879         ManagedDebuggingAssistants::EEStartupActivation();
880 #endif
881
882 #ifdef PROFILING_SUPPORTED
883         // Initialize the profiling services.
884         hr = ProfilingAPIUtility::InitializeProfiling();
885
886         _ASSERTE(SUCCEEDED(hr));
887         IfFailGo(hr);
888 #endif // PROFILING_SUPPORTED
889
890         InitializeExceptionHandling();
891
892         //
893         // Install our global exception filter
894         //
895         if (!InstallUnhandledExceptionFilter())
896         {
897             IfFailGo(E_FAIL);
898         }
899
900         // throws on error
901         SetupThread();
902
903 #ifdef DEBUGGING_SUPPORTED
904         // Notify debugger once the first thread is created to finish initialization.
905         if (g_pDebugInterface != NULL)
906         {
907             g_pDebugInterface->StartupPhase2(GetThread());
908         }
909 #endif
910
911         InitPreStubManager();
912
913 #ifdef FEATURE_COMINTEROP
914         InitializeComInterop();
915 #endif // FEATURE_COMINTEROP
916
917         StubHelpers::Init();
918         NDirect::Init();
919
920         // Before setting up the execution manager initialize the first part
921         // of the JIT helpers.
922         InitJITHelpers1();
923         InitJITHelpers2();
924
925         SyncBlockCache::Attach();
926
927         // Set up the sync block
928         SyncBlockCache::Start();
929
930         StackwalkCache::Init();
931
932         // This isn't done as part of InitializeGarbageCollector() above because it
933         // requires write barriers to have been set up on x86, which happens as part
934         // of InitJITHelpers1.
935         hr = g_pGCHeap->Initialize();
936         IfFailGo(hr);
937
938         // This isn't done as part of InitializeGarbageCollector() above because thread
939         // creation requires AppDomains to have been set up.
940         FinalizerThread::FinalizerThreadCreate();
941
942         // Now we really have fully initialized the garbage collector
943         SetGarbageCollectorFullyInitialized();
944
945 #ifdef DEBUGGING_SUPPORTED
946         // Make a call to publish the DefaultDomain for the debugger
947         // This should be done before assemblies/modules are loaded into it (i.e. SystemDomain::Init)
948         // and after its OK to switch GC modes and syncronize for sending events to the debugger.
949         // @dbgtodo  synchronization: this can probably be simplified in V3
950         LOG((LF_CORDB | LF_SYNC | LF_STARTUP, LL_INFO1000, "EEStartup: adding default domain 0x%x\n",
951              SystemDomain::System()->DefaultDomain()));
952         SystemDomain::System()->PublishAppDomainAndInformDebugger(SystemDomain::System()->DefaultDomain());
953 #endif
954
955 #endif // CROSSGEN_COMPILE
956
957         SystemDomain::System()->Init();
958
959 #ifdef PROFILING_SUPPORTED
960         // <TODO>This is to compensate for the DefaultDomain workaround contained in
961         // SystemDomain::Attach in which the first user domain is created before profiling
962         // services can be initialized.  Profiling services cannot be moved to before the
963         // workaround because it needs SetupThread to be called.</TODO>
964
965         SystemDomain::NotifyProfilerStartup();
966 #endif // PROFILING_SUPPORTED
967
968         g_fEEInit = false;
969
970         SystemDomain::System()->DefaultDomain()->LoadSystemAssemblies();
971
972         SystemDomain::System()->DefaultDomain()->SetupSharedStatics();
973
974 #ifdef _DEBUG
975         APIThreadStress::SetThreadStressCount(g_pConfig->GetAPIThreadStressCount());
976 #endif
977 #ifdef FEATURE_STACK_SAMPLING
978         StackSampler::Init();
979 #endif
980
981 #ifndef CROSSGEN_COMPILE
982         if (!NingenEnabled())
983         {
984             // Perform any once-only SafeHandle initialization.
985             SafeHandle::Init();
986         }
987
988 #ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
989         // retrieve configured max size for the mini-metadata buffer (defaults to 64KB)
990         g_MiniMetaDataBuffMaxSize = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MiniMdBufferCapacity);
991         // align up to GetOsPageSize(), with a maximum of 1 MB
992         g_MiniMetaDataBuffMaxSize = (DWORD) min(ALIGN_UP(g_MiniMetaDataBuffMaxSize, GetOsPageSize()), 1024 * 1024);
993         // allocate the buffer. this is never touched while the process is running, so it doesn't 
994         // contribute to the process' working set. it is needed only as a "shadow" for a mini-metadata
995         // buffer that will be set up and reported / updated in the Watson process (the 
996         // DacStreamsManager class coordinates this)
997         g_MiniMetaDataBuffAddress = (TADDR) ClrVirtualAlloc(NULL, 
998                                                 g_MiniMetaDataBuffMaxSize, MEM_COMMIT, PAGE_READWRITE);
999 #endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
1000
1001 #endif // CROSSGEN_COMPILE
1002
1003         g_fEEStarted = TRUE;
1004         g_EEStartupStatus = S_OK;
1005         hr = S_OK;
1006         STRESS_LOG0(LF_STARTUP, LL_ALWAYS, "===================EEStartup Completed===================");
1007
1008 #ifndef CROSSGEN_COMPILE
1009
1010 #ifdef _DEBUG
1011
1012         //if g_fEEStarted was false when we loaded the System Module, we did not run ExpandAll on it.  In
1013         //this case, make sure we run ExpandAll here.  The rationale is that if we Jit before g_fEEStarted
1014         //is true, we can't initialize Com, so we can't jit anything that uses Com types.  Also, it's
1015         //probably not safe to Jit while g_fEEStarted is false.
1016         //
1017         //Also, if you run this it's possible we'll call CoInitialize, which defaults to MTA.  This might
1018         //mess up an application that uses STA.  However, this mode is only supported for certain limited
1019         //jit testing scenarios, so it can live with the limitation.
1020         if (g_pConfig->ExpandModulesOnLoad())
1021         {
1022             SystemDomain::SystemModule()->ExpandAll();
1023         }
1024
1025         // Perform mscorlib consistency check if requested
1026         g_Mscorlib.CheckExtended();
1027
1028 #endif // _DEBUG
1029
1030 #ifdef HAVE_GCCOVER
1031         MethodDesc::Init();
1032 #endif
1033
1034 #endif // !CROSSGEN_COMPILE
1035
1036 ErrExit: ;
1037     }
1038     EX_CATCH
1039     {
1040 #ifdef CROSSGEN_COMPILE
1041         // for minimal impact we won't update hr for regular builds
1042         hr = GET_EXCEPTION()->GetHR();
1043         _ASSERTE(FAILED(hr));
1044         StackSString exceptionMessage;
1045         GET_EXCEPTION()->GetMessage(exceptionMessage);
1046         fprintf(stderr, "%S\n", exceptionMessage.GetUnicode());
1047 #endif // CROSSGEN_COMPILE
1048     }
1049     EX_END_CATCH(RethrowTerminalExceptionsWithInitCheck)
1050
1051     if (!g_fEEStarted) {
1052         if (g_fEEInit)
1053             g_fEEInit = false;
1054
1055         if (!FAILED(hr))
1056             hr = E_FAIL;
1057
1058         g_EEStartupStatus = hr;
1059     }
1060
1061     if (breakOnEELoad.val(CLRConfig::UNSUPPORTED_BreakOnEELoad) == 2)
1062     {
1063 #ifdef _DEBUG
1064         _ASSERTE(!"Done loading EE!");
1065 #else
1066         DebugBreak();
1067 #endif
1068     }
1069
1070 }
1071
1072 LONG FilterStartupException(PEXCEPTION_POINTERS p, PVOID pv)
1073 {
1074     CONTRACTL
1075     {
1076         NOTHROW;
1077         GC_NOTRIGGER;
1078         MODE_ANY;
1079         PRECONDITION(CheckPointer(p));
1080         PRECONDITION(CheckPointer(pv));
1081     } CONTRACTL_END;
1082
1083     g_EEStartupStatus = (HRESULT)p->ExceptionRecord->ExceptionInformation[0];
1084
1085     // Make sure we got a failure code in this case
1086     if (!FAILED(g_EEStartupStatus))
1087         g_EEStartupStatus = E_FAIL;
1088
1089     // Initializations has failed so reset the g_fEEInit flag.
1090     g_fEEInit = false;
1091
1092     if (p->ExceptionRecord->ExceptionCode == BOOTUP_EXCEPTION_COMPLUS)
1093     {
1094         // Don't ever handle the exception in a checked build
1095 #ifndef _DEBUG
1096         return EXCEPTION_EXECUTE_HANDLER;
1097 #endif
1098     }
1099
1100     return EXCEPTION_CONTINUE_SEARCH;
1101 }
1102
1103 // EEStartup is responcible for all the one time intialization of the runtime.  Some of the highlights of
1104 // what it does include
1105 //     * Creates the default and shared, appdomains. 
1106 //     * Loads mscorlib.dll and loads up the fundamental types (System.Object ...)
1107 // 
1108 // see code:EEStartup#TableOfContents for more on the runtime in general. 
1109 // see code:#EEShutdown for a analagous routine run during shutdown. 
1110 // 
1111 HRESULT EEStartup(COINITIEE fFlags)
1112 {
1113     // Cannot use normal contracts here because of the PAL_TRY.
1114     STATIC_CONTRACT_NOTHROW;
1115
1116     _ASSERTE(!g_fEEStarted && !g_fEEInit && SUCCEEDED (g_EEStartupStatus));
1117
1118     PAL_TRY(COINITIEE *, pfFlags, &fFlags)
1119     {
1120 #ifndef CROSSGEN_COMPILE
1121         InitializeClrNotifications();
1122 #ifdef FEATURE_PAL
1123         InitializeJITNotificationTable();
1124         DacGlobals::Initialize();
1125 #endif
1126 #endif // CROSSGEN_COMPILE
1127
1128         EEStartupHelper(*pfFlags);
1129     }
1130     PAL_EXCEPT_FILTER (FilterStartupException)
1131     {
1132         // The filter should have set g_EEStartupStatus to a failure HRESULT.
1133         _ASSERTE(FAILED(g_EEStartupStatus));
1134     }
1135     PAL_ENDTRY
1136
1137     return g_EEStartupStatus;
1138 }
1139
1140
1141 #ifndef CROSSGEN_COMPILE
1142
1143 #ifdef FEATURE_COMINTEROP
1144
1145 void InnerCoEEShutDownCOM()
1146 {
1147     CONTRACTL
1148     {
1149         THROWS;
1150         GC_TRIGGERS;
1151         MODE_ANY;
1152     } CONTRACTL_END;
1153
1154     static LONG AlreadyDone = -1;
1155
1156     if (g_fEEStarted != TRUE)
1157         return;
1158
1159     if (FastInterlockIncrement(&AlreadyDone) != 0)
1160         return;
1161
1162     g_fShutDownCOM = true;
1163
1164     // Release IJupiterGCMgr *
1165     RCWWalker::OnEEShutdown();
1166
1167     // Release all of the RCWs in all contexts in all caches.
1168     ReleaseRCWsInCaches(NULL);
1169
1170 #ifdef FEATURE_APPX    
1171     // Cleanup cached factory pointer in SynchronizationContextNative
1172     SynchronizationContextNative::Cleanup();
1173 #endif    
1174 }
1175
1176 // ---------------------------------------------------------------------------
1177 // %%Function: CoEEShutdownCOM()
1178 //
1179 // Parameters:
1180 //  none
1181 //
1182 // Returns:
1183 //  Nothing
1184 //
1185 // Description:
1186 //  COM Objects shutdown stuff should be done here
1187 // ---------------------------------------------------------------------------
1188 void STDMETHODCALLTYPE CoEEShutDownCOM()
1189 {
1190
1191     CONTRACTL
1192     {
1193         NOTHROW;
1194         GC_TRIGGERS;
1195         MODE_PREEMPTIVE;
1196         ENTRY_POINT;
1197     } CONTRACTL_END;
1198
1199     if (g_fEEStarted != TRUE)
1200         return;
1201
1202     HRESULT hr;
1203     BEGIN_EXTERNAL_ENTRYPOINT(&hr)
1204
1205     InnerCoEEShutDownCOM();
1206
1207     END_EXTERNAL_ENTRYPOINT;
1208
1209     // API doesn't allow us to communicate a failure HRESULT.  MDAs can
1210     // be enabled to catch failure inside CanRunManagedCode.
1211     // _ASSERTE(SUCCEEDED(hr));
1212 }
1213
1214 #endif // FEATURE_COMINTEROP
1215
1216 // ---------------------------------------------------------------------------
1217 // %%Function: ForceEEShutdown()
1218 //
1219 // Description: Force the EE to shutdown now.
1220 // 
1221 // Note: returns when sca is SCA_ReturnWhenShutdownComplete.
1222 // ---------------------------------------------------------------------------
1223 void ForceEEShutdown(ShutdownCompleteAction sca)
1224 {
1225     WRAPPER_NO_CONTRACT;
1226
1227     // Don't bother to take the lock for this case.
1228
1229     STRESS_LOG0(LF_STARTUP, INFO3, "EEShutdown invoked from ForceEEShutdown");
1230     EEPolicy::HandleExitProcess(sca);
1231 }
1232
1233 //---------------------------------------------------------------------------
1234 // %%Function: ExternalShutdownHelper
1235 //
1236 // Parameters:
1237 //  int exitCode :: process exit code
1238 //  ShutdownCompleteAction sca :: indicates whether ::ExitProcess() is
1239 //                                called or if the function returns.
1240 //
1241 // Returns:
1242 //  Nothing
1243 //
1244 // Description:
1245 // This is a helper shared by CorExitProcess and ShutdownRuntimeWithoutExiting 
1246 // which causes the runtime to shutdown after the appropriate checks. 
1247 // ---------------------------------------------------------------------------
1248 static void ExternalShutdownHelper(int exitCode, ShutdownCompleteAction sca)
1249 {
1250     CONTRACTL {
1251         NOTHROW;
1252         GC_TRIGGERS;
1253         MODE_ANY;
1254         ENTRY_POINT;
1255     } CONTRACTL_END;
1256
1257     CONTRACT_VIOLATION(GCViolation | ModeViolation);
1258
1259     if (g_fEEShutDown || !g_fEEStarted)
1260         return;
1261
1262     if (HasIllegalReentrancy())
1263     {
1264         return;
1265     }
1266     else
1267     if (!CanRunManagedCode())
1268     {
1269         return;
1270     }
1271
1272     // The exit code for the process is communicated in one of two ways.  If the
1273     // entrypoint returns an 'int' we take that.  Otherwise we take a latched
1274     // process exit code.  This can be modified by the app via System.SetExitCode().
1275     SetLatchedExitCode(exitCode);
1276
1277
1278     ForceEEShutdown(sca);
1279
1280     // @TODO: If we cannot run ManagedCode, BEGIN_EXTERNAL_ENTRYPOINT will skip
1281     // the shutdown.  We could call ::ExitProcess in that failure case, but that
1282     // would violate our hosting agreement.  We are supposed to go through EEPolicy::
1283     // HandleExitProcess().  Is this legal if !CanRunManagedCode()?
1284
1285 }
1286
1287 //---------------------------------------------------------------------------
1288 // %%Function: void STDMETHODCALLTYPE CorExitProcess(int exitCode)
1289 //
1290 // Parameters:
1291 //  int exitCode :: process exit code
1292 //
1293 // Returns:
1294 //  Nothing
1295 //
1296 // Description:
1297 //  COM Objects shutdown stuff should be done here
1298 // ---------------------------------------------------------------------------
1299 extern "C" void STDMETHODCALLTYPE CorExitProcess(int exitCode)
1300 {
1301     WRAPPER_NO_CONTRACT;
1302
1303     ExternalShutdownHelper(exitCode, SCA_ExitProcessWhenShutdownComplete);
1304 }
1305
1306 //---------------------------------------------------------------------------
1307 // %%Function: ShutdownRuntimeWithoutExiting
1308 //
1309 // Parameters:
1310 //  int exitCode :: process exit code
1311 //
1312 // Returns:
1313 //  Nothing
1314 //
1315 // Description:
1316 // This is a helper used only by the v4+ Shim to shutdown this runtime and
1317 // and return when the work has completed. It is exposed to the Shim via
1318 // GetCLRFunction.
1319 // ---------------------------------------------------------------------------
1320 void ShutdownRuntimeWithoutExiting(int exitCode)
1321 {
1322     WRAPPER_NO_CONTRACT;
1323
1324     ExternalShutdownHelper(exitCode, SCA_ReturnWhenShutdownComplete);
1325 }
1326
1327 //---------------------------------------------------------------------------
1328 // %%Function: IsRuntimeStarted
1329 //
1330 // Parameters:
1331 //  pdwStartupFlags: out parameter that is set to the startup flags if the
1332 //                   runtime is started.
1333 //
1334 // Returns:
1335 //  TRUE if the runtime has been started, FALSE otherwise.
1336 //
1337 // Description:
1338 // This is a helper used only by the v4+ Shim to determine if this runtime
1339 // has ever been started. It is exposed ot the Shim via GetCLRFunction.
1340 // ---------------------------------------------------------------------------
1341 BOOL IsRuntimeStarted(DWORD *pdwStartupFlags)
1342 {
1343     LIMITED_METHOD_CONTRACT;
1344
1345     if (pdwStartupFlags != NULL) // this parameter is optional
1346     {
1347         *pdwStartupFlags = 0;
1348     }
1349     return g_fEEStarted;
1350 }
1351
1352 static bool WaitForEndOfShutdown_OneIteration()
1353 {
1354     CONTRACTL{
1355         NOTHROW;
1356         GC_NOTRIGGER;
1357         MODE_PREEMPTIVE;
1358     } CONTRACTL_END;
1359
1360     // We are shutting down.  GC triggers does not have any effect now.
1361     CONTRACT_VIOLATION(GCViolation);
1362
1363     // If someone calls EEShutDown while holding OS loader lock, the thread we created for shutdown
1364     // won't start running.  This is a deadlock we can not fix.  Instead, we timeout and continue the 
1365     // current thread.
1366     DWORD timeout = GetEEPolicy()->GetTimeout(OPR_ProcessExit);
1367     timeout *= 2;
1368     ULONGLONG endTime = CLRGetTickCount64() + timeout;
1369     bool done = false;
1370
1371     EX_TRY
1372     {
1373         ULONGLONG curTime = CLRGetTickCount64();
1374         if (curTime > endTime)
1375         {
1376             done = true;
1377         }
1378         else
1379         {
1380 #ifdef PROFILING_SUPPORTED
1381             if (CORProfilerPresent())
1382             {
1383                 // A profiler is loaded, so just wait without timeout. This allows
1384                 // profilers to complete potentially lengthy post processing, without the
1385                 // CLR killing them off first. The Office team's server memory profiler,
1386                 // for example, does a lot of post-processing that can exceed the 80
1387                 // second imit we normally impose here. The risk of waiting without
1388                 // timeout is that, if there really is a deadlock, shutdown will hang.
1389                 // Since that will only happen if a profiler is loaded, that is a
1390                 // reasonable compromise
1391                 timeout = INFINITE;
1392             }
1393             else
1394 #endif //PROFILING_SUPPORTED
1395             {
1396                 timeout = static_cast<DWORD>(endTime - curTime);
1397             }
1398             DWORD status = g_pEEShutDownEvent->Wait(timeout,TRUE);
1399             if (status == WAIT_OBJECT_0 || status == WAIT_TIMEOUT)
1400             {
1401                 done = true;
1402             }
1403             else
1404             {
1405                 done = false;
1406             }
1407         }
1408     }
1409     EX_CATCH
1410     {
1411     }
1412     EX_END_CATCH(SwallowAllExceptions);
1413     return done;
1414 }
1415
1416 void WaitForEndOfShutdown()
1417 {
1418     CONTRACTL{
1419         NOTHROW;
1420         GC_NOTRIGGER;
1421         MODE_PREEMPTIVE;
1422     } CONTRACTL_END;
1423
1424     // We are shutting down.  GC triggers does not have any effect now.
1425     CONTRACT_VIOLATION(GCViolation);
1426
1427     Thread *pThread = GetThread();
1428     // After a thread is blocked in WaitForEndOfShutdown, the thread should not enter runtime again,
1429     // and block at WaitForEndOfShutdown again.
1430     if (pThread)
1431     {
1432         _ASSERTE(!pThread->HasThreadStateNC(Thread::TSNC_BlockedForShutdown));
1433         pThread->SetThreadStateNC(Thread::TSNC_BlockedForShutdown);
1434     }
1435
1436     while (!WaitForEndOfShutdown_OneIteration());
1437 }
1438
1439 // ---------------------------------------------------------------------------
1440 // Function: EEShutDownHelper(BOOL fIsDllUnloading)
1441 //
1442 // The real meat of shut down happens here.  See code:#EEShutDown for details, including
1443 // what fIsDllUnloading means.
1444 //
1445 void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
1446 {
1447     CONTRACTL
1448     {
1449         NOTHROW;
1450         GC_TRIGGERS;
1451         MODE_ANY;
1452     } CONTRACTL_END;
1453
1454     // Used later for a callback.
1455     CEEInfo ceeInf;
1456
1457     if(fIsDllUnloading)
1458     {
1459         ETW::EnumerationLog::ProcessShutdown();
1460     }
1461
1462 #ifdef FEATURE_PERFTRACING
1463     // Shutdown the event pipe.
1464     EventPipe::Shutdown();
1465 #endif // FEATURE_PERFTRACING
1466
1467 #if defined(FEATURE_COMINTEROP)
1468     // Get the current thread.
1469     Thread * pThisThread = GetThread();
1470 #endif
1471
1472     // If the process is detaching then set the global state.
1473     // This is used to get around FreeLibrary problems.
1474     if(fIsDllUnloading)
1475         g_fProcessDetach = true;
1476
1477     if (IsDbgHelperSpecialThread())
1478     {
1479         // Our debugger helper thread does not allow Thread object to be set up.
1480         // We should not run shutdown code on debugger helper thread.
1481         _ASSERTE(fIsDllUnloading);
1482         return;
1483     }
1484
1485 #ifdef _DEBUG
1486     // stop API thread stress
1487     APIThreadStress::SetThreadStressCount(0);
1488 #endif
1489
1490     STRESS_LOG1(LF_STARTUP, LL_INFO10, "EEShutDown entered unloading = %d", fIsDllUnloading);
1491
1492 #ifdef _DEBUG
1493     if (_DbgBreakCount)
1494         _ASSERTE(!"An assert was hit before EE Shutting down");
1495
1496     if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_BreakOnEEShutdown))
1497         _ASSERTE(!"Shutting down EE!");
1498 #endif
1499
1500 #ifdef DEBUGGING_SUPPORTED
1501     // This is a nasty, terrible, horrible thing. If we're being
1502     // called from our DLL main, then the odds are good that our DLL
1503     // main has been called as the result of some person calling
1504     // ExitProcess. That rips the debugger helper thread away very
1505     // ungracefully. This check is an attempt to recognize that case
1506     // and avoid the impending hang when attempting to get the helper
1507     // thread to do things for us.
1508     if ((g_pDebugInterface != NULL) && g_fProcessDetach)
1509         g_pDebugInterface->EarlyHelperThreadDeath();
1510 #endif // DEBUGGING_SUPPORTED
1511
1512     BOOL fFinalizeOK = FALSE;
1513
1514     EX_TRY
1515     {
1516         ClrFlsSetThreadType(ThreadType_Shutdown);
1517
1518         if (fIsDllUnloading && g_fEEShutDown)
1519         {
1520             // I'm in the final shutdown and the first part has already been run.
1521             goto part2;
1522         }
1523
1524         // Indicate the EE is the shut down phase.
1525         g_fEEShutDown |= ShutDown_Start;
1526
1527         fFinalizeOK = TRUE;
1528
1529         // Terminate the BBSweep thread
1530         g_BBSweep.ShutdownBBSweepThread();
1531
1532         // We perform the final GC only if the user has requested it through the GC class.
1533         // We should never do the final GC for a process detach
1534         if (!g_fProcessDetach && !g_fFastExitProcess)
1535         {
1536             g_fEEShutDown |= ShutDown_Finalize1;
1537             FinalizerThread::EnableFinalization();
1538             fFinalizeOK = FinalizerThread::FinalizerThreadWatchDog();
1539         }
1540
1541
1542         // Ok.  Let's stop the EE.
1543         if (!g_fProcessDetach)
1544         {
1545             // Convert key locks into "shutdown" mode. A lock in shutdown mode means:
1546             // - Only the finalizer/helper/shutdown threads will be able to take the the lock.
1547             // - Any other thread that tries takes it will just get redirected to an endless WaitForEndOfShutdown().
1548             //
1549             // The only managed code that should run after this point is the finalizers for shutdown.
1550             // We convert locks needed for running + debugging such finalizers. Since such locks may need to be
1551             // juggled between multiple threads (finalizer/helper/shutdown), no single thread can take the
1552             // lock and not give it up.
1553             //
1554             // Each lock needs its own shutdown flag (they can't all be converted at once).
1555             // To avoid deadlocks, we need to convert locks in order of crst level (biggest first).
1556
1557             // Notify the debugger that we're going into shutdown to convert debugger-lock to shutdown.
1558             if (g_pDebugInterface != NULL)
1559             {
1560                 g_pDebugInterface->LockDebuggerForShutdown();
1561             }
1562
1563             // This call will convert the ThreadStoreLock into "shutdown" mode, just like the debugger lock above.
1564             g_fEEShutDown |= ShutDown_Finalize2;
1565             if (fFinalizeOK)
1566             {
1567                 fFinalizeOK = FinalizerThread::FinalizerThreadWatchDog();
1568             }
1569
1570             if (!fFinalizeOK)
1571             {
1572                 // One of the calls to FinalizerThreadWatchDog failed due to timeout, so we need to prevent
1573                 // any thread from running managed code, including the finalizer.
1574                 ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_FOR_SHUTDOWN);
1575                 g_fSuspendOnShutdown = TRUE;
1576                 g_fSuspendFinalizerOnShutdown = TRUE;
1577                 ThreadStore::TrapReturningThreads(TRUE);
1578                 ThreadSuspend::RestartEE(FALSE, TRUE);
1579             }
1580         }
1581
1582 #ifdef FEATURE_EVENT_TRACE
1583         // Flush managed object allocation logging data.
1584         // We do this after finalization is complete and returning threads have been trapped, so that
1585         // no there will be no more managed allocations and no more GCs which will manipulate the
1586         // allocation sampling data structures.
1587         ETW::TypeSystemLog::FlushObjectAllocationEvents();
1588 #endif // FEATURE_EVENT_TRACE
1589
1590 #ifdef FEATURE_PERFMAP
1591         // Flush and close the perf map file.
1592         PerfMap::Destroy();
1593 #endif
1594
1595 #ifdef FEATURE_PREJIT
1596         {
1597             // If we're doing basic block profiling, we need to write the log files to disk.
1598
1599             static BOOL fIBCLoggingDone = FALSE;
1600             if (!fIBCLoggingDone)
1601             {
1602                 if (g_IBCLogger.InstrEnabled())
1603                 {
1604                     Thread * pThread = GetThread();
1605                     ThreadLocalIBCInfo* pInfo = pThread->GetIBCInfo();
1606
1607                     // Acquire the Crst lock before creating the IBCLoggingDisabler object.
1608                     // Only one thread at a time can be processing an IBC logging event.
1609                     CrstHolder lock(IBCLogger::GetSync());
1610                     {
1611                         IBCLoggingDisabler disableLogging( pInfo );  // runs IBCLoggingDisabler::DisableLogging
1612                         
1613                         CONTRACT_VIOLATION(GCViolation);
1614                         Module::WriteAllModuleProfileData(true);
1615                     }
1616                 }
1617                 fIBCLoggingDone = TRUE;
1618             }
1619         }
1620
1621 #endif // FEATURE_PREJIT
1622
1623         ceeInf.JitProcessShutdownWork();  // Do anything JIT-related that needs to happen at shutdown.
1624
1625 #ifdef FEATURE_INTERPRETER
1626         // This will check a flag and do nothing if not enabled.
1627         Interpreter::PrintPostMortemData();
1628 #endif // FEATURE_INTERPRETER
1629         
1630         FastInterlockExchange((LONG*)&g_fForbidEnterEE, TRUE);
1631
1632         if (g_fProcessDetach)
1633         {
1634             ThreadStore::TrapReturningThreads(TRUE);
1635         }
1636
1637         if (!g_fProcessDetach && !fFinalizeOK)
1638         {
1639             goto lDone;
1640         }
1641
1642 #ifdef PROFILING_SUPPORTED
1643         // If profiling is enabled, then notify of shutdown first so that the
1644         // profiler can make any last calls it needs to.  Do this only if we
1645         // are not detaching
1646
1647         if (CORProfilerPresent())
1648         {
1649             // If EEShutdown is not being called due to a ProcessDetach event, so
1650             // the profiler should still be present
1651             if (!g_fProcessDetach)
1652             {
1653                 BEGIN_PIN_PROFILER(CORProfilerPresent());
1654                 GCX_PREEMP();
1655                 g_profControlBlock.pProfInterface->Shutdown();
1656                 END_PIN_PROFILER();
1657             }
1658
1659             g_fEEShutDown |= ShutDown_Profiler;
1660
1661             // Free the interface objects.
1662             ProfilingAPIUtility::TerminateProfiling();
1663         }
1664 #endif // PROFILING_SUPPORTED
1665
1666
1667 #ifdef _DEBUG
1668         g_fEEShutDown |= ShutDown_SyncBlock;
1669 #endif
1670         {
1671             // From here on out we might call stuff that violates mode requirements, but we ignore these
1672             // because we are shutting down.
1673             CONTRACT_VIOLATION(ModeViolation);
1674
1675 #ifdef FEATURE_COMINTEROP
1676             // We need to call CoUninitialize in part one to ensure orderly shutdown of COM dlls.
1677             if (!g_fFastExitProcess)
1678             {
1679                 if (pThisThread!= NULL)
1680                 {
1681                     pThisThread->CoUninitialize();
1682                 }
1683             }
1684 #endif // FEATURE_COMINTEROP
1685         }
1686
1687         // This is the end of Part 1.
1688
1689 part2:
1690         // If process shutdown is in progress and Crst locks to be used in shutdown phase 2
1691         // are already in use, then skip phase 2. This will happen only when those locks
1692         // are orphaned. In Vista, the penalty for attempting to enter such locks is 
1693         // instant process termination.
1694         if (g_fProcessDetach)
1695         {
1696             // The assert below is a bit too aggresive and has generally brought cases that have been race conditions
1697             // and not easily reproed to validate a bug. A typical race scenario is when there are two threads,
1698             // T1 and T2, with T2 having taken a lock (e.g. SystemDomain lock), the OS terminates
1699             // T2 for some reason. Later, when we enter the shutdown thread, we would assert on such
1700             // a lock leak, but there is not much we can do since the OS wont notify us prior to thread 
1701             // termination. And this is not even a user bug.
1702             //
1703             // Converting it to a STRESS LOG to reduce noise, yet keep things in radar if they need
1704             // to be investigated.
1705             //_ASSERTE_MSG(g_ShutdownCrstUsageCount == 0, "Some locks to be taken during shutdown may already be orphaned!");
1706             if (g_ShutdownCrstUsageCount > 0)
1707             {
1708                 STRESS_LOG0(LF_STARTUP, LL_INFO10, "Some locks to be taken during shutdown may already be orphaned!");
1709                 goto lDone;
1710             }
1711         }
1712
1713         {
1714             CONTRACT_VIOLATION(ModeViolation);
1715
1716             // On the new plan, we only do the tear-down under the protection of the loader
1717             // lock -- after the OS has stopped all other threads.
1718             if (fIsDllUnloading && (g_fEEShutDown & ShutDown_Phase2) == 0)
1719             {
1720                 g_fEEShutDown |= ShutDown_Phase2;
1721
1722                 // Shutdown finalizer before we suspend all background threads. Otherwise we
1723                 // never get to finalize anything. Obviously.
1724
1725 #ifdef _DEBUG
1726                 if (_DbgBreakCount)
1727                     _ASSERTE(!"An assert was hit After Finalizer run");
1728 #endif
1729
1730                 // No longer process exceptions
1731                 g_fNoExceptions = true;
1732
1733                 //
1734                 // Remove our global exception filter. If it was NULL before, we want it to be null now.
1735                 //
1736                 UninstallUnhandledExceptionFilter();
1737
1738                 // <TODO>@TODO: This does things which shouldn't occur in part 2.  Namely,
1739                 // calling managed dll main callbacks (AppDomain::SignalProcessDetach), and
1740                 // RemoveAppDomainFromIPC.
1741                 //
1742                 // (If we move those things to earlier, this can be called only if fShouldWeCleanup.)</TODO>
1743                 if (!g_fFastExitProcess)
1744                 {
1745                     SystemDomain::DetachBegin();
1746                 }
1747
1748
1749 #ifdef DEBUGGING_SUPPORTED
1750                 // Terminate the debugging services.
1751                 TerminateDebugger();
1752 #endif // DEBUGGING_SUPPORTED
1753
1754                 StubManager::TerminateStubManagers();
1755
1756 #ifdef FEATURE_INTERPRETER
1757                 Interpreter::Terminate();
1758 #endif // FEATURE_INTERPRETER
1759
1760 #ifdef SHOULD_WE_CLEANUP
1761                 if (!g_fFastExitProcess)
1762                 {
1763                     GCHandleUtilities::GetGCHandleManager()->Shutdown();
1764                 }
1765 #endif /* SHOULD_WE_CLEANUP */
1766
1767                 //@TODO: find the right place for this
1768                 VirtualCallStubManager::UninitStatic();
1769
1770 #ifdef ENABLE_PERF_LOG
1771                 PerfLog::PerfLogDone();
1772 #endif //ENABLE_PERF_LOG
1773
1774                 Frame::Term();
1775
1776                 if (!g_fFastExitProcess)
1777                 {
1778                     SystemDomain::DetachEnd();
1779                 }
1780
1781                 // Unregister our vectored exception and continue handlers from the OS.
1782                 // This will ensure that if any other DLL unload (after ours) has an exception,
1783                 // we wont attempt to process that exception (which could lead to various
1784                 // issues including AV in the runtime).
1785                 //
1786                 // This should be done:
1787                 //
1788                 // 1) As the last action during the shutdown so that any unexpected AVs
1789                 //    in the runtime during shutdown do result in FailFast in VEH.
1790                 //
1791                 // 2) Only when the runtime is processing DLL_PROCESS_DETACH. 
1792                 CLRRemoveVectoredHandlers();
1793
1794 #if USE_DISASSEMBLER
1795                 Disassembler::StaticClose();
1796 #endif // USE_DISASSEMBLER
1797
1798 #ifdef _DEBUG
1799                 if (_DbgBreakCount)
1800                     _ASSERTE(!"EE Shutting down after an assert");
1801 #endif
1802
1803
1804 #ifdef LOGGING
1805                 extern unsigned FcallTimeHist[11];
1806 #endif
1807                 LOG((LF_STUBS, LL_INFO10, "FcallHist %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d\n",
1808                     FcallTimeHist[0], FcallTimeHist[1], FcallTimeHist[2], FcallTimeHist[3],
1809                     FcallTimeHist[4], FcallTimeHist[5], FcallTimeHist[6], FcallTimeHist[7],
1810                     FcallTimeHist[8], FcallTimeHist[9], FcallTimeHist[10]));
1811
1812                 WriteJitHelperCountToSTRESSLOG();
1813
1814                 STRESS_LOG0(LF_STARTUP, LL_INFO10, "EEShutdown shutting down logging");
1815
1816 #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
1817                 if (!g_fFastExitProcess)
1818                     StressLog::Terminate(TRUE);
1819 #endif
1820
1821                 if (g_pConfig != NULL)
1822                     g_pConfig->Cleanup();
1823
1824 #ifdef LOGGING
1825                 ShutdownLogging();
1826 #endif
1827             }
1828         }    
1829
1830     lDone: ;
1831     }
1832     EX_CATCH
1833     {
1834     }
1835     EX_END_CATCH(SwallowAllExceptions);
1836
1837     ClrFlsClearThreadType(ThreadType_Shutdown);
1838     if (!g_fProcessDetach)
1839     {
1840         g_pEEShutDownEvent->Set();
1841     }
1842 }
1843
1844
1845 #ifdef FEATURE_COMINTEROP
1846
1847 BOOL IsThreadInSTA()
1848 {
1849     CONTRACTL
1850     {
1851         NOTHROW;
1852         GC_TRIGGERS;
1853         MODE_ANY;
1854     }
1855     CONTRACTL_END;
1856
1857     // If ole32.dll is not loaded
1858     if (WszGetModuleHandle(W("ole32.dll")) == NULL)
1859     {
1860         return FALSE;
1861     }
1862
1863     BOOL fInSTA = TRUE;
1864     // To be conservative, check if finalizer thread is around
1865     EX_TRY
1866     {
1867         Thread *pFinalizerThread = FinalizerThread::GetFinalizerThread();
1868         if (!pFinalizerThread || pFinalizerThread->Join(0, FALSE) != WAIT_TIMEOUT)
1869         {
1870             fInSTA = FALSE;
1871         }
1872     }
1873     EX_CATCH
1874     {
1875     }
1876     EX_END_CATCH(SwallowAllExceptions);
1877
1878     if (!fInSTA)
1879     {
1880         return FALSE;
1881     }
1882
1883     THDTYPE type;
1884     HRESULT hr = S_OK;
1885
1886     hr = GetCurrentThreadTypeNT5(&type);
1887     if (hr == S_OK)
1888     {
1889         fInSTA = (type == THDTYPE_PROCESSMESSAGES) ? TRUE : FALSE;
1890
1891         // If we get back THDTYPE_PROCESSMESSAGES, we are guaranteed to
1892         // be an STA thread. If not, we are an MTA thread, however
1893         // we can't know if the thread has been explicitly set to MTA
1894         // (via a call to CoInitializeEx) or if it has been implicitly
1895         // made MTA (if it hasn't been CoInitializeEx'd but CoInitialize
1896         // has already been called on some other thread in the process.
1897     }
1898     else
1899     {
1900         // CoInitialize hasn't been called in the process yet so assume the current thread
1901         // is MTA. 
1902         fInSTA = FALSE;
1903     }
1904
1905     return fInSTA;
1906 }
1907 #endif
1908
1909 static LONG s_ActiveShutdownThreadCount = 0;
1910
1911 // ---------------------------------------------------------------------------
1912 // Function: EEShutDownProcForSTAThread(LPVOID lpParameter)
1913 //
1914 // Parameters:
1915 //    LPVOID lpParameter: unused
1916 //
1917 // Description:
1918 //    When EEShutDown decides that the shut down logic must occur on another thread,
1919 //    EEShutDown creates a new thread, and this function acts as the thread proc. See
1920 //    code:#STAShutDown for details.
1921 // 
1922 DWORD WINAPI EEShutDownProcForSTAThread(LPVOID lpParameter)
1923 {
1924     ClrFlsSetThreadType(ThreadType_ShutdownHelper);
1925
1926     EEShutDownHelper(FALSE);
1927     for (int i = 0; i < 10; i ++)
1928     {
1929         if (s_ActiveShutdownThreadCount)
1930         {
1931             return 0;
1932         }
1933         __SwitchToThread(20, CALLER_LIMITS_SPINNING);
1934     }
1935
1936     EPolicyAction action = GetEEPolicy()->GetDefaultAction(OPR_ProcessExit, NULL);
1937     if (action < eRudeExitProcess)
1938     {
1939         action = eRudeExitProcess;
1940     }
1941
1942     UINT exitCode = GetLatchedExitCode();
1943     EEPolicy::HandleExitProcessFromEscalation(action, exitCode);
1944
1945     return 0;
1946 }
1947
1948 // ---------------------------------------------------------------------------
1949 // #EEShutDown
1950 // 
1951 // Function: EEShutDown(BOOL fIsDllUnloading)
1952 //
1953 // Parameters:
1954 //    BOOL fIsDllUnloading:
1955 //         * TRUE => Called from CLR's DllMain (DLL_PROCESS_DETACH). Not safe point for
1956 //             full cleanup
1957 //         * FALSE => Called some other way (e.g., end of the CLR's main). Safe to do
1958 //             full cleanup.
1959 //
1960 // Description:
1961 // 
1962 //     All ee shutdown stuff should be done here. EEShutDown is generally called in one
1963 //     of two ways:
1964 //     * 1. From code:EEPolicy::HandleExitProcess (via HandleExitProcessHelper), with
1965 //         fIsDllUnloading == FALSE. This code path is typically invoked by the CLR's
1966 //         main just falling through to the end. Full cleanup can be performed when
1967 //         EEShutDown is called this way.
1968 //     * 2. From CLR's DllMain (DLL_PROCESS_DETACH), with fIsDllUnloading == TRUE. When
1969 //         called this way, much cleanup code is unsafe to run, and is thus skipped.
1970 // 
1971 // Actual shut down logic is factored out to EEShutDownHelper which may be called
1972 // directly by EEShutDown, or indirectly on another thread (see code:#STAShutDown).
1973 //
1974 // In order that callees may also know the value of fIsDllUnloading, EEShutDownHelper
1975 // sets g_fProcessDetach = fIsDllUnloading, and g_fProcessDetach may then be retrieved
1976 // via code:IsAtProcessExit.
1977 //
1978 // NOTE 1: Actually, g_fProcessDetach is set to TRUE if fIsDllUnloading is TRUE. But
1979 // g_fProcessDetach doesn't appear to be explicitly set to FALSE. (Apparently
1980 // g_fProcessDetach is implicitly initialized to FALSE as clr.dll is loaded.)
1981 // 
1982 // NOTE 2: EEDllMain(DLL_PROCESS_DETACH) already sets g_fProcessDetach to TRUE, so it
1983 // appears EEShutDownHelper doesn't have to.
1984 // 
1985 void STDMETHODCALLTYPE EEShutDown(BOOL fIsDllUnloading)
1986 {
1987     CONTRACTL {
1988         NOTHROW;
1989         GC_TRIGGERS;
1990         MODE_ANY;
1991         PRECONDITION(g_fEEStarted);
1992     } CONTRACTL_END;
1993
1994     // If we have not started runtime successfully, it is not safe to call EEShutDown.
1995     if (!g_fEEStarted || g_fFastExitProcess == 2)
1996     {
1997         return;
1998     }
1999
2000     // We only do the first part of the shutdown once.
2001     static LONG OnlyOne = -1;
2002
2003     if (!fIsDllUnloading)
2004     {
2005         if (FastInterlockIncrement(&OnlyOne) != 0)
2006         {
2007             // I'm in a regular shutdown -- but another thread got here first.
2008             // It's a race if I return from here -- I'll call ExitProcess next, and
2009             // rip things down while the first thread is half-way through a
2010             // nice cleanup.  Rather than do that, I should just wait until the
2011             // first thread calls ExitProcess().  I'll die a nice death when that
2012             // happens.
2013             GCX_PREEMP_NO_DTOR();
2014             WaitForEndOfShutdown();
2015             return;
2016         }
2017
2018 #ifdef FEATURE_MULTICOREJIT
2019         if (!AppX::IsAppXProcess()) // When running as Appx, make the delayed timer driven writing be the only option
2020         {
2021             MulticoreJitManager::StopProfileAll();
2022         }
2023 #endif
2024     }
2025
2026 #ifdef FEATURE_COMINTEROP
2027     if (!fIsDllUnloading && CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_FinalizeOnShutdown) && IsThreadInSTA())
2028     {
2029         // #STAShutDown
2030         // 
2031         // During shutdown, we may need to release STA interface on the shutdown thread.
2032         // It is possible that the shutdown thread may deadlock. During shutdown, all
2033         // threads are blocked, except the shutdown thread and finalizer thread. If a
2034         // lock is held by one of these suspended threads, it can deadlock the process if
2035         // the shutdown thread tries to enter the lock. To mitigate this risk, create
2036         // another thread (B) to do shutdown activities (i.e., EEShutDownHelper), while
2037         // this thread (A) waits. If B deadlocks, A will time out and immediately return
2038         // from EEShutDown. A will then eventually call the OS's ExitProcess, which will
2039         // kill the deadlocked thread (and all other threads).
2040         // 
2041         // Many Windows Forms-based apps will also execute the code below to shift shut
2042         // down logic to a separate thread, even if they don't use COM objects. Reason
2043         // being that they will typically use a main UI thread to pump all Windows
2044         // messages (including messages that facilitate cross-thread COM calls to STA COM
2045         // objects), and will set that thread up as an STA thread just in case there are
2046         // such cross-thread COM calls to contend with. In fact, when you use VS's
2047         // File.New.Project to make a new Windows Forms project, VS will mark Main() with
2048         // [STAThread]
2049         DWORD thread_id = 0;
2050         if (CreateThread(NULL,0,EEShutDownProcForSTAThread,NULL,0,&thread_id))
2051         {
2052             GCX_PREEMP_NO_DTOR();
2053
2054             ClrFlsSetThreadType(ThreadType_Shutdown);
2055             WaitForEndOfShutdown();
2056             FastInterlockIncrement(&s_ActiveShutdownThreadCount);
2057             ClrFlsClearThreadType(ThreadType_Shutdown);
2058         }
2059     }
2060     else
2061         // Otherwise, this thread calls EEShutDownHelper directly.  First switch to
2062         // cooperative mode if this is a managed thread
2063 #endif
2064     if (GetThread())
2065     {
2066         GCX_COOP();
2067         EEShutDownHelper(fIsDllUnloading);
2068         if (!fIsDllUnloading)
2069         {
2070             FastInterlockIncrement(&s_ActiveShutdownThreadCount);
2071         }
2072     }
2073     else
2074     {
2075         EEShutDownHelper(fIsDllUnloading);
2076         if (!fIsDllUnloading)
2077         {
2078             FastInterlockIncrement(&s_ActiveShutdownThreadCount);
2079         }
2080     }
2081 }
2082
2083 // ---------------------------------------------------------------------------
2084 // %%Function: IsRuntimeActive()
2085 //
2086 // Parameters:
2087 //  none
2088 //
2089 // Returns:
2090 //  TRUE or FALSE
2091 //
2092 // Description: Indicates if the runtime is active or not. "Active" implies
2093 //              that the runtime has started and is in a position to run
2094 //              managed code. If either of these conditions are false, the
2095 //              function return FALSE.
2096 //          
2097 //              Why couldnt we add !g_fEEStarted check in CanRunManagedCode?
2098 //
2099 // 
2100 //              ExecuteDLL in ceemain.cpp could start the runtime 
2101 //             (due to DLL_PROCESS_ATTACH) after invoking CanRunManagedCode. 
2102 //              If the function were to be modified, then this scenario could fail. 
2103 //              Hence, I have built over CanRunManagedCode in IsRuntimeActive.
2104
2105 // ---------------------------------------------------------------------------
2106 BOOL IsRuntimeActive()
2107 {
2108     // If the runtime has started AND we can run managed code,
2109     // then runtime is considered "active".
2110     BOOL fCanRunManagedCode = CanRunManagedCode();
2111     return (g_fEEStarted && fCanRunManagedCode);
2112 }
2113
2114 // ---------------------------------------------------------------------------
2115 // %%Function: CanRunManagedCode()
2116 //
2117 // Parameters:
2118 //  none
2119 //
2120 // Returns:
2121 //  true or false
2122 //
2123 // Description: Indicates if one is currently allowed to run managed code.
2124 // ---------------------------------------------------------------------------
2125 NOINLINE BOOL CanRunManagedCodeRare(LoaderLockCheck::kind checkKind, HINSTANCE hInst /*= 0*/)
2126 {
2127     CONTRACTL {
2128         NOTHROW;
2129         if (checkKind == LoaderLockCheck::ForMDA) { GC_TRIGGERS; } else { GC_NOTRIGGER; }; // because of the CustomerDebugProbe
2130         MODE_ANY;
2131     } CONTRACTL_END;
2132
2133     // If we are shutting down the runtime, then we cannot run code.
2134     if (g_fForbidEnterEE)
2135         return FALSE;
2136
2137     // If pre-loaded objects are not present, then no way.
2138     if (g_pPreallocatedOutOfMemoryException == NULL)
2139         return FALSE;
2140
2141     // If we are finaling live objects or processing ExitProcess event,
2142     // we can not allow managed method to run unless the current thread
2143     // is the finalizer thread
2144     if ((g_fEEShutDown & ShutDown_Finalize2) && !FinalizerThread::IsCurrentThreadFinalizer())
2145         return FALSE;
2146
2147 #if defined(FEATURE_COMINTEROP) && defined(MDA_SUPPORTED)
2148     if ((checkKind == LoaderLockCheck::ForMDA) && (NULL == MDA_GET_ASSISTANT(LoaderLock))) 
2149         return TRUE;
2150
2151     if (checkKind == LoaderLockCheck::None)
2152         return TRUE;
2153
2154     // If we are checking whether the OS loader lock is held by the current thread, then
2155     // it better not be.  Note that ShouldCheckLoaderLock is a cached test for whether
2156     // we are checking this probe.  So we can call AuxUlibIsDLLSynchronizationHeld before
2157     // verifying that the probe is still enabled.
2158     //
2159     // What's the difference between ignoreLoaderLock & ShouldCheckLoaderLock?
2160     // ShouldCheckLoaderLock is a process-wide flag.  In a few places where we
2161     // *know* we are in the loader lock but haven't quite reached the dangerous
2162     // point, we call CanRunManagedCode suppressing/deferring this check.
2163     BOOL IsHeld;
2164
2165     if (ShouldCheckLoaderLock(FALSE) &&
2166         AuxUlibIsDLLSynchronizationHeld(&IsHeld) &&
2167         IsHeld)
2168     {
2169         if (checkKind == LoaderLockCheck::ForMDA)
2170         {
2171             MDA_TRIGGER_ASSISTANT(LoaderLock, ReportViolation(hInst));
2172         }
2173         else
2174         {
2175             return FALSE;
2176         }
2177     }
2178 #endif // defined(FEATURE_COMINTEROP) && defined(MDA_SUPPORTED)
2179
2180     return TRUE;
2181 }
2182
2183 #include <optsmallperfcritical.h>
2184 BOOL CanRunManagedCode(LoaderLockCheck::kind checkKind, HINSTANCE hInst /*= 0*/)
2185 {
2186     CONTRACTL {
2187         NOTHROW;
2188         if (checkKind == LoaderLockCheck::ForMDA) { GC_TRIGGERS; } else { GC_NOTRIGGER; }; // because of the CustomerDebugProbe
2189         MODE_ANY;
2190     } CONTRACTL_END;
2191
2192     // Special-case the common success cases
2193     //  (Try not to make any calls here so that we don't have to spill our incoming arg regs)
2194     if (!g_fForbidEnterEE 
2195         && (g_pPreallocatedOutOfMemoryException != NULL)
2196         && !(g_fEEShutDown & ShutDown_Finalize2)
2197         && (((checkKind == LoaderLockCheck::ForMDA) 
2198 #ifdef MDA_SUPPORTED
2199              && (NULL == MDA_GET_ASSISTANT(LoaderLock))
2200 #endif // MDA_SUPPORTED
2201             ) || (checkKind == LoaderLockCheck::None)))
2202     {
2203         return TRUE;
2204     }
2205
2206     // Then call a helper for everything else.
2207     return CanRunManagedCodeRare(checkKind, hInst);
2208 }
2209 #include <optdefault.h>
2210
2211
2212 // ---------------------------------------------------------------------------
2213 // %%Function: CoInitializeEE(DWORD fFlags)
2214 //
2215 // Parameters:
2216 //  fFlags                  - Initialization flags for the engine.  See the
2217 //                              COINITIEE enumerator for valid values.
2218 //
2219 // Returns:
2220 //  Nothing
2221 //
2222 // Description:
2223 //  Initializes the EE if it hasn't already been initialized. This function
2224 //  no longer maintains a ref count since the EE doesn't support being
2225 //  unloaded and re-loaded. It simply ensures the EE has been started.
2226 // ---------------------------------------------------------------------------
2227 HRESULT STDAPICALLTYPE CoInitializeEE(DWORD fFlags)
2228 {
2229     CONTRACTL
2230     {
2231         NOTHROW;
2232         GC_TRIGGERS;
2233         MODE_PREEMPTIVE;
2234     }
2235     CONTRACTL_END;
2236
2237     HRESULT hr = S_OK;
2238     BEGIN_ENTRYPOINT_NOTHROW;
2239     hr = InitializeEE((COINITIEE)fFlags);
2240     END_ENTRYPOINT_NOTHROW;
2241
2242     return hr;
2243 }
2244
2245 // ---------------------------------------------------------------------------
2246 // %%Function: CoUninitializeEE
2247 //
2248 // Parameters:
2249 //  BOOL fIsDllUnloading :: is it safe point for full cleanup
2250 //
2251 // Returns:
2252 //  Nothing
2253 //
2254 // Description:
2255 //  Must be called by client on shut down in order to free up the system.
2256 // ---------------------------------------------------------------------------
2257 void STDAPICALLTYPE CoUninitializeEE(BOOL fIsDllUnloading)
2258 {
2259     LIMITED_METHOD_CONTRACT;
2260     //BEGIN_ENTRYPOINT_VOIDRET;
2261
2262     // This API is unfortunately publicly exported so we cannot get rid
2263     // of it. However since the EE doesn't currently support being unloaded
2264     // and re-loaded, it is useless to do any ref counting here or to pretend
2265     // to unload it. The proper way to shutdown the EE is to call CorExitProcess.
2266     //END_ENTRYPOINT_VOIDRET;
2267
2268 }
2269
2270 //*****************************************************************************
2271 BOOL ExecuteDLL_ReturnOrThrow(HRESULT hr, BOOL fFromThunk)
2272 {
2273     CONTRACTL {
2274         if (fFromThunk) THROWS; else NOTHROW;
2275         WRAPPER(GC_TRIGGERS);
2276         MODE_ANY;
2277     } CONTRACTL_END;
2278
2279     // If we have a failure result, and we're called from a thunk,
2280     // then we need to throw an exception to communicate the error.
2281     if (FAILED(hr) && fFromThunk)
2282     {
2283         COMPlusThrowHR(hr);
2284     }
2285     return SUCCEEDED(hr);
2286 }
2287
2288 //
2289 // Initialize the Garbage Collector
2290 //
2291
2292 void InitializeGarbageCollector()
2293 {
2294     CONTRACTL{
2295         THROWS;
2296         GC_TRIGGERS;
2297         MODE_ANY;
2298     } CONTRACTL_END;
2299
2300     HRESULT hr;
2301
2302     // Build the special Free Object used by the Generational GC
2303     _ASSERT(g_pFreeObjectMethodTable == NULL);
2304     g_pFreeObjectMethodTable = (MethodTable *) new BYTE[sizeof(MethodTable)];
2305     ZeroMemory(g_pFreeObjectMethodTable, sizeof(MethodTable));
2306
2307     // As the flags in the method table indicate there are no pointers
2308     // in the object, there is no gc descriptor, and thus no need to adjust
2309     // the pointer to skip the gc descriptor.
2310
2311     g_pFreeObjectMethodTable->SetBaseSize(ARRAYBASE_BASESIZE);
2312     g_pFreeObjectMethodTable->SetComponentSize(1);
2313
2314     hr = GCHeapUtilities::LoadAndInitialize();
2315     if (hr != S_OK)
2316     {
2317         ThrowHR(hr);
2318     }
2319
2320     // Apparently the Windows linker removes global variables if they are never
2321     // read from, which is a problem for g_gcDacGlobals since it's expected that
2322     // only the DAC will read from it. This forces the linker to include
2323     // g_gcDacGlobals.
2324     volatile void* _dummy = g_gcDacGlobals;
2325 }
2326
2327 /*****************************************************************************/
2328 /* This is here only so that if we get an exception we stop before we catch it */
2329 LONG DllMainFilter(PEXCEPTION_POINTERS p, PVOID pv)
2330 {
2331     LIMITED_METHOD_CONTRACT;
2332     _ASSERTE(!"Exception happened in mscorwks!DllMain!");
2333     return EXCEPTION_EXECUTE_HANDLER;
2334 }
2335
2336 //*****************************************************************************
2337 // This is the part of the old-style DllMain that initializes the
2338 // stuff that the EE team works on. It's called from the real DllMain
2339 // up in MSCOREE land. Separating the DllMain tasks is simply for
2340 // convenience due to the dual build trees.
2341 //*****************************************************************************
2342 BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
2343     HINSTANCE   hInst,             // Instance handle of the loaded module.
2344     DWORD       dwReason,          // Reason for loading.
2345     LPVOID      lpReserved)        // Unused.
2346 {
2347     STATIC_CONTRACT_NOTHROW;
2348     STATIC_CONTRACT_GC_TRIGGERS;
2349
2350     // HRESULT hr;
2351     // BEGIN_EXTERNAL_ENTRYPOINT(&hr);
2352     // EE isn't spun up enough to use this macro
2353
2354     struct Param
2355     {
2356         HINSTANCE hInst;
2357         DWORD dwReason;
2358         LPVOID lpReserved;
2359         void **pTlsData;
2360     } param;
2361     param.hInst = hInst;
2362     param.dwReason = dwReason;
2363     param.lpReserved = lpReserved;
2364     param.pTlsData = NULL;
2365
2366     // Can't use PAL_TRY/EX_TRY here as they access the ClrDebugState which gets blown away as part of the
2367     // PROCESS_DETACH path. Must use special PAL_TRY_FOR_DLLMAIN, passing the reason were in the DllMain.
2368     PAL_TRY_FOR_DLLMAIN(Param *, pParam, &param, pParam->dwReason)
2369     {
2370
2371     switch (pParam->dwReason)
2372         {
2373             case DLL_PROCESS_ATTACH:
2374             {
2375                 // We cache the SystemInfo for anyone to use throughout the
2376                 // life of the DLL.
2377                 GetSystemInfo(&g_SystemInfo);
2378
2379                 // Remember module instance
2380                 g_pMSCorEE = pParam->hInst;
2381
2382
2383                 // Set callbacks so that LoadStringRC knows which language our
2384                 // threads are in so that it can return the proper localized string.
2385             // TODO: This shouldn't rely on the LCID (id), but only the name
2386                 SetResourceCultureCallbacks(GetThreadUICultureNames,
2387                                             GetThreadUICultureId);
2388
2389                 InitEEPolicy();
2390
2391                 break;
2392             }
2393
2394             case DLL_PROCESS_DETACH:
2395             {
2396                 // lpReserved is NULL if we're here because someone called FreeLibrary
2397                 // and non-null if we're here because the process is exiting.
2398                 // Since nobody should ever be calling FreeLibrary on mscorwks.dll, lpReserved
2399                 // should always be non NULL.
2400                 _ASSERTE(pParam->lpReserved || !g_fEEStarted);
2401                 g_fProcessDetach = TRUE;
2402
2403                 if (g_fEEStarted)
2404                 {
2405                     // GetThread() may be set to NULL for Win9x during shutdown.
2406                     Thread *pThread = GetThread();
2407                     if (GCHeapUtilities::IsGCInProgress() &&
2408                         ( (pThread && (pThread != ThreadSuspend::GetSuspensionThread() ))
2409                             || !g_fSuspendOnShutdown))
2410                     {
2411                         g_fEEShutDown |= ShutDown_Phase2;
2412                         break;
2413                     }
2414
2415                     LOG((LF_STARTUP, INFO3, "EEShutDown invoked from EEDllMain"));
2416                     EEShutDown(TRUE); // shut down EE if it was started up
2417                 }
2418                 else
2419                 {
2420                     CLRRemoveVectoredHandlers();
2421                 }
2422                 break;
2423             }
2424
2425             case DLL_THREAD_DETACH:
2426             {
2427                 // Don't destroy threads here if we're in shutdown (shutdown will
2428                 // clean up for us instead).
2429
2430                 // Store the TLS data; we'll need it later and we might NULL the slot in DetachThread.
2431                 // This would be problematic because we can't depend on the FLS still existing.
2432                 pParam->pTlsData = CExecutionEngine::CheckThreadStateNoCreate(0
2433 #ifdef _DEBUG
2434                  // When we get here, OS has destroyed FLS, so FlsGetValue returns NULL now.
2435                  // We have validation code in CExecutionEngine::CheckThreadStateNoCreate to ensure that
2436                  // our TLS and FLS data are consistent, but since FLS has been destroyed, we need
2437                  // to silent the check there.  The extra arg for check build is for this purpose.
2438                                                                                          , TRUE
2439 #endif
2440                                                                                          );
2441                 Thread* thread = GetThread();
2442                 if (thread)
2443                 {
2444 #ifdef FEATURE_COMINTEROP
2445                     // reset the CoInitialize state
2446                     // so we don't call CoUninitialize during thread detach
2447                     thread->ResetCoInitialized();
2448 #endif // FEATURE_COMINTEROP
2449                     // For case where thread calls ExitThread directly, we need to reset the
2450                     // frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
2451                     // We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
2452                     if (thread->m_pFrame != FRAME_TOP)
2453                     {
2454 #ifdef _DEBUG
2455                         thread->m_GCOnTransitionsOK = FALSE;
2456 #endif
2457                         GCX_COOP_NO_DTOR();
2458                         thread->m_pFrame = FRAME_TOP;
2459                         GCX_COOP_NO_DTOR_END();
2460                     }
2461                     thread->DetachThread(TRUE);
2462                 }
2463             }
2464         }
2465
2466     }
2467     PAL_EXCEPT_FILTER(DllMainFilter)
2468     {
2469     }
2470     PAL_ENDTRY;
2471
2472     if (dwReason == DLL_THREAD_DETACH || dwReason == DLL_PROCESS_DETACH)
2473     {
2474         CExecutionEngine::ThreadDetaching(param.pTlsData);
2475     }
2476     return TRUE;
2477 }
2478
2479 #ifdef DEBUGGING_SUPPORTED
2480 //
2481 // InitializeDebugger initialized the Runtime-side COM+ Debugging Services
2482 //
2483 static void InitializeDebugger(void)
2484 {
2485     CONTRACTL
2486     {
2487         THROWS;
2488         GC_TRIGGERS;
2489         MODE_ANY;
2490     }
2491     CONTRACTL_END;
2492
2493     // Ensure that if we throw, we'll call TerminateDebugger to cleanup.
2494     // This makes our Init more atomic by avoiding partially-init states.
2495     class EnsureCleanup {
2496         BOOL    fNeedCleanup;
2497     public:
2498         EnsureCleanup()
2499         {
2500             fNeedCleanup = TRUE;
2501         }
2502
2503         void SuppressCleanup()
2504         {
2505             fNeedCleanup  = FALSE;
2506         }
2507
2508         ~EnsureCleanup()
2509         {
2510              STATIC_CONTRACT_NOTHROW;
2511              STATIC_CONTRACT_GC_NOTRIGGER;
2512              STATIC_CONTRACT_MODE_ANY;
2513
2514             if (fNeedCleanup) 
2515             { 
2516                 TerminateDebugger();
2517             }
2518         }
2519     } hCleanup;
2520
2521     HRESULT hr = S_OK;
2522
2523     LOG((LF_CORDB, LL_INFO10, "Initializing left-side debugging services.\n"));
2524
2525     FARPROC gi = (FARPROC) &CorDBGetInterface;
2526
2527     // Init the interface the EE provides to the debugger,
2528     // ask the debugger for its interface, and if all goes
2529     // well call Startup on the debugger.
2530     EEDbgInterfaceImpl::Init();
2531     _ASSERTE(g_pEEDbgInterfaceImpl != NULL); // throws on OOM
2532
2533     // This allocates the Debugger object.
2534     typedef HRESULT __cdecl CORDBGETINTERFACE(DebugInterface**);
2535     hr = ((CORDBGETINTERFACE*)gi)(&g_pDebugInterface);
2536     IfFailThrow(hr);
2537
2538     g_pDebugInterface->SetEEInterface(g_pEEDbgInterfaceImpl);
2539
2540     {
2541         hr = g_pDebugInterface->Startup(); // throw on error
2542         _ASSERTE(SUCCEEDED(hr));
2543
2544         // 
2545         // If the debug pack is not installed, Startup will return S_FALSE
2546         // and we should cleanup and proceed without debugging support.
2547         //
2548         if (hr != S_OK)
2549         {
2550             return;
2551         }
2552     }
2553
2554
2555     LOG((LF_CORDB, LL_INFO10, "Left-side debugging services setup.\n"));
2556
2557     hCleanup.SuppressCleanup();
2558
2559     return;
2560 }
2561
2562
2563 //
2564 // TerminateDebugger shuts down the Runtime-side COM+ Debugging Services
2565 // InitializeDebugger will call this if it fails.
2566 // This may be called even if the debugger is partially initialized.
2567 // This can be called multiple times.
2568 //
2569 static void TerminateDebugger(void)
2570 {
2571     CONTRACTL
2572     {
2573         NOTHROW;
2574         GC_NOTRIGGER;
2575         MODE_ANY;
2576     }
2577     CONTRACTL_END;
2578
2579     LOG((LF_CORDB, LL_INFO10, "Shutting down left-side debugger services.\n"));
2580
2581     // If initialized failed really early, then we didn't even get the Debugger object.
2582     if (g_pDebugInterface != NULL)
2583     {
2584         // Notify the out-of-process debugger that shutdown of the in-process debugging support has begun. This is only
2585         // really used in interop debugging scenarios.
2586         g_pDebugInterface->ShutdownBegun();
2587
2588         // This will kill the helper thread, delete the Debugger object, and free all resources.
2589         g_pDebugInterface->StopDebugger();
2590     }
2591
2592     g_CORDebuggerControlFlags = DBCF_NORMAL_OPERATION;
2593
2594 }
2595
2596 #endif // DEBUGGING_SUPPORTED
2597
2598 #ifndef LOCALE_SPARENT
2599 #define LOCALE_SPARENT 0x0000006d
2600 #endif
2601
2602 // ---------------------------------------------------------------------------
2603 // Impl for UtilLoadStringRC Callback: In VM, we let the thread decide culture
2604 // copy culture name into szBuffer and return length
2605 // ---------------------------------------------------------------------------
2606 extern BOOL g_fFatalErrorOccuredOnGCThread;
2607 static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames)
2608 {
2609     CONTRACTL
2610     {
2611         NOTHROW;
2612         GC_NOTRIGGER;
2613         MODE_ANY;
2614         PRECONDITION(CheckPointer(pCultureNames));
2615     } 
2616     CONTRACTL_END;
2617
2618     HRESULT hr = S_OK;
2619
2620     EX_TRY
2621     {
2622         InlineSString<LOCALE_NAME_MAX_LENGTH> sCulture;
2623         InlineSString<LOCALE_NAME_MAX_LENGTH> sParentCulture;
2624
2625 #if 0 // Enable and test if/once the unmanaged runtime is localized
2626         Thread * pThread = GetThread();
2627
2628         // When fatal errors have occured our invariants around GC modes may be broken and attempting to transition to co-op may hang
2629         // indefinately. We want to ensure a clean exit so rather than take the risk of hang we take a risk of the error resource not
2630         // getting localized with a non-default thread-specific culture.
2631         // A canonical stack trace that gets here is a fatal error in the GC that comes through:
2632         // coreclr.dll!GetThreadUICultureNames
2633         // coreclr.dll!CCompRC::LoadLibraryHelper
2634         // coreclr.dll!CCompRC::LoadLibrary
2635         // coreclr.dll!CCompRC::GetLibrary
2636         // coreclr.dll!CCompRC::LoadString
2637         // coreclr.dll!CCompRC::LoadString
2638         // coreclr.dll!SString::LoadResourceAndReturnHR
2639         // coreclr.dll!SString::LoadResourceAndReturnHR
2640         // coreclr.dll!SString::LoadResource
2641         // coreclr.dll!EventReporter::EventReporter
2642         // coreclr.dll!EEPolicy::LogFatalError
2643         // coreclr.dll!EEPolicy::HandleFatalError
2644         if (pThread != NULL && !g_fFatalErrorOccuredOnGCThread) {
2645
2646             // Switch to cooperative mode, since we'll be looking at managed objects
2647             // and we don't want them moving on us.
2648             GCX_COOP();
2649
2650             CULTUREINFOBASEREF pCurrentCulture = (CULTUREINFOBASEREF)Thread::GetCulture(TRUE);
2651
2652             if (pCurrentCulture != NULL)
2653             {
2654                 STRINGREF cultureName = pCurrentCulture->GetName();
2655
2656                 if (cultureName != NULL)
2657                 {
2658                     sCulture.Set(cultureName->GetBuffer(),cultureName->GetStringLength());
2659                 }
2660
2661                 CULTUREINFOBASEREF pParentCulture = pCurrentCulture->GetParent();
2662
2663                 if (pParentCulture != NULL)
2664                 {
2665                     STRINGREF parentCultureName = pParentCulture->GetName();
2666
2667                     if (parentCultureName != NULL)
2668                     {
2669                         sParentCulture.Set(parentCultureName->GetBuffer(),parentCultureName->GetStringLength());
2670                     }
2671
2672                 }
2673             }
2674         }
2675 #endif
2676
2677         // If the lazily-initialized cultureinfo structures aren't initialized yet, we'll
2678         // need to do the lookup the hard way.
2679         if (sCulture.IsEmpty() || sParentCulture.IsEmpty())
2680         {
2681             LocaleIDValue id ;
2682             int tmp; tmp = GetThreadUICultureId(&id);   // TODO: We should use the name instead
2683             _ASSERTE(tmp!=0 && id != UICULTUREID_DONTCARE);
2684             SIZE_T cchParentCultureName=LOCALE_NAME_MAX_LENGTH;
2685 #ifdef FEATURE_USE_LCID 
2686             SIZE_T cchCultureName=LOCALE_NAME_MAX_LENGTH;
2687             if (!::LCIDToLocaleName(id, sCulture.OpenUnicodeBuffer(static_cast<COUNT_T>(cchCultureName)), static_cast<int>(cchCultureName), 0))
2688             {
2689                 hr = HRESULT_FROM_GetLastError();
2690             }
2691             sCulture.CloseBuffer();
2692 #else
2693             sCulture.Set(id);
2694 #endif
2695
2696 #ifndef FEATURE_PAL
2697             if (!::GetLocaleInfoEx((LPCWSTR)sCulture, LOCALE_SPARENT, sParentCulture.OpenUnicodeBuffer(static_cast<COUNT_T>(cchParentCultureName)),static_cast<int>(cchParentCultureName)))
2698             {
2699                 hr = HRESULT_FROM_GetLastError();
2700             }
2701             sParentCulture.CloseBuffer();
2702 #else // !FEATURE_PAL            
2703             sParentCulture = sCulture;
2704 #endif // !FEATURE_PAL            
2705         }
2706         // (LPCWSTR) to restrict the size to null terminated size 
2707         pCultureNames->AppendIfNotThere((LPCWSTR)sCulture);
2708         // Disabling for Dev10 for consistency with managed resource lookup (see AppCompat bug notes in ResourceFallbackManager.cs)
2709         // Also, this is in the wrong order - put after the parent culture chain.
2710         //AddThreadPreferredUILanguages(pCultureNames);
2711         pCultureNames->AppendIfNotThere((LPCWSTR)sParentCulture);
2712         pCultureNames->Append(SString::Empty());
2713     }
2714     EX_CATCH
2715     {
2716         hr=E_OUTOFMEMORY;
2717     }
2718     EX_END_CATCH(SwallowAllExceptions);
2719
2720     return hr;
2721 }
2722
2723 // The exit code for the process is communicated in one of two ways.  If the
2724 // entrypoint returns an 'int' we take that.  Otherwise we take a latched
2725 // process exit code.  This can be modified by the app via System.SetExitCode().
2726 static INT32 LatchedExitCode;
2727     
2728 void SetLatchedExitCode (INT32 code)
2729 {
2730     CONTRACTL
2731     {
2732         NOTHROW;
2733         GC_NOTRIGGER;
2734         MODE_ANY;
2735     }
2736     CONTRACTL_END;
2737
2738     STRESS_LOG1(LF_SYNC, LL_INFO10, "SetLatchedExitCode = %d\n", code);
2739     LatchedExitCode = code;
2740 }
2741
2742 INT32 GetLatchedExitCode (void)
2743 {
2744     LIMITED_METHOD_CONTRACT;
2745     return LatchedExitCode;
2746 }
2747
2748     
2749 // ---------------------------------------------------------------------------
2750 // Impl for UtilLoadStringRC Callback: In VM, we let the thread decide culture
2751 // Return an int uniquely describing which language this thread is using for ui.
2752 // ---------------------------------------------------------------------------
2753 // TODO: Callers should use names, not LCIDs
2754 #ifdef FEATURE_USE_LCID
2755 static int GetThreadUICultureId(__out LocaleIDValue* pLocale)
2756 {
2757     CONTRACTL{
2758         NOTHROW;
2759         GC_NOTRIGGER;
2760         MODE_ANY;
2761     } CONTRACTL_END;
2762
2763
2764
2765     int Result = UICULTUREID_DONTCARE;
2766
2767     Thread * pThread = GetThread();
2768
2769 #if 0 // Enable and test if/once the unmanaged runtime is localized
2770     // When fatal errors have occured our invariants around GC modes may be broken and attempting to transition to co-op may hang
2771     // indefinately. We want to ensure a clean exit so rather than take the risk of hang we take a risk of the error resource not
2772     // getting localized with a non-default thread-specific culture.
2773     // A canonical stack trace that gets here is a fatal error in the GC that comes through:
2774     // coreclr.dll!GetThreadUICultureNames
2775     // coreclr.dll!CCompRC::LoadLibraryHelper
2776     // coreclr.dll!CCompRC::LoadLibrary
2777     // coreclr.dll!CCompRC::GetLibrary
2778     // coreclr.dll!CCompRC::LoadString
2779     // coreclr.dll!CCompRC::LoadString
2780     // coreclr.dll!SString::LoadResourceAndReturnHR
2781     // coreclr.dll!SString::LoadResourceAndReturnHR
2782     // coreclr.dll!SString::LoadResource
2783     // coreclr.dll!EventReporter::EventReporter
2784     // coreclr.dll!EEPolicy::LogFatalError
2785     // coreclr.dll!EEPolicy::HandleFatalError
2786     if (pThread != NULL && !g_fFatalErrorOccuredOnGCThread)
2787     {
2788         // Switch to cooperative mode, since we'll be looking at managed objects
2789         // and we don't want them moving on us.
2790         GCX_COOP();
2791
2792         CULTUREINFOBASEREF pCurrentCulture = (CULTUREINFOBASEREF)Thread::GetCulture(TRUE);
2793
2794         if (pCurrentCulture != NULL)
2795         {
2796             STRINGREF cultureName = pCurrentCulture->GetName();
2797             _ASSERT(cultureName != NULL);
2798
2799             if ((Result = ::LocaleNameToLCID(cultureName->GetBuffer(), 0)) == 0)
2800                 Result = (int)UICULTUREID_DONTCARE;
2801         }
2802     }
2803 #endif
2804
2805     if (Result == (int)UICULTUREID_DONTCARE)
2806     {
2807         // This thread isn't set up to use a non-default culture. Let's grab the default
2808         // one and return that.
2809
2810         Result = COMNlsInfo::CallGetUserDefaultUILanguage();
2811
2812         if (Result == 0 || Result == (int)UICULTUREID_DONTCARE)
2813             Result = GetUserDefaultLangID();
2814
2815         _ASSERTE(Result != 0);
2816         if (Result == 0)
2817         {
2818             Result = (int)UICULTUREID_DONTCARE;
2819         }
2820
2821     }
2822     *pLocale=Result;
2823     return Result;
2824 }
2825 #else
2826 // TODO: Callers should use names, not LCIDs
2827 static int GetThreadUICultureId(__out LocaleIDValue* pLocale)
2828 {
2829     CONTRACTL{
2830         NOTHROW;
2831         GC_NOTRIGGER;
2832         MODE_ANY;
2833     } CONTRACTL_END;
2834
2835     _ASSERTE(sizeof(LocaleIDValue)/sizeof(WCHAR) >= LOCALE_NAME_MAX_LENGTH);
2836
2837     int Result = 0;
2838
2839     Thread * pThread = GetThread();
2840
2841 #if 0 // Enable and test if/once the unmanaged runtime is localized
2842     // When fatal errors have occured our invariants around GC modes may be broken and attempting to transition to co-op may hang
2843     // indefinately. We want to ensure a clean exit so rather than take the risk of hang we take a risk of the error resource not
2844     // getting localized with a non-default thread-specific culture.
2845     // A canonical stack trace that gets here is a fatal error in the GC that comes through:
2846     // coreclr.dll!GetThreadUICultureNames
2847     // coreclr.dll!CCompRC::LoadLibraryHelper
2848     // coreclr.dll!CCompRC::LoadLibrary
2849     // coreclr.dll!CCompRC::GetLibrary
2850     // coreclr.dll!CCompRC::LoadString
2851     // coreclr.dll!CCompRC::LoadString
2852     // coreclr.dll!SString::LoadResourceAndReturnHR
2853     // coreclr.dll!SString::LoadResourceAndReturnHR
2854     // coreclr.dll!SString::LoadResource
2855     // coreclr.dll!EventReporter::EventReporter
2856     // coreclr.dll!EEPolicy::LogFatalError
2857     // coreclr.dll!EEPolicy::HandleFatalError
2858     if (pThread != NULL && !g_fFatalErrorOccuredOnGCThread)
2859     {
2860
2861         // Switch to cooperative mode, since we'll be looking at managed objects
2862         // and we don't want them moving on us.
2863         GCX_COOP();
2864
2865         CULTUREINFOBASEREF pCurrentCulture = (CULTUREINFOBASEREF)Thread::GetCulture(TRUE);
2866
2867         if (pCurrentCulture != NULL)
2868         {
2869             STRINGREF currentCultureName = pCurrentCulture->GetName();
2870
2871             if (currentCultureName != NULL)
2872             {
2873                 int cchCurrentCultureNameResult = currentCultureName->GetStringLength();
2874                 if (cchCurrentCultureNameResult < LOCALE_NAME_MAX_LENGTH)
2875                 {
2876                     memcpy(*pLocale, currentCultureName->GetBuffer(), cchCurrentCultureNameResult*sizeof(WCHAR));
2877                     (*pLocale)[cchCurrentCultureNameResult]='\0';
2878                     Result=cchCurrentCultureNameResult;
2879                 }
2880             }
2881         }
2882     }
2883 #endif
2884     if (Result == 0)
2885     {
2886 #ifndef FEATURE_PAL
2887         // This thread isn't set up to use a non-default culture. Let's grab the default
2888         // one and return that.
2889
2890         Result = ::GetUserDefaultLocaleName(*pLocale, LOCALE_NAME_MAX_LENGTH);
2891
2892         _ASSERTE(Result != 0);
2893 #else // !FEATURE_PAL
2894         static const WCHAR enUS[] = W("en-US");
2895         memcpy(*pLocale, enUS, sizeof(enUS));
2896         Result = sizeof(enUS);
2897 #endif // !FEATURE_PAL
2898     }
2899     return Result;
2900 }
2901
2902 #endif // FEATURE_USE_LCID
2903
2904
2905 #ifdef ENABLE_CONTRACTS_IMPL
2906
2907 // Returns TRUE if any contract violation suppressions are in effect.
2908 BOOL AreAnyViolationBitsOn()
2909 {
2910     CONTRACTL
2911     {
2912         NOTHROW;
2913         GC_NOTRIGGER;
2914         MODE_ANY;
2915     }
2916     CONTRACTL_END;
2917     UINT_PTR violationMask = GetClrDebugState()->ViolationMask();
2918     violationMask &= ~((UINT_PTR)CanFreeMe);  //CanFreeMe is a borrowed bit and has nothing to do with violations
2919     if (violationMask & ((UINT_PTR)BadDebugState))
2920     {
2921         return FALSE;
2922     }
2923
2924     return violationMask != 0;
2925 }
2926
2927
2928 // This function is intentionally invoked inside a big CONTRACT_VIOLATION that turns on every violation
2929 // bit on the map. The dynamic contract at the beginning *should* turn off those violation bits. 
2930 // The body of this function tests to see that it did exactly that. This is to prevent the VSWhidbey B#564831 fiasco
2931 // from ever recurring.
2932 void ContractRegressionCheckInner()
2933 {
2934     // DO NOT TURN THIS CONTRACT INTO A STATIC CONTRACT!!! The very purpose of this function
2935     // is to ensure that dynamic contracts disable outstanding contract violation bits.
2936     // This code only runs once at process startup so it's not going pooch the checked build perf.
2937     CONTRACTL
2938     {
2939         NOTHROW;
2940         GC_NOTRIGGER;
2941         FORBID_FAULT;
2942         LOADS_TYPE(CLASS_LOAD_BEGIN);
2943         CANNOT_TAKE_LOCK;
2944     }
2945     CONTRACTL_END
2946
2947     if (AreAnyViolationBitsOn())
2948     {
2949         // If we got here, the contract above FAILED to turn off one or more violation bits. This is a 
2950         // huge diagnostics hole and must be fixed immediately.
2951         _ASSERTE(!("WARNING: mscorwks has detected an internal error that may indicate contracts are"
2952                    " being silently disabled across the runtime. Do not ignore this assert!"));
2953     }
2954 }
2955
2956 // This function executes once per process to ensure our CONTRACT_VIOLATION() mechanism 
2957 // is properly scope-limited by nested contracts.
2958 void ContractRegressionCheck()
2959 {
2960     CONTRACTL
2961     {
2962         NOTHROW;
2963         GC_NOTRIGGER;
2964         MODE_ANY;
2965     }
2966     CONTRACTL_END;
2967  
2968     {
2969         // DO NOT "FIX" THIS CONTRACT_VIOLATION!!!
2970         // The existence of this CONTRACT_VIOLATION is not a bug. This is debug-only code specifically written
2971         // to test the CONTRACT_VIOLATION mechanism itself. This is needed to prevent a regression of 
2972         // B#564831 (which left a huge swath of contracts silently disabled for over six months)
2973         PERMANENT_CONTRACT_VIOLATION(ThrowsViolation
2974                                    | GCViolation
2975                                    | FaultViolation
2976                                    | LoadsTypeViolation
2977                                    | TakesLockViolation
2978                                    , ReasonContractInfrastructure
2979                                     );
2980         {
2981             FAULT_NOT_FATAL();
2982             ContractRegressionCheckInner();
2983         }
2984     }
2985
2986     if (AreAnyViolationBitsOn())
2987     {
2988         // If we got here, the CONTRACT_VIOLATION() holder left one or more violation bits turned ON
2989         // after we left its scope. This is a huge diagnostic hole and must be fixed immediately.
2990         _ASSERTE(!("WARNING: mscorwks has detected an internal error that may indicate contracts are"
2991                    " being silently disabled across the runtime. Do not ignore this assert!"));
2992     }
2993
2994 }
2995
2996 #endif // ENABLE_CONTRACTS_IMPL
2997
2998 #endif // CROSSGEN_COMPILE