comp.lang.ada
 help / color / mirror / Atom feed
From: Robert A Duff <bobduff@world.std.com>
Subject: Re: Exception Propagation
Date: 1999/06/14
Date: 1999-06-14T00:00:00+00:00	[thread overview]
Message-ID: <wccd7yyrgfu.fsf@world.std.com> (raw)
In-Reply-To: 7jlud1$l76$1@nnrp1.deja.com

dennison@telepath.com writes:

> What I was trying to say is that an exception is *not* propagated into
> any task other than the one it occurred in (except in a rendezvous). If
> I were to create language TERD, which did have that behavior, then in
> TERD it would be completly non-deterministic in the parent task where an
> exception raised from the child task popped up.

Not necessarily.  Tasks synchronize with their parent whenever a master
is left.  It would make sense to say that at that point, if any
dependent tasks died due to unhandled exception, the parent task then
raises Tasking_Error (or Program_Error)?  Of course, this catches the
error rather late, but at least it's not totally ignored.

Another idea would be to abort the siblings, and then raise
Tasking_Error.

But Robert Dewar's idea is best, I think: An unhandled exception in
*any* task kills the whole program (hopefully with an error message).

It should be a strict language design principle: "Unhandled exceptions
never get lost."  Or, "The default behavior for run-time errors should
be to stop the program".  How many times have I run a shell script that
printed out an error message, and then continued to bumble along in a
confused manner, destroying the evidence and/or valuable data?  At least
Ada doesn't do that in *most* cases.

But Ada does has several other similar cases.  For example, an unhandled
exception in an interrupt handler is lost.  Instead, it should kill the
whole program.  As Robert pointed out, this puts the burden on the
programmer (where it belongs); if the programmer doesn't want the whole
program to die, then an exception handler is called for.

Another example: an unhandled exception in a Finalize procedure.  This
case isn't asynchronous, but it has similar problems: many Finalize
procedures are happening "together", and if two of them die, we don't
know what to do, so we raise Program_Error.  The rules for exactly what
happens when are way too complicated (I wrote them), and they're
extremely difficult to implement efficiently.  I think it would have
been better if the default behavior for Finalize would be to kill the
program; if the programmer wants some other behavior, write a handler.

Another example: Storage_Error.  It can happen pretty much anywhere, so
it's really asynchronous, in a sense.  You can pin it down if you look
at the machine code, but just looking at the semantics of a given Ada
program, it's impossible to predict where it might raise Storage_Error,
so there's not much a program can do about it.

>... Therefore there would be
> no good way to handle and recover from exceptions in child tasks. That's
> probably one reason why the designers of Ada did not do that! In Ada
> tasks can only get exceptions from themselves or from tasks they
> rendezvous with during the rendezvous. 

Not quite true -- if a child dies before its "begin", then the exception
is propagated to the parent.  (Well, it's not really "propagated",
because it turns into Tasking_Error, because it could happen more than
once simultaneously.)

All these cases where exceptions get turned into Tasking_Error or
Program_Error are fairly useless to handle in most cases -- all the
handler knows is "something went wrong".

>...That makes it quite
> deterministic.

That's the key...

> As for warning you that a task died, in my experinece most compilers do
> *not* do that. Whether that is from concerns about synchronizing writes
> to standard output, or from sheer lazieness I can't say. But I know that
> both Gnat and GreenHills behave that way, and I suspect ObjectAda does
> as well.

I'm not sure why, either.  I guess people just say, well, the RM says
it's not an error, so no error message is warranted.  Or maybe people
are afraid of failing the ACVC if they give an error message in a
non-error situation (I'm not sure they would...), which means you need
two different modes, which adds complexity, which maybe isn't worth it.

> If you *do* write such code in last-ditch handlers on your tasks, make
> sure to handle the IO synchronization problem yourself, or you are
> liable to get interspersed output, or different exceptions than the ones
> you are looking for.

Hmm.  Maybe.  But the more complicated you make that exception-handling
code, the more likely that *it* will have the same problem -- and whose
going to handle exceptions in the exception handler?

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




  reply	other threads:[~1999-06-14  0:00 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-06-07  0:00 Exception Propagation Decker, Christian R
1999-06-07  0:00 ` dennison
1999-06-08  0:00   ` Glen
1999-06-08  0:00     ` Decker, Christian R
1999-06-08  0:00       ` Robert Dewar
1999-06-08  0:00       ` David C. Hoos, Sr.
1999-06-09  0:00       ` dennison
1999-06-14  0:00         ` Robert A Duff [this message]
1999-06-14  0:00           ` dennison
1999-06-15  0:00             ` Robert A Duff
1999-06-14  0:00           ` Bryce Bardin
1999-06-15  0:00           ` Dale Stanbrough
1999-06-15  0:00             ` Robert A Duff
1999-06-08  0:00     ` dennison
1999-06-08  0:00     ` Robert Dewar
1999-06-09  0:00       ` Matthew Heaney
1999-06-08  0:00         ` R. Tim Coslet
1999-06-09  0:00         ` Robert Dewar
1999-06-09  0:00         ` dennison
  -- strict thread matches above, loose matches on Subject: below --
2006-03-15 15:16 Exception propagation REH
2006-03-16 21:29 ` Ludovic Brenta
2006-03-16 22:19   ` REH
2006-03-16 22:51     ` Ludovic Brenta
2006-03-17  2:52       ` REH
2006-03-17 14:52         ` Georg Bauhaus
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox