Section: 17.5 [support.start.term], 17.9.5 [exception.terminate] Status: New Submitter: JF Bastien Opened: 2018-03-15 Last modified: 2024-07-26
Priority: 3
View other active issues in [support.start.term].
View all other issues in [support.start.term].
View all issues with New status.
Discussion:
It's unclear how different termination facilities in C++ interact (and how they interact with the C
termination facilities). Individually some of these functions try to handle corner cases, but hilarity
ensues when combined with each other. As a simple example, can an atexit handler call exit?
If not, can it call quick_exit, and can then at_quick_exit handler call exit?
Is it possible to install an atexit handler from an at_quick_exit, without strongly
happens before, while handling a separate atexit handler (and what happens then)?
returning from main calls atexit handlers.
atexit / exit
at_quick_exit / quick_exit
set_terminate
violating noexcept and other things that call std::terminate (see
[except.terminate])
violating exception specification
parallel algorithms leaving with uncaught exception
some std::signal such as SIGTERM, SIGSEGV, SIGINT,
SIGILL, SIGABRT, and (maybe?) SIGFPE.
set_unexpected (now a zombie)
unexpected_handler (now a zombie)
What's unclear is:
Is termination handling a DAG?
Which thread(s) are termination handlers called on?
Is program termination Turing complete?
I've written a sample program which exercises some of this, see here.
[2018-04-02, Jens comments]
Any potential wording should carefully take [basic.start] into account, and maybe should actually be integrated into the core wording, not the library wording.
[2018-04-02 Priority set to 3 after discussion on the reflector.]
[2024-07-26; Jonathan comments]
In C89 and C99 the spec for exit in C said
"If more than one call to the exit function is executed by a program,
the behavior is undefined."
Since C11 that was updated to also talk about at_quick_exit, saying
"If a program calls the exit function more than once,
or calls the quick_exit function in addition to the exit function,
the behavior is undefined." The spec for quick_exit is similar.
That answers most of the questions here. An atexit or at_quick_exit
handler cannot call exit or quick_exit, because if a handler is running
then it means that exit or quick_exit has already been called,
and calling either of them again would be undefined.
It doesn't matter whether an atexit handler installs an at_quick_exit
handler, because once exit handlers start running
it would be undefined to call quick_exit, and vice versa. So you should never
have a situation where both sets of handlers are running.
There is a suggestion
to relax this in POSIX so that calling exit or quick_exit again from other
threads would not be UB but would just block until the process exits,
which should happen eventually assuming exit handlers make forward progress
(calling exit or quick_exit from a handler would still be UB).
Why does C++ not make it undefined to call exit twice? Can we change that?
Proposed resolution: