ReactOS 0.4.16-dev-918-g97e7efc
exit.cpp File Reference
#include <corecrt_internal.h>
#include <eh.h>
#include <process.h>
Include dependency graph for exit.cpp:

Go to the source code of this file.

Typedefs

typedef void(WINAPIexit_process_pft) (UINT)
 

Functions

static bool __cdecl is_managed_app () throw ()
 
static void __cdecl try_cor_exit_process (UINT const return_code) throw ()
 
static bool __cdecl should_call_terminate_process () throw ()
 
static void __cdecl exit_or_terminate_process (UINT const return_code) throw ()
 
static int __cdecl atexit_exception_filter (unsigned long const _exception_code) throw ()
 
void __cdecl __acrt_initialize_thread_local_exit_callback (void *encoded_null)
 
void __cdecl _register_thread_local_exe_atexit_callback (_In_ _tls_callback_type const _Callback)
 
static void __cdecl common_exit (int const return_code, _crt_exit_cleanup_mode const cleanup_mode, _crt_exit_return_mode const return_mode) throw ()
 
int __cdecl _is_c_termination_complete ()
 
void __cdecl exit (int const return_code)
 
void __cdecl _exit (int const return_code)
 
void __cdecl _Exit (int const return_code)
 
void __cdecl quick_exit (int const return_code)
 
void __cdecl _cexit ()
 
void __cdecl _c_exit ()
 

Variables

static long c_termination_complete = FALSE
 
_onexit_table_t __acrt_atexit_table
 
_onexit_table_t __acrt_at_quick_exit_table
 
static _tls_callback_type thread_local_exit_callback_func
 

Typedef Documentation

◆ exit_process_pft

typedef void(WINAPI * exit_process_pft) (UINT)

Definition at line 46 of file exit.cpp.

Function Documentation

◆ __acrt_initialize_thread_local_exit_callback()

void __cdecl __acrt_initialize_thread_local_exit_callback ( void encoded_null)

Definition at line 155 of file exit.cpp.

156{
157 thread_local_exit_callback_func = reinterpret_cast<_tls_callback_type>(encoded_null);
158}
static _tls_callback_type thread_local_exit_callback_func
Definition: exit.cpp:21

◆ _c_exit()

void __cdecl _c_exit ( void  )

Definition at line 315 of file exit.cpp.

316{
318}
static void __cdecl common_exit(int const return_code, _crt_exit_cleanup_mode const cleanup_mode, _crt_exit_return_mode const return_mode)
Definition: exit.cpp:175
@ _crt_exit_no_cleanup
@ _crt_exit_return_to_caller

◆ _cexit()

void __cdecl _cexit ( void  )

Definition at line 310 of file exit.cpp.

◆ _exit()

void __cdecl _exit ( int const  return_code)

Definition at line 292 of file exit.cpp.

293{
296}
#define UNREACHABLE
@ _crt_exit_terminate_process

◆ _Exit()

void __cdecl _Exit ( int const  return_code)

Definition at line 298 of file exit.cpp.

◆ _is_c_termination_complete()

int __cdecl _is_c_termination_complete ( void  )

Definition at line 279 of file exit.cpp.

280{
281 return static_cast<int>(__crt_interlocked_read(&c_termination_complete));
282}
static long c_termination_complete
Definition: exit.cpp:12

◆ _register_thread_local_exe_atexit_callback()

void __cdecl _register_thread_local_exe_atexit_callback ( _In_ _tls_callback_type const  _Callback)

Definition at line 162 of file exit.cpp.

163{
164 // Can only set the callback once.
165 if (thread_local_exit_callback_func != __crt_fast_encode_pointer(nullptr))
166 {
167 terminate();
168 }
169
170 thread_local_exit_callback_func = __crt_fast_encode_pointer(_Callback);
171}
void MSVCRT() terminate()
Definition: cpp.c:716

◆ atexit_exception_filter()

static int __cdecl atexit_exception_filter ( unsigned long const  _exception_code)
throw (
)
static

Definition at line 143 of file exit.cpp.

144{
145 if (_exception_code == ('msc' | 0xE0000000))
146 {
148 }
149
151}
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91
#define _exception_code()
Definition: pseh2_64.h:194

Referenced by common_exit().

◆ common_exit()

static void __cdecl common_exit ( int const  return_code,
_crt_exit_cleanup_mode const  cleanup_mode,
_crt_exit_return_mode const  return_mode 
)
throw (
)
static

Definition at line 175 of file exit.cpp.

