Resumable exceptions bad: (was Re: Comparison with False - something I don't understand)

John Nagle nagle at animats.com
Mon Dec 6 14:23:15 EST 2010


On 12/6/2010 12:40 AM, Steve Holden wrote:
> On 12/6/2010 9:14 AM, Paul Rubin wrote:
>> mdw at distorted.org.uk (Mark Wooding) writes:
>>> The most obvious improvement is resumable exceptions.
>>
>> You know, I've heard the story from language designers several times
>> over, that they tried putting resumable exceptions into their languages
>> and it turned out to be a big mess, so they went to termination
>> exceptions that fixed the issue.  Are there any languages out there with
>> resumable exceptions?  Escaping to a debugger doesn't really count as
>> that.  I guess one way to do it would be call a coroutine to handle the
>> exception, and either continue or unwind after the continue returns, but
>> doing it in a single-threaded system just seems full of hazards.
>
> I seem to remember PL/1 has resumable exceptions, but I don't ever
> remember finding a real use for them. And it's so long since I used PL/1
> I may be mistaken.

     Resumable exceptions were a popular idea in the early days of 
programming.  LISP, PL/I, and early COBOL had constructs which
could be considered resumable exceptions.  They didn't work out
well, because the exception handler gets control in an ambiguous
situation, perhaps in the middle of an expression.  Changing
the state of the execution, then returning, can leave the program
in an invalid state.

     Signal handling has many of the same problems.  A POSIX signal
is a forced subroutine call while something else is going on,
which is in itself a weird concept.  That's what a resumable
exception looks like.  CPython has a terrible time with signal
handling.  See "http://www.dabeaz.com/python/UnderstandingGIL.pdf"
for the whole ugly mess.  That's why control-C won't terminate
multi-thread programs, among other things.

     Unwinding cleanly from a signal is difficult, but possible
with proper CPU and compiler design.  It's done right in Ada, and
in Visual C++ for x86 on Windows.  Only some CPUs support "exact"
floating point exceptions, where you're guaranteed that the
exception comes in at the point where the problem occurred.
In modern superscalar CPUs, the exception comes in several
instructions after the problem was detected.  In x86 type
CPUs, the CPU hardware in the "retirement unit" backs up the
CPU state to the point at which the exception was detected.
PowerPC and SPARC CPUs do not do this; if you need exactness
in exception position on them, you have to put in "fence" instructions
to stop lookahead.  This costs performance.

     As a result, C code which unwinds from signals via "longjmp"
is not portable.
See 
"https://www.securecoding.cert.org/confluence/display/seccode/SIG32-C.+Do+not+call+longjmp%28%29+from+inside+a+signal+handler"
Nor is changing the program state from inside a signal handler.
You're not entirely sure, on many CPUs, where control is at the
point the signal came in.

     (In a physics simulator, I once had to handle floating point
overflow, which indicated that the computation had to be backed
up and rerun with a smaller time step.  It's possible to do this
safely under Windows on x86 if you read all the appropriate documents.
It's not portable.  That's why I'm aware of this mess.)

     So that's why resumable exceptions are a bad idea.

					John Nagle



More information about the Python-list mailing list