What's the difference between exit and _exit both in libc.so? - exit

(gdb) info symbol exit
exit in section .text of /lib64/libc.so.6
(gdb) info symbol _exit
_exit in section .text of /lib64/libc.so.6
Anyone knows?

Simply said, exit is a high-level function that you should call to exit a process, it invokes on-exit handlers and some other high-level cleanup stuff. _exit is a low-level cleanup function, it is called as a last step from exit. exit will really terminate the process (by making the exit syscall).
From the glibc manual
at http://www.gnu.org/software/libc/manual/html_mono/libc.html (also check out the source code of glibc for details):
25.6.1 Normal Termination
A process terminates normally when its program signals it is done by calling exit. Returning from main is equivalent to calling exit, and the value that main returns is used as the argument to exit.
— Function: void exit (int status)
The exit function tells the system that the program is done, which causes it to terminate the process.
status is the program's exit status, which becomes part of the process' termination status. This function does not return.
Normal termination causes the following actions:
Functions that were registered with the atexit or on_exit functions are called in the reverse order of their registration. This mechanism allows your application to specify its own “cleanup” actions to be performed at program termination. Typically, this is used to do things like saving program state information in a file, or unlocking locks in shared data bases.
All open streams are closed, writing out any buffered output data. See Closing Streams. In addition, temporary files opened with the tmpfile function are removed; see Temporary Files.
_exit is called, terminating the program. See Termination Internals.
And in section "Termination Internals":
25.6.5 Termination Internals
The _exit function is the primitive used for process termination by exit. It is declared in the header file unistd.h.
— Function: void _exit (int status)
The _exit function is the primitive for causing a process to terminate with status status. Calling this function does not execute cleanup functions registered with atexit or on_exit.

Related

How does exit(EXITT_FAILURE) work in both c and c++?

I used exit(EXIT_FAILURE) in a precise function which is not the main one, but after its execution nothing is executed in the main function.
I really wanna know why ?
Thanks a lot in advance.
In order to understand how exit works it helps to understand how program termination upon returning from main works.
When the program returns from main it returns to a piece of helper code in the C or C++ runtime. That piece performs some cleanup and then calls the _exit system call with the return value of main. The kernel will stop execution of the process at that point.
The exit function has similar behavior, it performs the same cleanup as the helper code from the C and C++ runtime does when returned from main, then calls the _exit system call. It's this last call to the _exit system call that prevents execution of anything else (in main or otherwise) after calling of exit.

Difference between exit and kill in C++