180{
181 // First, check to see if we're loaded in a managed app. If we are, try to
182 // call CorExitProcess to let the CLR handle the process termination. If
183 // the call to CorExitProcess is successful, then it will call back through
184 // this function with a return mode of _crt_exit_return_to_caller, at which
185 // point we will run the C termination routines. It will then terminate the
186 // process itself and not return.
187 if (return_mode == _crt_exit_terminate_process && is_managed_app())
188 {
189 try_cor_exit_process(return_code);
190 }
191
192 // Run the C termination:
193 bool crt_uninitialization_required = false;
194
195 __acrt_lock_and_call(__acrt_select_exit_lock(), [&]
196 {
197 static bool c_exit_complete = false;
198 if (c_exit_complete)
199 {
200 return;
201 }
202
204
205 __try
206 {
207 if (cleanup_mode == _crt_exit_full_cleanup)
208 {
209
210 // If this module has any dynamically initialized
211 // __declspec(thread) variables, then we invoke their
212 // destruction for the primary thread. All thread_local
213 // destructors are sequenced before any atexit calls or static
214 // object destructors (3.6.3/1)
215 if (thread_local_exit_callback_func != __crt_fast_encode_pointer(nullptr))
216 {
217 (__crt_fast_decode_pointer(thread_local_exit_callback_func))(nullptr, DLL_PROCESS_DETACH, nullptr);
218 }
219
221 }
222 else if (cleanup_mode == _crt_exit_quick_cleanup)
223 {
225 }
226 }
228 {
229 terminate();
230 }
232
233 #ifndef CRTDLL
234 // When the CRT is statically linked, we are responsible for executing
235 // the terminators here, because the CRT code is present in this module.
236 // When the CRT DLLs are used, the terminators will be executed when
237 // the CRT DLLs are unloaded, after the call to ExitProcess.
238 if (cleanup_mode == _crt_exit_full_cleanup)
239 {
241 }
242
244 #endif // CRTDLL
245
246 if (return_mode == _crt_exit_terminate_process)
247 {
248 c_exit_complete = true;
249 crt_uninitialization_required = true;
250 }
251 });
252
253 // Do NOT try to uninitialize the CRT while holding one of its locks.
254 if (crt_uninitialization_required)
255 {
256 // If we are about to terminate the process, if the debug CRT is linked
257 // statically into this module and this module is an EXE, we need to
258 // ensure that we fully and correctly uninitialize the CRT so that the
259 // debug on-exit() checks (e.g. debug heap leak detection) have a chance
260 // to run.
261 //
262 // We do not need to uninitialize the CRT when it is statically linked
263 // into a DLL because its DllMain will be called for DLL_PROCESS_DETACH
264 // and we can uninitialize the CRT there.
265 //
266 // We never need to uninitialize the retail CRT during exit() because
267 // the process is about to terminate.
268 #if !CRTDLL && _DEBUG
269 __scrt_uninitialize_crt(true, true);
270 #endif
271 }
272
273 if (return_mode == _crt_exit_terminate_process)
274 {
275 exit_or_terminate_process(return_code);
276 }
277}
bool __cdecl __scrt_uninitialize_crt(bool is_terminating, bool from_exit)
#define __acrt_select_exit_lock()
_ACRTIMP int __cdecl _execute_onexit_table(_In_opt_ _onexit_table_t *_Table)
_ACRTIMP void __cdecl _initterm(_In_reads_(_Last - _First) _In_ _PVFV *_First, _In_ _PVFV *_Last)
#define TRUE
Definition: types.h:120
#define DLL_PROCESS_DETACH
Definition: compat.h:130
_onexit_table_t __acrt_at_quick_exit_table
Definition: exit.cpp:15
static bool __cdecl is_managed_app()
Definition: exit.cpp:49
static int __cdecl atexit_exception_filter(unsigned long const _exception_code)
Definition: exit.cpp:143
static void __cdecl exit_or_terminate_process(UINT const return_code)
Definition: exit.cpp:126
_onexit_table_t __acrt_atexit_table
Definition: exit.cpp:14
static void __cdecl try_cor_exit_process(UINT const return_code)
Definition: exit.cpp:82
_PVFV __xp_z[]
_PVFV __xp_a[]
_PVFV __xt_a[]
_PVFV __xt_z[]
long __cdecl _InterlockedExchange(_Interlocked_operand_ long volatile *_Target, long _Value)
#define __try
Definition: pseh2_64.h:188
#define __except
Definition: pseh2_64.h:189
#define __endtry
Definition: pseh2_64.h:191
#define GetExceptionCode()
Definition: exception.h:68
@ _crt_exit_quick_cleanup

