This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: catch(...) and forced unwind
- From: David Abrahams <dave at boost-consulting dot com>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: Jason Merrill <jason at redhat dot com>, Matt Austern <austern at apple dot com>, Ulrich Drepper <drepper at redhat dot com>, gcc at gcc dot gnu dot org, Richard Henderson <rth at redhat dot com>, Nathan Myers <ncm at cantrip dot org>, Jakub Jelinek <jakub at redhat dot com>, wekempf at cox dot net, fjh at cs dot mu dot oz dot au, Benjamin Kosnik <bkoz at redhat dot com>
- Date: Wed, 17 Dec 2003 11:57:07 -0500
- Subject: Re: catch(...) and forced unwind
- References: <xypwu91ofvf.fsf@miranda.boston.redhat.com><ud6at1wvg.fsf@boost-consulting.com><xypekv9nr9u.fsf@miranda.boston.redhat.com><u65gkyhv4.fsf@boost-consulting.com><20031214035909.GE2416@tofu.dreamhost.com><xypk74xltaa.fsf@miranda.boston.redhat.com><ullpdlksl.fsf@boost-consulting.com><xyp1xr5lh5q.fsf@miranda.boston.redhat.com><usmjlhryu.fsf@boost-consulting.com><278A5A0A-3001-11D8-8564-00039390D9E0@apple.com><usmjkbkb5.fsf@boost-consulting.com><0BB52C3C-3009-11D8-8564-00039390D9E0@apple.com><ud6aobfgy.fsf@boost-consulting.com><A156A7B0-3012-11D8-8564-00039390D9E0@apple.com><uu1409v32.fsf@boost-consulting.com><xypd6aoi0zz.fsf@miranda.boston.redhat.com><1071632782.3793.114.camel@minax.codesourcery.com><u4qvz8zae.fsf@boost-consulting.com><1071678864.4082.22.camel@minax.codesourcery.com>
Mark Mitchell <mark@codesourcery.com> writes:
> On Wed, 2003-12-17 at 03:22, David Abrahams wrote:
>> Mark Mitchell <mark@codesourcery.com> writes:
>>
>> > (3) The thread_cancellation objects contain a reference count; copying
>> > the object increments the reference count and destroying the object
>> > decrements the reference count. If the reference count goes to zero (as
>> > would happen when the exception is caught and not rethrown) the thread
>> > is uncancelled.
>>
>> If "uncancelled" doesn't mean "re-deferred", I don't see the point of
>> the reference count. How is the "uncancelled" case different from
>> the one where a copy of the thread_cancellation object is kept alive
>> indefinitely, i.e.
>>
>> catch (posix::thread_cancellation& x)
>> {
>> some_stack.push(new (nothrow) thread_cancellation(x));
>> }
>
> I'm not sure exactly what you're getting at here.
>
> I was looking for semantics like auto_ptr.
>
> In particular, as long as you hold on to the thread_cancellation object
> things are as if you are in a POSIX thread cancellation handler --
> nothing is a cancellation point.
I get it.
> Consider this code:
>
> posix::thread_cancellation* p = NULL;
> try { }
> catch (posix::thread_cancellation& x) {
> // Continue with the code outside this catch block, but
> // as if we are in a thread cancellation handler.
> p = new (nothrow) posix::thread_cancellation (x);
> // x is destroyed as we leave this scope.
> }
> // Do some more stuff.
> ...
> // Now rethrow the cancellation exception.
> if (p)
> throw *p;
>
> If, on the other hand, you let go of all references to the
> thread_cancellation object, then you decided you do not want to be
> cancelled at all.
*This time*. Because by letting go of the cancellation object, you
re-enable cancellation points. That's kind of an odd paradox isn't
it?
>> I'm not convinced there's a better solution, but it seems to me that
>> this could be a disaster for the ability to freely use C++ libraries
>> in threads without knowing something about their implementations.
>
> I don't think there is any way to combine C++ and POSIX threads such
> that all existing thread-safe, exception-safe C++ libraries will work in
> the presence of cancellation. Fundamentally, the idea of cancellation
> means that you have to audit your entire library before using it in a
> thread. That's not news:
It's news to me, but then I haven't been paying too enough attention
to threading issues ;-)
> the same problems come up with cooperating processes in the presence
> of signals. A correct program, written for an environment without
> SIGTERM, must be audited before being deployed in an environment
> with SIGTERM.
Yeah, but signals were fundamentally different from exceptions until
the posix/c++ standard conflict about which functions can throw arose.
> My proposal gives two operating modes for the combination of POSIX
> threads and C++.
>
> In one mode, the C++ thread sees a conforming C++ environment (i.e., one
> in which "printf" never throws exceptions). Stack unwinding will not be
> done in that environment, so if such a thread is cancelled, it will not
> get a chance to clean up after itself.
Y'know, I don't like that. It doesn't give people the choice to add
explicit cancellation checks to a codebase while preserving the C++
standard behavior of functions that don't throw. If I was trying to
import some generally-threadsafe code to a threaded environment,
looking for a few places where it's safe to throw cancellations would
be my first strategy.
> For many threads, that will be OK, just as it is OK for many
> processes not to have a SIGTERM handler. In this situation, you
> have to audit your C++ code to make sure that it is safe for it to
> go away without running cleanups.
>
> In the other mode, the C++ thread sees a non-conforming environment, in
> that some C library functions can throw exceptions. In some cases,
> simply writing exception-safe code around such calls may be good
> enough. In the general case, the library will have to be modified to
> know about the idea of cancellation exceptions and take appropriate
> action. No surprise, that; lots of programs need modification to deal
> with SIGTERM. In this situation, you have to audit your C++ code to
> make sure you've handled all the cancellation points correctly.
>
> There's no way to avoid having to do an audit, but you can pick which
> audit you have to do.
>
>> Is it worth considering adding a mechanism which turns off
>> cancellation exceptions during unwinding? I realize it's a
>> half-measure, but at least it would prevent some printf logging code
>> from sending us to terminate.
>
> I think this is a good suggestion. It is orthogonal to my proposal,
> though.
Yes, I recognize that. Well, not completely orthogonal. If we were
just going to override Posix with C++ against your advice, my
suggestion would be pointless.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com