Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

_exit() and destructors

2 views
Skip to first unread message

Michi Henning

unread,
Aug 3, 2007, 11:36:14 AM8/3/07
to
Hi,

I'm in a situation where I have to terminate a threaded program
in response to a signal. I can't call exit() because that has
undefined behavior for a threaded program, so I'm calling _exit().

This works fine. No destructors run, and the process just goes away
without further ado, just as I want it to.

What I find troubling though is that I cannot find any guarantee in
the spec to say that destructors won't run if I call _exit().

Should there be such a guarantee?

Failing that, what else does or could the spec provide to deal with
this scenario?

Thanks,

Michi.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Steve Clamage

unread,
Aug 3, 2007, 3:38:04 PM8/3/07
to
On 08/03/07 08:36, Michi Henning wrote:

> I'm in a situation where I have to terminate a threaded program
> in response to a signal. I can't call exit() because that has
> undefined behavior for a threaded program, so I'm calling _exit().
>
> This works fine. No destructors run, and the process just goes away
> without further ado, just as I want it to.
>
> What I find troubling though is that I cannot find any guarantee in
> the spec to say that destructors won't run if I call _exit().
>
> Should there be such a guarantee?
>
> Failing that, what else does or could the spec provide to deal with
> this scenario?

The C++ Standard says nothing about the _exit() function, and neither
does the C standard.

The _exit() function is a standard Unix (and POSIX) function, but the
SIngle Unix Standard (SUS) says nothing about its effects on operations
that are specific to C++. (SUS says nothing about C++.)

SUS takes 2 pages to describe the differences between exit() and
_exit(). Briefly: When you call _exit(), functions registered with
atexit() are not called. There are complicated issues regarding the
status of signals, child processes, and Unix I/O.

Some C++ implementations use atexit() registration for static
destructors. In those implementations, destructors for static objects
will not be called if you call _exit().

Not all systems are Unix-compliant, of course.

The short answer is that you can't depend on portable behavior when
calling _exit(). You can review the documentation for the compiler and
OS to see whether its effects on C++ programs are discussed.

---
Steve Clamage
Sun Microsystems

Daniel Krügler

unread,
Aug 14, 2007, 11:03:07 AM8/14/07
to
On Aug 3, 9:38 pm, Steve Clamage <stephen.clam...@sun.com> wrote:
> The short answer is that you can't depend on portable behavior when
> calling _exit(). You can review the documentation for the compiler and
> OS to see whether its effects on C++ programs are discussed.

Concerning the guarantees related to atexit and signals the OP should
use the new C99 function _Exit:

"The _Exit function causes normal program termination to occur and
control to be returned to the host environment. No functions
registered
by the atexit function or signal handlers registered by the signal
function
are called. The status returned to the host environment is determined
in
the same way as for the exit function (7.20.4.3). Whether open
streams
with unwritten buffered data are flushed, open streams are closed,
or temporary files are removed is implementation-defined."

Of course there exist no behaviour descriptions under multi-threaded
conditions, since they are not (yet) described by neither C nor C++.

Greetings from Bremen,

Daniel Krügler

James Kanze

unread,
Aug 14, 2007, 3:09:59 PM8/14/07
to
On Aug 14, 5:03 pm, Daniel Krügler <daniel.krueg...@googlemail.com>
wrote:

> On Aug 3, 9:38 pm, Steve Clamage <stephen.clam...@sun.com> wrote:

> > The short answer is that you can't depend on portable behavior when
> > calling _exit(). You can review the documentation for the compiler and
> > OS to see whether its effects on C++ programs are discussed.

> Concerning the guarantees related to atexit and signals the OP should
> use the new C99 function _Exit:

> "The _Exit function causes normal program termination to occur
> and control to be returned to the host environment. No
> functions registered by the atexit function or signal handlers
> registered by the signal function are called. The status
> returned to the host environment is determined in the same way
> as for the exit function (7.20.4.3). Whether open streams with
> unwritten buffered data are flushed, open streams are closed,
> or temporary files are removed is implementation-defined."

It's interesting to note that _Exit isn't mentioned in
[support.start.term] of the current draft yet. It should be:
the statement (concerning <cstdlib>) that "The contents are the
same as the Standard C library header[...]" suggests that it
should be present, but it isn't mentioned explicitly, and like
exit(), it probably needs some special handling. (A priori,
given that we expect destructors to be ordered with respect to
functions registered with atexit, and _Exit doesn't call those,
I would expect that it not call destructors either. But without
specific language to this effect, who knows?)

> Of course there exist no behaviour descriptions under
> multi-threaded conditions, since they are not (yet) described
> by neither C nor C++.