I have written a signal handler to handle a SIG, and I want to kill the process if I get too many of it. So, which of the following code is better, or should I use them both?
exit(-1); // or some other exit code
kill(getpid(), SIGKILL);
You probably don't want either one, but what you do want is much closer to exit than to kill.
kill is something else coming in from the outside, and forcibly destroying a process. exit is the process itself deciding to quit executing. The latter is generally preferable.
As to why exit isn't the right answer either: most C++ code depends on destructors to clean up objects as you exit from a scope. If you call exit, that won't generally happen--you call exit, it exits to the OS, and no destructors get called in between (except things registered with onexit).
Instead, you generally want to throw an exception that's typically only caught in main, and exits gracefully when it is caught:
int main() {
try {
do_stuff();
}
catch(time_to_die const &) {
}
}
The advantage in this case is that when you do a throw time_to_die;, it automatically unwinds the stack, executing the destructors for all local objects as it goes. When it gets back to main, you get a normal exit, with all destructors having executed, so (assuming proper use of RAII) all your files, network connections, database connections, etc., have been closed as expected, any caches flushed, and so on, so you get a nice, graceful exit.
Short summary: as a rule of thumb, C++ code should never call exit. If your code is completely stuck in a crack, and you want to exit immediately, you want to call abort. If you want a semi-normal exit, do it by throwing an exception that will get you back to main so you can clean things and up and exit gracefully.
Difference between exit and kill in C++
One difference is that kill function is not specified in the C++ standard library. It is merely specified in POSIX. exit is standard C++.
Another difference is that kill(getpid(), SIGKILL) will cause the operating system terminates the process forcefully. exit instead performs cleanup (by calling a atexit callback, and flushing streams etc.) and terminates the execution voluntarily.
So, which of the following code is better, or should I use them both?
Depends on the use case, but usually exit is more sensible, since one usually wants the cleanup that it provides.
I would recommend exit(1).
Typically, an app would want to terminate gracefully if at all possible. SIGKILL is an instant death for your process - your exit handlers won't be called, for example. But in your case, you also have to call the getpid as well as the kill itself. exit instantly initiates the graceful exit process. It's the right choice for your needs.
There's rarely a good architectural reason to use SIGKILL in general. there's so many signals (http://man7.org/linux/man-pages/man7/signal.7.html in POSIX, you have SIGINT, SIGTERM, ... ) and to reiterate, there's no reason not to die gracefully if you can.

how to exit from a function but not from main()

Does C/C++ support terminating a program from a subroutine function i.e not main?
So far I only found that exit and abort allow a user to terminate current function or process.
If I'm not in main function, is there a way to terminate the whole program?
If you are not in main() and in other function then also you can call exit() or abort() it will terminate your whole process.
where exit() will do required clean up where abort() will not perform that.
exit(0) or exit(1)
If this is 0 or EXIT_SUCCESS, it indicates success.
If it is EXIT_FAILURE, it indicates failure.
ref: See here
since you're talking C++, consider std::terminate
u now, for “Does C/C++ support terminating a program from a subroutine function i.e not main?”
by default std::terminate calls abort, but this is configurable by installing a handler via std::set_terminate
void exit (int status)
Above method Terminates the process normally, performing the regular cleanup for terminating programs.
Normal program termination performs the following (in the same order):
Objects associated with the current thread with thread storage duration are destroyed (C++11 only).
Objects with static storage duration are destroyed (C++) and functions registered with atexit are called.
All C streams (open with functions in ) are closed (and flushed, if buffered), and all files created with tmpfile are removed.
And after that Control is returned to the host environment.
As it terminates the calling process, becuase your function is part of same process, so using exit() in that will terminate the program.
It can only be possible if you called that function from main function. And from that function from which you want to terminate the program return a value for terminating the program for example -1.
Example:
void main()
{
//Call to a function
int i = functionFromMain();
if(i == -1)
{
//Terminate Program
}
}

exit() function fails to exit process

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.

What is the difference between exit() and abort()?

In C and C++, what is the difference between exit() and abort()? I am trying to end my program after an error (not an exception).
abort() exits your program without calling functions registered using atexit() first, and without calling objects' destructors first. exit() does both before exiting your program. It does not call destructors for automatic objects though. So
A a;
void test() {
static A b;
A c;
exit(0);
}
Will destruct a and b properly, but will not call destructors of c. abort() wouldn't call destructors of neither objects. As this is unfortunate, the C++ Standard describes an alternative mechanism which ensures properly termination:
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().
struct exit_exception {
int c;
exit_exception(int c):c(c) { }
};
int main() {
try {
// put all code in here
} catch(exit_exception& e) {
exit(e.c);
}
}
Instead of calling exit(), arrange that code throw exit_exception(exit_code); instead.
abort sends a SIGABRT signal, exit just closes the application performing normal cleanup.
You can handle an abort signal however you want, but the default behavior is to close the application as well with an error code.
abort will not perform object destruction of your static and global members, but exit will.
Of course though when the application is completely closed the operating system will free up any unfreed memory and other resources.
In both abort and exit program termination (assuming you didn't override the default behavior), the return code will be returned to the parent process that started your application.
See the following example:
SomeClassType someobject;
void myProgramIsTerminating1(void)
{
cout<<"exit function 1"<<endl;
}
void myProgramIsTerminating2(void)
{
cout<<"exit function 2"<<endl;
}
int main(int argc, char**argv)
{
atexit (myProgramIsTerminating1);
atexit (myProgramIsTerminating2);
//abort();
return 0;
}
Comments:
If abort is uncommented: nothing is printed and the destructor of someobject will not be called.
If abort is commented like above: someobject destructor will be called you will get the following output:
exit function 2
exit function 1
The following things happen when a program calls exit():
Functions registered by the atexit function are executed
All open streams are flushed and closed, files created by tmpfile are removed
The program terminates with the specified exit code to the host
The abort() function sends the SIGABRT signal to the current process, if it is not caught the program is terminated with no guarantee that open streams are flushed/closed or that temporary files created via tmpfile are removed, atexit registered functions are not called, and a non-zero exit status is returned to the host.
From the exit() manual page:
The exit() function causes normal process termination and the value of
status & 0377 is returned to the parent.
From the abort() manual page:
The abort() first unblocks the SIGABRT signal, and then raises that
signal for the calling process. This results in the abnormal termination of the process unless the SIGABRT signal is caught and the signal
handler does not return.
abort sends the SIGABRT signal. abort does not return to the caller. The default handler for the SIGABRT signal closes the application. stdio file streams are flushed, then closed. Destructors for C++ class instances are not, however (not sure on this one -- perhaps results are undefined?).
exit has its own callbacks, set with atexit. If callbacks are specified (or only one), they are called in the order reverse of their registration order (like a stack), then the program exits. As with abort, exit does not return to the caller. stdio file streams are flushed, then closed. Also, destructors for C++ class instances are called.