This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: catch(...) and forced unwind


On Sat, 13 Dec 2003 19:59:09 -0800, Nathan Myers <ncm@cantrip.org> wrote:

> On Sat, Dec 13, 2003 at 08:20:15AM -0500, David Abrahams wrote:
>> Jason Merrill <jason@redhat.com> writes:
>> 
>> > On Fri, 12 Dec 2003 17:42:27 -0500, David Abrahams 
>> >
>> >> 2. There is some documentation somewhere which indicates that one of
>> >>    the functions called by tf is a "cancellation point" (i.e. may
>> >>    throw thread cancellation exceptions).  Otherwise, it seems to me,
>> >>    "this high-level behavior" would not be wrong.
>> >
>> > Basically, all of the C library I/O functions are cancellation points.
>> 
>> Well, I constider that very surprising. It harms the ability to write
>> portable code, for reasons explained below.
>
> Indeed, it's commmon to declare external C functions "throw()", meaning
> no exceptions can ever come out of them, and expect the compiler to 
> optimize accordingly.

And g++ does.  I'm not sure at the moment what we do when a forced unwind
tries to unwind through a throw(); things don't seem to be working
properly on my laptop at the moment.  I suspect that we fall back on the
old semantics, i.e. run explicitly pushed cleanups and kill the thread.

>> > I don't expect writing 'cout << "."' to suppress thread cancellation.
>> > Do you disagree that this is an extremely surprising side-effect?
>> 
>> Yes, I disagree that it's surprising.  I know that iostream operations
>> won't throw unless you set badbit, and I therefore expect them not to
>> throw.  

Aha.  I didn't realize that the disagreement was so basic.

> Not throwing is part of iostream's contract.  For the runtime system
> to arbitrarily change that contract makes any code written to the old 
> contract indeterminate and likely wrong.

I don't see any such contract.

  17.4.4.8  Restrictions on              [lib.res.on.exception.handling]
       exception handling

2 None of the functions from the Standard  C  library  shall  report  an
  error by throwing an exception,176) unless it calls a program-supplied
  function that throws an exception.177)

3 No destructor operation defined in the C++ Standard Library will throw
  an exception.  Any other functions defined in the C++ Standard Library
  that  do not have an exception-specification may throw implementation-
  defined  exceptions  unless otherwise specified.178)

This passage seems to give the implementation the latitude to throw an
implementation-defined exception from any of the iostream functions, since
none of them are specified throw().

>> Furthermore, throwing against the standard's guarantees undermines
>> portability.  All code which can run in a cancellable thread now has
>> to have special knowledge of the behavior of the system it's running
>> on.  That could mean, for example, that people can't pick up the Boost
>> libraries and use them inside of a thread.  This effect is bad with
>> functions people don't *expect* to throw (the C I/O) but the standard
>> does allow those to throw implementation-defined exceptions.  It's
>> *really really* bad with functions the standard guarantees won't
>> throw.

Actually, this is backwards -- the standard doesn't allow the C I/O
functions to throw any exceptions; see the passage above.  This obviously
needs to change if we're going to do anything useful with POSIX thread
cancellation.

>> I think it's not the nature of the exception, but the fact that you're
>> running in a thread which makes it "outside the scope", since the
>> standard doesn't cover threading.  Still, the ability to use code in
>> threads which was written without knowledge of your threading system,
>> I would think, is crucial.

Oh, I agree.  I'm just skeptical that iostream code throwing a cancellation
exception would interfere with this ability.

> The population of coders willing to write code just for this one
> threading system is necessarily small.

Which one?  POSIX threads?  I hear they're pretty widespread.  But
seriously, we have a number of customers writing code for that threading
system, and asking for this functionality.

> This is a difference from the C world.  With C, no one expects a library 
> to work right in a threaded program if it wasn't written with that target 
> in mind.  Contrarily, C++ users routinely expect portable C++ libraries 
> to be exception- and thread-safe, and an enormous amount of such code
> has already been written that is.  Changing the semantics of exception 
> handlers breaks it all.

Nathan, you seem to assume that I'm advocating implicit rethrow.  I'm not.
I'm only suggesting that cancellation should propagate out of iostream
code, and suggested several ways that might happen.

Both your and David's replies seem to have amounted to saying that any
change to current behavior is unacceptable.  That isn't very useful.  Just
to step back a moment, can we all agree that we want pthread cancellation
to run C++ cleanups?  And that we might have to adjust a few things to make
that work?

> In the meantime, the ISO committee is discussing a standard threads
> library for C++, including a cancellation model incompatible with what
> is being proposed here.  It would be better for everybody involved for 
> Gcc to match it.

Please elaborate.  I don't see a relevant paper in any of the recent
mailings.

Jason


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]