Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different ways of exiting a process in C++

There are various ways of exiting a process:

e.g.: ExitProcess, ExitThread (from the main thread), exit, abort, return from main, terminate.

I'd like to know the effects each method has on static/global/automatic object destruction.

For example, I have a project that crashes (probably due to some deallocation error) when ExitProcess is called, but not when exit() is called. (related to this question, incidentally).

So basically I'd like to know under which circumstances deallocation of the above objects occurs, and in what order (For VC++).

like image 728
Assaf Lavie Avatar asked May 27 '09 11:05

Assaf Lavie


1 Answers

In short: The only totally safe thing to do is to allow main(), or your thread function, to return.

The C++ standard guarantees (3.6.3/1, 18.3) that destructors for global objects (including static objects) will be called if exit() is called, however it explicitly states that destructors for local variables will not be called in this case. exit() will call any functions registered with atexit(), and will also flush and then close any open stdio streams (including at least stdin, stdout, stderr).

Calling abort() is guaranteed not to call local or global destructors. Nor will it call functions registered with atexit() or flush stdio streams.

Calling any Win32 primitive such as ExitProcess() or ExitThread() will certainly not call destructors for local variables, and will almost certainly not call any destructors for global objects, or any functions registered with atexit(). Calling these functions directly in a C++ program is not advised -- basically, these Win32 functions and the C++ runtime library know nothing about each other. In fact, even the MSDN documentation for ExitThread() advises that C++ programs should return from the thread function instead of calling ExitThread().

(It is theoretically possible that the runtime library has specially arranged for ExitProcess() to call global object destructors -- this could be done by always loading a specific DLL whose entry point function will perform these calls, since ExitProcess() will call the entry point function for each loaded DLL with DLL_PROCESS_DETACH -- however to my knowledge, no implementation does this.)

like image 154
j_random_hacker Avatar answered Nov 12 '22 18:11

j_random_hacker