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++).
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.)
See the source code of ExitProcess() (posted on compuserve, usenet)
Related
We have some c++ code that can make calls to exit(3) through the users API. My assumption is that we are not properly unwinding stacks and that this considered bad in c++. Also there is a big c++ library involved that must be considered a black box.
I want to patch this, and also have an idea how, but don't know how to observe and compare the change. Can I make this somehow visible? Possibly on OS X?
exit() apparently does some cleanup. This is described in section 18.5 [support.start.term] of the standard, but the frequently correct site www.cplusplus.com summarizes it.
So it says objects with static storage or thread storage will be cleaned up, as will the entire I/O system (files will be flushed, etc).
But there are other ways to exit without running the C++ cleanup. For example, if it is a library that calls exit and it is a C language library (not C++) then it may or may not do the C++ cleanup. Or there are calls to abort or quick_exit. And, too, if you call the OS directly (e.g., ExitProcess() on Windows) then the process exits immediately and no C++ cleanup is done.
If you want to make the behavior visible: Make a object with a destructor that does something interesting - like log a message somewhere. Or maybe when it is constructed it creates a file with a certain name and when destructed it deletes it. Declare an instance this object in your main(). Declare another one (with a different message) at static scope. So now you have an effect observable in your environment.
The following is from 18.5 of N4140 (2014-10-07):
[[noreturn]] void exit(int status)
8 The function exit() has additional behavior in this International Standard:
(8.1) First, objects with thread storage duration and associated with the current
thread are destroyed. Next,objects with static storage duration are destroyed
and functions registered by calling `atexit` are called. See 3.6.3 for the
order of destructions and calls. (Automatic objects are not destroyed as a
result of calling `exit()`.) If control leaves a registered function called by
`exit` because the function does not provide a handler for a thrown exception,
`std::terminate()` shall be called (15.5.1).
(8.2) Next, all open C streams (as mediated by the function signatures declared in
`<cstdio>`) with unwritten buffered data are flushed, all open C streams are
closed, and all files created by calling `tmpfile()` are removed.
(8.3) Finally, control is returned to the host environment. If `status` is zero or
`EXIT_SUCCESS`, an implementation-defined form of the status _successful
termination_ is returned. If `status` is `EXIT_FAILURE`, an implementation-
defined form of the status _unsuccessful termination_ is returned. Otherwise
the status returned is implementation-defined.
I have a single class which does all the required initialization.
currently i have declared a global object of this class type, which is being instantiated on library load.
I've seen other ways, like delaring
BOOL APIENTRY DllMain
entry point for the shared library, and does the actual initialization on process attach.
does this differ from letting the implicit global initialization to its job? which way is better?
This is what happens during C++ DLL startup:
System calls DLL's entry point, generated by you compiler
Entry point calls DllMainCRTStartup (name may differ), which initializes C/C++ runtimes and instantiates all global objects.
DllMainCRTStartup then calls user-defined DllMain.
I personally prefer DllMain, because this way I can explicitly control order of initialization. When you use global objects in different compilation units, they will be initialized in random order which may bring some unexpected surprises 10 minutes before the deadline.
DllMain also let's you do per-thread initialization, which you can not achieve with global objects. However, it is not portable to other platforms.
P.S. You do NOT need mutex in DllMain, as all calls to it are already serialized under process-global critical section. I.e. it is guaranteed two threads will not enter it at the same time for any purpose. This is also the reason why you should not communicate with other threads, load other libraries etc. from this function; see MSDN article for explanation.
A couple of things that should never be done from DllMain:
Call LoadLibrary or LoadLibraryEx (either directly or indirectly). This can cause a deadlock or a crash.
Synchronize with other threads. This can cause a deadlock.
Acquire a synchronization object that is owned by code that is waiting to acquire the loader lock. This can cause a deadlock.
Initialize COM threads by using CoInitializeEx. Under certain conditions, this function can call LoadLibraryEx.
Call the registry functions. These functions are implemented in Advapi32.dll. If Advapi32.dll is not initialized before your DLL, the DLL can access uninitialized memory and cause the process to crash.
Call CreateProces. Creating a process can load another DLL.
Call ExitThread. Exiting a thread during DLL detach can cause the loader lock to be acquired again, causing a deadlock or a crash.
Call CreateThread. Creating a thread can work if you do not synchronize with other threads, but it is risky.
Create a named pipe or other named object (Windows 2000 only). In Windows 2000, named objects are provided by the Terminal Services DLL. If this DLL is not initialized, call to the DLL can cause the process to crash.
Use the memory management function from the dynamic C Run-Time (CRT). If the CRT DLL is not initialized, calls to these functions can cause the process to crash.
Call functions in User32.dll or Gdi32.dll. Some functions load another DLL, which may not be initialized.
Use managed code.
You need a static boolean initialization variable and a mutex. Statically initialize "initialized" to 0. In your DllMain(), make a call to CreateMutex(). Use bInitialOwner=0 and a unique name for lpName that's unique to your application. Then use WaitForSingleObject() to wait for the mutex. Check if initialized is non-zero. If not, do your initialization, and then set initialized to 1. If initialized is non-zero, do nothing. Finally, release the mutex using ReleaseMutex() and close it using CloseHandle().
Here's some pseudo-code, with error and exception handling omitted:
initialized = 0;
DllMain()
{
mutex = CreateMutex(..., 0, "some-unique-name");
result = WaitForSingleObject(handle, ...);
if (result == WAIT_OBJECT_0) {
if (!initialized) {
// initialization goes here
initialized = 1;
}
}
ReleaseMutex(mutex);
CloseHandle(mutex);
}
hi i would recommend u to prefer a signleton class where u can only create a single object of a class and use it. Sigleton class can be created with a private constructor. Now suppose ur class A is a singleton class its object can be used in a constructor of each Class which u want to initialize. Please give us some sample code so other may help u better.
I want to immediately exit my MFC app in C++. Is exit(0) the best solution? eg. does it prevent destructors from being called, is it threadsafe? etc. Is there a better solution? Thanks.
Yes, exit(0) is the best solution. It will cause the destructors of global objects (and static objects within functions) to run, however it will not cause destructors of stack-allocated or heap-allocated objects to run:
// At global scope
ClassWithDestruct globalObject;
void SomeFunction()
{
static ClassWithDestructor staticObject;
ClassWithDestructor stackObject;
ClassWithDestructor *heapObject = new ClassWithDestructor;
// On the following call to exit(), the destructors of 'globalObject' and
// 'staticObject' will run, but those of 'stackObject' and 'heapObject' will
// NOT run
exit(0);
}
As to whether or not it's thread-safe, that's a hard question to answer: you should not be calling exit simultaneously from multiple threads, you should only call it once. If any destructors run as a result of exit, or any if any functions registered with atexit run, then obviously those functions should be thread-safe if they deal with data that could potentially be being used by other threads.
If your program is exiting normally (say, as a result of the user requesting an exit), you should either call exit or return from main/WinMain, which is equivalent to calling exit. If your program is exiting abnormally (say, as a result of an access violation or failed assertion), you should call either _exit or abort, which do not call any destructors.
If you want to exit immediately, ensuring against running any destructors and such beforehand, then you probably want to call abort(). If you do want destructors to execute, then you probably want to use PostQuitMessage(0);. Either way, exit() is probably the wrong choice.
when a win32 process exits any resource associated with it is cleaned up by the OS, so in order to me it is perfectly ok.
exit(0) exits the process. All memory is cleaned up. On the other hand explicitly managed resources may not be closed. Of course file handles would be closed and stuff in windows buffers will be flushed. However stuff that the application manages will not.
No, it's not a safe way to end your program. Static-storage data and non-local automatic objects will destruct, but local automatic objects will not.
From 18.3/8 in the C++ standard:
The function exit() has additional
behavior in this International
Standard:
First, objects with static storage
duration are destroyed and functions
registered by calling atexit are
called. Non-local objects with static
storage duration are destroyed […].
(Automatic objects are not destroyed
as a result of calling
exit().)[207]) […] A local static
object obj3 is destroyed at the same
time it would be if a function calling
the obj3 destructor were registered
with atexit at the completion of the
obj3 constructor.
Next, all open C streams (as
mediated by the function signatures
declared in <cstdio>) with unwritten
buffered data are flushed, all open C
streams are closed, and all files
created by calling tmpfile() are
removed.[209])
[207]: Objects with automatic storage
duration are all destroyed in a
program whose function main()
contains no automatic objects and
executes the call to exit(). Control
can be transferred directly to such a
main() by throwing an exception that
is caught in main().
[209]: Any C streams associated with
cin, cout, etc (27.3) are flushed
and closed when static objects are
destroyed in the previous phase. The
function tmpfile() is declared in
<cstdio>.
On a related note, std::exit(EXIT_SUCCESS) is disturbingly misleading.
C99 offers the _Exit function, which exits "immediately", although it does may close file descriptors. Unix/POSIX extends this behavior by mandating the closing of all fd's without flushing (and offers the synonym _exit).
Will these functions call destructors for static objects when called from a C++ program? Does the C++ standard make any guarantees about _Exit?
(Inspired by this question; I suddenly wondered what happens in the typical fork-exec-_exit idiom in C++.)
First, no form of program exit will automatically call destructors for heap objects (implied in ISO/IEC 14882:1998(E) 12.4.10).
Calling exit() will not call destructors for objects with automatic duration, as it does not return through their enclosing scopes (3.6.1.4). However, destructors for static objects will be called, in reverse order of construction (18.3.8).
Calling abort() does not call any destructors for any type of object, nor does it call atexit() registered functions (18.3.3). The C++ standard copy I have here is a bit dated and does not mention _exit or _Exit directly, but I'd imagine that, if present, they should behave the same - that is, not calling any destructors. In particular, in the C99 standard, _Exit() skips atexit handlers (it is implementation defined whether stream buffers are flushed, open streams are closed, or temporary files removed).
Further note that abort() can be cancelled by trapping signal SIGABRT (ISO/IEC 9899:1999 (E) 7.20.4.1.2 - I only have C99 here but I expect it would be the same in the version referenced by C++). _Exit() cannot.
On a more practical note, on most unix implementations of abort() and _exit(), abort() raises a SIGABRT while _exit() simply calls an operating system call to terminate the process immediately. This means that the main differences are:
You can specify an exit code for _exit()
abort() may be trapped by a signal handler
Depending on system configuration, OS, and ulimits, abort() may result in a core dump or similar
In a fork()/exec() pattern, _exit() would probably be preferable, to avoid the possibility of core dump.
It simply doesn't exist in standard C++, so there are no guarantees.
It is planned for inclusion in C++0x. That specifies (§18.5):
The function _Exit(int status) has
additional behavior in this
International Standard:
— The program is terminated without
executing destructors for objects of
automatic, thread, or static storage
duration and without calling functions
passed to atexit() (3.6.3).
Followup:
ISO approved C++0x on August 12, 2011.
Technically, _Exit is not defined by the C++ standard, so you can't even call it from a 100% portable C++ program. The C++03 standard incorporates by reference the C89 standard (aka C90 or ANSI C), whereas _Exit is only defined in the newer C99 standard. I'm not sure which version of C the upcoming C++0x standard incorporates, but I would guess that it's based on C99.
In any case, though, here are the relevant clauses from the relevant language standards:
_Exit is not guaranteed to close file descriptors. From C99 §7.20.4.4/2 (emphasis mine):
The _Exit function causes normal program termination to occur and control to be returned to the host environment. No functions registered by the atexit function or signal handlers registered by the signal function are called. The status returned to the host environment is determined in the same way as for the exit function (7.20.4.3). Whether open streams with unwritten buffered data are flushed, open streams are closed, or temporary files are removed is implementation-defined.
Recall that implementation-defined means that the implementation (that is, the compiler toolchain and runtime environment) can choose to do whatever it wants, but it must document what it does.
From C++03 §3.6.3/1:
Destructors (12.4) for initialized objects of static storage duration (declared at block scope or at namespace scope) are called as a result of returning from main and as a result of calling exit (18.3). These objects are destroyed in the reverse order of the completion of their constructor or of the completion of their dynamic initialization. If an object is initialized statically, the object is destroyed in the same order as if the object was dynamically initialized. For an object of array or class type, all subobjects of that object are destroyed before any local object with static storage duration initialized during the construction of the subobjects is destroyed.
§3.6.3/4:
Calling the function
void abort();
declared in <cstdlib> terminates the program without executing destructors for objects of automatic or static storage duration and without calling the functions passed to atexit().
Practically, in most implementations, global object destructors are implemented via atexit, so what you will see is that _Exit will not call the destructors for global objects, although this behavior is not guaranteed (since _Exit and C++ are not guaranteed to both exist in the same language).
Note that while C++ does not specify _Exit and C99 leaves it implementation-defined whether it flushes buffers, POSIX requires that it not flush buffers (since this would break the main usage of _exit/_Exit, i.e. handling failure of execve after fork). As POSIX does not align itself with C++ standards or defer to them on anything, I think it's very unlikely that a future version of the C++ standard would try to change any of this. It will probably either leave _Exit unspecified or specify that it's implementation-defined.
C++0x defines a new function called std::quick_exit that terminates a process without calling any destructors. Just checked, g++-4.4.5 already provides it.
There is an interesting analysis here in relation with concurrency and object destruction. As far as I know, destructors will not be called. There is nothing about it in the current standard.
Calling of static destructors is defined in terms of atexit. _exit (or _Exit) is defined not to run atexit handlers. So static destructors should not be called by any implementation.
Automatic destructors are not even called when calling exit().
So any sane definition of _Exit semantics for C++ would not run destructors.
I did a quick test with gcc on Mac OS and my destructors didn't get called.
struct A
{
~A()
{
puts("A::~A");
}
};
A globalA;
int main()
{
A localA;
_exit(0); // or _Exit(0)
return 0;
}
exit(0) on the other hand calls globalA's destructor.
fork(), exec(), and _exit() are all defined by POSIX and they pre-date C99's _Exit() by many years. Programs that use fork/exec/_exit are not portable to every system that supports C++.
With regard to _exit() specifically, it is an operating system call that (under POSIX) will close files and terminate the process directly (but not necessarily quickly). This would bypass any C++ mechanisms for calling destructors.
Even with _Exit() or similar being provided by C++0x, I doubt if there would be much reason to use that in conjunction with fork. It likely just provides broader portability for a "quick-exit" in other contexts. That functionality is already covered by _exit() if you are using the POSIX API.
Program termination is addressed in C++2003 section [3.6.3]. It says that static objects are destructed implicitly when main() returns and when exit() is called. It also says that such objects are NOT destructed when abort() is called. _exit() isn't addressed in the C++ 2003 standard, but the fact that it is meant to bypass language-specific cleanup is described in the POSIX documentation. That effect is further substantiated by what is stated and by what is NOT stated in the C++ standard.
Let's say I write a DLL in C++, and declare a global object of a class with a non-trivial destructor. Will the destructor be called when the DLL is unloaded?
In a Windows C++ DLL, all global objects (including static members of classes) will be constructed just before the calling of the DllMain with DLL_PROCESS_ATTACH, and they will be destroyed just after the call of the DllMain with DLL_PROCESS_DETACH.
Now, you must consider three problems:
0 - Of course, global non-const objects are evil (but you already know that, so I'll avoid mentionning multithreading, locks, god-objects, etc.)
1 - The order of construction of objects or different compilation units (i.e. CPP files) is not guaranteed, so you can't hope the object A will be constructed before B if the two objects are instanciated in two different CPPs. This is important if B depends on A. The solution is to move all global objects in the same CPP file, as inside the same compilation unit, the order of instanciation of the objects will be the order of construction (and the inverse of the order of destruction)
2 - There are things that are forbidden to do in the DllMain. Those things are probably forbidden, too, in the constructors. So avoid locking something. See Raymond Chen's excellent blog on the subject:
Some reasons not to do anything scary in your DllMain
Another reason not to do anything scary in your DllMain: Inadvertent deadlock
Some reasons not to do anything scary in your DllMain, part 3
In this case, lazy initialization could be interesting: The classes remain in an "un-initialized" state (internal pointers are NULL, booleans are false, whatever) until you call one of their methods, at which point they'll initialize themselves. If you use those objects inside the main (or one of the main's descendant functions), you'll be ok because they will be called after execution of DllMain.
3 - Of course, if some global objects in DLL A depend on global objects in DLL B, you should be very very careful about DLL loading order, and thus dependancies. In this case, DLLs with direct or indirect circular dependancies will cause you an insane amount of headaches. The best solution is to break the circular dependancies.
P.S.: Note that in C++, constructor can throw, and you don't want an exception in the middle of a DLL loading, so be sure your global objects won't be using exception without a very, very good reason. As correctly written destructors are not authorized to throw, the DLL unloading should be ok in this case.
This page from Microsoft goes into the details of DLL initialization and destruction of globals:
http://msdn.microsoft.com/en-us/library/988ye33t.aspx
If you want to see the actual code that gets executed when linking a .dll, take a look at %ProgramFiles%\Visual Studio 8\vc\crt\src\dllcrt0.c.
From inspection, destructors will be called via _cexit() when the internal reference count maintained by the dll CRT hits zero.
It should be called when either the application ends or the DLL is unloaded, whichever comes first. Note that this is somewhat dependent on the actual runtime you're compiling against.
Also, beware non-trivial destructors as there are both timing and ordering issues. Your DLL may be unloaded after a DLL your destructor relies on, which would obviously cause issues.
In windows binary image files with extension *.exe, *.dll are in PE format
Such files have Entry Point. You can view it with dumpbin tool like
dumpbin /headers dllname.dll
If you use C runtime from Microsoft, then your entry point will be something like
*CRTStartup or *DllMainCRTStartup
Such functions perform initialization of c and c++ runtime and delegate execution to (main, WinMain) or to DllMain respectively.
If you use Microsofts VC compiler then you can watch at source code of this functions in yours VC directory:
crt0.c
dllcrt0.c
DllMainCRTStartup process all things need to init/deinit your global variables from .data sections in normal scenario, when it retrive notification DLL_PROCESS_DETACH during dll unload. For example:
main or WinMain of startup thread of program returns control flow
you explictly call FreeLibrary and use-dll-counter is zero
When DllMain with fdwReason = DLL_PROCESS_DETACH parameter is called it means the DLL is unloaded by the application. This is the time before the destructor of global/static objects gets called.