6

Is there a need to explicitly flush output streams before calling abort() to avoid loss of output?

As I understand, with stderr there is no buffering, so calling abort after output to stderr/cerr should be ok. How about stdout/cout, or files that I open?

PS. I am working in Linux environment (if it matters).

user2052436
  • 4,321
  • 1
  • 25
  • 46

2 Answers2

12

Yes, it's needed, but no, it may not be possible. If you're aborting from an async-signal context, calling fflush invokes undefined behavior. And in general, if the reason for calling abort is that you've detected inconsistent state in your program, there's a risk that stdio state is also corrupted, and that calling fflush is therefore unsafe.

In general, you should use exit(1) if you're terminating due to a condition that your program simply can't handle, and use abort() (without fflush) only when you have detected that your program invoked undefined behavior already,

Some more details:

The C standard allows an implementation to flush stdio streams as part of abort (C11 7.22.4.1:):

Whether open streams with unwritten buffered data are flushed, open streams are closed, or temporary files are removed is implementation-defined.

However, this does not remove the requirement that abort work if called from a signal handler. Since, from a practical standpoint, it's usually impossible to flush buffers if abort is being called from a signal handler that interrupted stdio code that has the buffer in an inconsistent state, any implementation that attempts to use this allowance is likely to be buggy.

The current version of the Linux man page for abort incorrectly states:

If the abort() function causes process termination, all open streams are closed and flushed.

A more correct statement of the current behavior would be that flushing is attempted but may fail or corrupt your data. This bug is presently in the process of being fixed in glibc (maybe the fix was already committed...?) according to this thread:

http://www.sourceware.org/ml/libc-alpha/2013-05/msg00207.html

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • Does abort flush kernel buffers only, or stdio buffers in user space as well? – user2052436 Aug 19 '13 at 16:09
  • I am writing scientific code with MPI, and OpenMP threads. And if I encounter an error (typically user-input related, or some run-time computations related), I just want to quit my program. The reason I asked initial question is that I want my log files, which contain info and error descrption, to be flushed before my program terminates. So from your answer follows, that I do not need to use `abort`, `exit(EXIT_FAILURE)` will suffice? – user2052436 Aug 19 '13 at 16:14
  • @user2052436: As far as observable behavior, there is no such thing as a kernel buffer. – R.. GitHub STOP HELPING ICE Aug 19 '13 at 16:39
  • 1
    @user2052436, yes `exit(EXIT_FAILURE)` should largely suffice to capture user errors. `abort` should only be used for more dramtic cases. e.g if you detect that your application runs completely out of memory. – Jens Gustedt Aug 19 '13 at 16:40
  • @JensGustedt: I would argue that both `abort` and `exit(1)` are *bad behavior* for running out of memory. There's really no need to prefer `abort` here, since the program is in a state where it's still safe to call `exit`, but `abort` may be slightly less malicious since the calling code could perhaps catch `SIGABRT` and `longjmp` out of the bad code that's aborting on out-of-memory. :-) If you do use `abort` in non-UB situations like this, I think it's a good idea to call `fflush(0)` first. – R.. GitHub STOP HELPING ICE Aug 19 '13 at 16:48
0

Stdout is buffered and so are the file you open with ofstream for example. You have to explicitly flush them using the flush manipulator

cyberz
  • 884
  • 1
  • 8
  • 16
  • While this is true most of the time, it _is_ possible to open a file without buffering, and I believe it might even be possible to get an unbuffered `stdout` with some trickery. – arne Aug 19 '13 at 15:34
  • 1
    Just use `setvbuf` or `setbuf` at the beginning of `main` to get unbuffered `stdout`. – R.. GitHub STOP HELPING ICE Aug 19 '13 at 15:36