150

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).

Martin Liversage
  • 104,481
  • 22
  • 209
  • 256

5 Answers5

133

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.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 2
    +1 because, while Brian R. Bondy was good, you did raise the problem of abort/exit (not destructor of stack objects called), and offered the alternative for a RAII-intensive C++ process. – paercebal Jan 02 '09 at 23:27
  • I was looking on a way to quit a program without calling dtor and your answer is just what i was looking for! Thanks – acemtp Apr 19 '09 at 17:49
  • That is perfectly correct of course, if it actually matters that your automatic objects destructors are not called :-) – Chris Huang-Leaver Jan 05 '10 at 10:10
  • 3
    To my knowledge, one further difference between exit and abort would be, that abort could (depending on the operating system configuration) lead to the generation of a core dump. – Dirk Herrmann Apr 29 '20 at 13:36
36

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

Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
12

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.

Robert Gamble
  • 106,424
  • 25
  • 145
  • 137
  • hmm. the standard says the program is only not terminated if the signal handler "does not return". you're quite well with C. can you imagine any scenario that would make it allow continue normal execution without returning? i imagine longjmp, but i'm not sure about how it behaves in signal handlers. – Johannes Schaub - litb Dec 29 '08 at 03:58
  • In general, calling longjmp from a signal handler is undefined but there is a special case for when the signal was generated with raise/abort so I guess this would be theoretically possible although I don't think I have ever seen it done. Now I am going to have to try it ;) – Robert Gamble Dec 29 '08 at 04:23
  • 1
    This seems to work (broken into multiple posts due to 300 char limit): #include #include #include #include volatile sig_atomic_t do_abort = 1; jmp_buf env; void abort_handler(int i) { do_abort = 0; longjmp(env, 1);} – Robert Gamble Dec 29 '08 at 04:36
  • int main(void) { setjmp(env); puts("At setjmp"); if (do_abort) { signal(SIGABRT, abort_handler); puts("Calling abort"); abort(); } puts("Didn't abort!"); return 0; } – Robert Gamble Dec 29 '08 at 04:36
  • On Ubuntu 7.04 this prints: At setjmp Calling abort At setjmp Didn't abort! – Robert Gamble Dec 29 '08 at 04:37
  • i've seen it even support longjmp out of a SIGSEGV :) http://libsigsegv.sourceforge.net/ – Johannes Schaub - litb Jan 10 '09 at 14:39
  • I feel like stream flushing & closing is the most important difference. I don't care if my objects are freed by c++ dtors or the OS, but with IO this can be a big difference. – Quantum7 Aug 12 '10 at 19:07
  • You can call [`_exit`](https://man7.org/linux/man-pages/man2/_exit.2.html) in the signal handler of `SIGABRT`. – ceving Jun 28 '21 at 15:14
7

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.

strager
  • 88,763
  • 26
  • 134
  • 176
  • exit can have multiple callback functions registered via atexit, when exit is called all the callback functions will be called in the reverse order in which they were registered. – Robert Gamble Dec 29 '08 at 03:54
  • @Gamble, Of course, I mentioned that myself a few minutes ago in a comment to @Bondy's answer. I'll edit my own answer to reflect that. – strager Dec 29 '08 at 04:07
6

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.

Federico A. Ramponi
  • 46,145
  • 29
  • 109
  • 133