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.
Related
I am working with a program where my code calls a third party library which uses boost and shared_pointers to create a large and complex structure. This structure is created in a method that I call and at the end of the method I know that the program is finished.
For a large sample that I am handling the code to handle the processing takes 30 minutes and the boost code called automatically at exit takes many hours. Exiting the program without releasing the memory and spending all that time would be a perfectly acceptable outcome.
I tried
vector *iddListV = new vector(); // this WILL leak memory
with all the relevant structures added to the vector but this does not help.
I also tried calling exit(0); before reaching the end of the subroutine. This also causes the boost code to spend many hours trying to release pointers.
How to I get a C++ program (Microsoft C++ on Windows if that matters) to abruptly exit without calling the boost destructors.
My constraints are I can call any function before the boost structure are allocated but cannot modify the code once it starts running.
_Exit quits without calling any destructors.
If you're unconcerned about portability, you can call TerminateProcess(). But remember to take care that you are absolutely sure that your program is in a state which is ready to terminate. For example, if you terminate before I/O has had a chance to flush, then your file data and network streams may become invalid.
It is possible, in a portable manner, to do:
#include <exception>
...
std::terminate();
However, there's a big gotcha, in that, at least on linux, this may cause a core dump. (I'm really not sure what the behavior is on Windows).
It should be noted, that the behavior is implementation defined as far as whether or not destructors are called. Siting §15.5.1 P2:
In the situation where the search for a handler (15.3) encounters the
outermost block of a function with a noexcept-specification that does
not allow the exception (15.4), it is implementation-defined whether
the stack is unwound, unwound partially, or not unwound at all before
std::terminate() is called.
Additionally in §18.8.3.4 P1:
Remarks: Called by the implementation when exception handling must be
abandoned for any of several reasons (15.5.1), in effect immediately
after evaluating the throw-expression (18.8.3.1). May also be called
directly by the program.
C++11 also defines the function std::quick_exit(int status) that can be used in a similar manner (presumably without a coredump). This function is available from <cstdlib>.
I'm working on a multithreaded C++ application in Linux with FreeGLUT. Oddly enough, calling exit() in one of my threads results in an onexit() callback being called and completed, but fails to exit my program. Instead it hangs in a select() call in the GLUT library, according to GDB.
I also have a keyboard callback that exits when I press 'q'. GLUT exits fine if I press 'q' while the program is hanging.
No one seems to be having similar problems. Documentation says that exit() is supposed to close an entire process, and not just a thread, so it's not that. I'm stumped. Do you have any ideas?
EDIT: I've found the problem. I was wrong that the exit handler had finished. A library function call was waiting on a mutex that was already locked at the time that exit() was called. GLUT just took advantage of the free time. Thank you all for your responses.
In C++03
Note: exit() is a C function.
C as a language does not have the concept of threads at the language level.
Threads are usually added to C via a library support. So you need to read the library documentation of the affects of calling exit() from a thread that is not the main thread.
It is probably not portable across threading implementations.
Your best bet is to only call exit() from the main thread.
In a child thread you should probably just set some state that is viewed by the main thread. Let the main thread see this state and call exit manually. Note even calling exit on the man thread may hang some threading libraries if their are child threads still running. So best to get the main thread to wait for all children before exiting if you want your code to be portable.
In C++11
Now that C++11 has entered the since with explicit threading in the language there is more to it. See n3376 Section 18.4.1 [cstdint.syn] Paragraph 8
The function exit() has additional behavior in this International Standard:
— 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).
— Next, all open C streams (as mediated by the function signatures declared in ) with unwritten buffered data are flushed, all open C streams are closed, and all files created by calling tmpfile() are removed.
— 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 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.
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)