Referenced by _c_exit(), _cexit(), _exit(), _Exit(), exit(), and quick_exit().

◆ exit()

void __cdecl exit ( int const  return_code)

Definition at line 286 of file exit.cpp.

◆ exit_or_terminate_process()

static void __cdecl exit_or_terminate_process ( UINT const  return_code)
throw (
)
static

Definition at line 126 of file exit.cpp.

127{
129 {
130 TerminateProcess(GetCurrentProcess(), return_code);
131 }
132
133 try_cor_exit_process(return_code);
134
135 // If that returned, then the exe for this process is not managed or we
136 // failed to exit via a call to CorExitProcess. Exit the normal way:
137 ExitProcess(return_code);
138}
#define GetCurrentProcess()
Definition: compat.h:759
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
static bool __cdecl should_call_terminate_process()
Definition: exit.cpp:105

Referenced by common_exit().

◆ is_managed_app()

static bool __cdecl is_managed_app ( )
throw (
)
static

Definition at line 49 of file exit.cpp.

50{
51 PIMAGE_DOS_HEADER const dos_header = reinterpret_cast<PIMAGE_DOS_HEADER>(GetModuleHandleW(nullptr));
52 if (dos_header == nullptr)
53 return false;
54
56 return false;
57
58 PIMAGE_NT_HEADERS const pe_header = reinterpret_cast<PIMAGE_NT_HEADERS>(
59 reinterpret_cast<BYTE*>(dos_header) + dos_header->e_lfanew);
60
61 if (pe_header->Signature != IMAGE_NT_SIGNATURE)
62 return false;
63
65 return false;
66
67 // prefast assumes we are overrunning __ImageBase
68 #pragma warning(push)
69 #pragma warning(disable: 26000)
70
72 return false;
73
74 #pragma warning(pop)
75
77 return false;
78
79 return true;
80}
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
static IMAGE_DOS_HEADER dos_header
Definition: data.c:13
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
#define IMAGE_NT_OPTIONAL_HDR_MAGIC
Definition: ntimage.h:387
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
unsigned char BYTE
Definition: xxhash.c:193

Referenced by common_exit().

◆ quick_exit()

void __cdecl quick_exit ( int const  return_code)

Definition at line 304 of file exit.cpp.

Referenced by test_call_quick_exit().

◆ should_call_terminate_process()

static bool __cdecl should_call_terminate_process ( )
throw (
)
static

Definition at line 105 of file exit.cpp.

106{
108 {
109 return false;
110 }
111
112 // If application verifier is running, we still want to call ExitProcess,
113 // to enable tools that require DLLs to be unloaded cleanly at process exit
114 // to do their work.
116 {
117 return false;
118 }
119
120 return true;
121}
process_end_policy __cdecl __acrt_get_process_end_policy(void)
bool __cdecl __acrt_app_verifier_enabled(void)
Definition: peb_access.cpp:14
@ process_end_policy_exit_process

Referenced by exit_or_terminate_process().

◆ try_cor_exit_process()

static void __cdecl try_cor_exit_process ( UINT const  return_code)
throw (
)
static

Definition at line 82 of file exit.cpp.

83{
84 __crt_unique_hmodule mscoree;
85 if (!GetModuleHandleExW(0, L"mscoree.dll", mscoree.get_address_of()))
86 return;
87
88 auto const cor_exit_process = __crt_get_proc_address<exit_process_pft>(mscoree.get(), "CorExitProcess");
89 if (!cor_exit_process)
90 return;
91
92 cor_exit_process(return_code);
93}
BOOL WINAPI GetModuleHandleExW(IN DWORD dwFlags, IN LPCWSTR lpwModuleName OPTIONAL, OUT HMODULE *phModule)
Definition: loader.c:866
#define L(x)
Definition: ntvdm.h:50

Referenced by common_exit(), and exit_or_terminate_process().

Variable Documentation

◆ __acrt_at_quick_exit_table

_onexit_table_t __acrt_at_quick_exit_table

Definition at line 15 of file exit.cpp.

Referenced by common_exit().

◆ __acrt_atexit_table

_onexit_table_t __acrt_atexit_table

Definition at line 14 of file exit.cpp.

Referenced by common_exit().

◆ c_termination_complete

long c_termination_complete = FALSE
static

Definition at line 12 of file exit.cpp.

Referenced by _is_c_termination_complete(), and common_exit().

◆ thread_local_exit_callback_func

_tls_callback_type thread_local_exit_callback_func
static