And the obvious answer is: calling exit() or _Exit() when
any thread other than the calling thread is still active is
undefined behavior. I think anything else would be a lot of
effort, and probably not worth it. (And not doable in the
available time.)

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Steve Clamage

unread,
Aug 14, 2007, 2:09:23 PM8/14/07
to
On 8/14/2007 8:03 AM, Daniel Krügler wrote:
> On Aug 3, 9:38 pm, Steve Clamage <stephen.clam...@sun.com> wrote:
>> The short answer is that you can't depend on portable behavior when
>> calling _exit(). You can review the documentation for the compiler and
>> OS to see whether its effects on C++ programs are discussed.
>
> Concerning the guarantees related to atexit and signals the OP should
> use the new C99 function _Exit

But that has the same problem as _exit -- not available on all systems,
C++ is not C99, and the description of _Exit does not say anything about
C++.

> ...


>
> Of course there exist no behaviour descriptions under multi-threaded
> conditions, since they are not (yet) described by neither C nor C++.

Exactly.

I think what the OP wants is abort(). The C++ standard currently does
not discuss behavior of multi-threaded programs, but abort() exits
without calling any destructors.

---
Steve Clamage
Sun Microsystems

---

Daniel Krügler

unread,
Aug 14, 2007, 7:41:48 PM8/14/07
to
On 14 Aug., 21:09, James Kanze <james.ka...@gmail.com> wrote:
> It's interesting to note that _Exit isn't mentioned in
> [support.start.term] of the current draft yet. It should be:
> the statement (concerning <cstdlib>) that "The contents are the
> same as the Standard C library header[...]" suggests that it
> should be present, but it isn't mentioned explicitly, and like
> exit(), it probably needs some special handling. (A priori,
> given that we expect destructors to be ordered with respect to
> functions registered with atexit, and _Exit doesn't call those,
> I would expect that it not call destructors either. But without
> specific language to this effect, who knows?)

IMO you are right, that it *should* be added, but exactly due to the
above quoted current description "same as the Standard C library"
it seems currently *not* to be indented. This is only a very
subjective
interpretation of mine inspired by the two seperate paragraphs 2 and
3
of [intro.refs] in N2369:

"2 The library described in clause 7 of ISO/IEC 9899:1990 and clause
7
of ISO/IEC 9899/Amd.1:1995 is hereinafter called the Standard C
Library. 1)

3 The library described in clause 7 of ISO/IEC 9899:1999 and clause 7
of ISO/IEC 9899:1999/Cor.1:2001 and clause 7 of ISO/IEC 9899:1999/Cor.
2:2003
is hereinafter called the Standard C99 Library."

This differentiation seems to mean that _Exit shall not be part of the
new C++ standard. And yes, if _Exit would be included, the special
destructore handling must be explicitley mentioned (and probably
skipped similar to atexit-registered functions)

Greetings from Bremen,

Daniel

Bjørn Roald

unread,
Aug 14, 2007, 8:58:24 PM8/14/07
to
Steve Clamage wrote:
> I think what the OP wants is abort(). The C++ standard currently does
> not discuss behavior of multi-threaded programs, but abort() exits
> without calling any destructors.

He did want something similar to abort(), yes. At least from postings
in comp.lang.c++.moderated. But the problem with abort() was that he
need the process to return with success.

--
Bjørn

Daniel Krügler

unread,
Aug 15, 2007, 8:22:37 PM8/15/07
to
Just for the record: After reading the current proposal

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2383.html

it seems that it addresses exactly the here discussed problem.
The relevant function seems to be the newly proposed quick_exit
function in combination with another new function at_quick_exit
to register functions which need to be executed even
under quick_exit conditions (these functions are *only* invoked if
quick_exit is called and destructors are *not* invoked!).

Greetings from Bremen,

Daniel Krügler


Anders Dalvander

unread,
Aug 16, 2007, 3:33:20 AM8/16/07
to
On Aug 16, 2:22 am, Daniel Krügler <daniel.krueg...@googlemail.com>
wrote:

> Just for the record: After reading the current proposal
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2383.html

> Add a new paragraph 15,
>
> Returns: The at_quick_exit() function does not return.

at_quick_exit should return, quick_exit should not.

// Anders Dalvander

Michi Henning

unread,
Aug 22, 2007, 1:03:22 AM8/22/07
to
Daniel Krügler wrote:
> Just for the record: After reading the current proposal
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2383.html
>
> it seems that it addresses exactly the here discussed problem.

Yes, that is exactly what I'm looking for. This would solve the problem
beautifully. quick_exit() should probably be explicitly marked as
async-signal-safe, because a common case is to want to call this from
a signal handler.

Cheers,

Michi.

0 new messages