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: