Topic: Exceptions and Threads?


Author: trickr@uh2372p03.daytonoh.NCR.COM
Date: 5 Nov 93 17:06:02 GMT
Raw View
What should happen to an unhandled C++ exception within a thread?

Should the run-time library exit the process, or exit the thread, or
pass the exception on to the parent process?

I can see arguments for all three approaches, although I prefer the last
approach, and was wondering if anyone had any information on what the
standard says, or what the compiler implementors are considering.



#include <disclaimer.std>




Author: saunders@eisner.decus.org (John Saunders)
Date: 5 Nov 93 18:59:48 -0400
Raw View
In article <CG13I2.CIJ@uc2372c.DaytonOH.NCR.COM>, trickr@uh2372p03.daytonoh.NCR.COM writes:
> What should happen to an unhandled C++ exception within a thread?
>
> Should the run-time library exit the process, or exit the thread, or
> pass the exception on to the parent process?
>
> I can see arguments for all three approaches, although I prefer the last
> approach, and was wondering if anyone had any information on what the
> standard says, or what the compiler implementors are considering.

As has recently been discussed, the standard doesn't mention threads.

Personally, I'd like to see the same thing happen as would happen in a
single-threaded process, whatever that happens to be on the platform you're
using. In an environment that uses signals, I guess the signal would get
passed to the parent? But the parent will not be able to catch the exception,
since it will be asynchronous to the parent.

>
> #include <disclaimer.std>

John Saunders
saunders@eisner.decus.org
(user of POSIX Threads under VMS)




Author: jbn@lulea.trab.se (Johan Bengtsson)
Date: 8 Nov 93 14:42:50 GMT
Raw View
John Saunders (saunders@eisner.decus.org) wrote:
: In article <CG13I2.CIJ@uc2372c.DaytonOH.NCR.COM>, trickr@uh2372p03.daytonoh.NC
R.COM writes:
: > What should happen to an unhandled C++ exception within a thread?
: >
: > Should the run-time library exit the process, or exit the thread, or
: > pass the exception on to the parent process?
: >
: > I can see arguments for all three approaches, although I prefer the last
: > approach, and was wondering if anyone had any information on what the
: > standard says, or what the compiler implementors are considering.

: As has recently been discussed, the standard doesn't mention threads.

: Personally, I'd like to see the same thing happen as would happen in a
: single-threaded process, whatever that happens to be on the platform you're
: using.  In an environment that uses signals, I guess the signal would get
: passed to the parent?

The default behaviour for an unhandled exception is to call
terminate(), which calls abort(), which terminates the program.
Any other behaviour must be programmed, possibly by installing
a user-defined terminate() function, by calling set_terminate().

However, since it is implementation-defined (at least I think it is)
whether set_terminate() applies to a single thread or to all threads,
it might be better to simply catch all exceptions in each thread,
taking appropriate action in the catch(...) block.

:But the parent will not be able to catch the exception,
: since it will be asynchronous to the parent.

Since the exception mechanism works synchronously, the burden of
propagating errors to parent threads must be laid on the programmer.
A similar situation exists for asynchronous signal handlers.  They
cannnot throw exceptions, since it is (in general) not guaranteed that
the current execution thread will be in a stable state.

--
-------------------------------------------------------------------------
| Johan Bengtsson, Telia Research AB, Aurorum 6, S-977 75 Lulea, Sweden |
| Johan.Bengtsson@lulea.trab.se; Voice:(+46)92075471; Fax:(+46)92075490 |
-------------------------------------------------------------------------




Author: db@argon.Eng.Sun.COM (David Brownell)
Date: 13 Nov 1993 18:21:12 GMT
Raw View
(Attributions deleted for brevity:)

> : > What should happen to an unhandled C++ exception within a thread?
>
> : As has recently been discussed, the standard doesn't mention threads.
>
> However, since it is implementation-defined (at least I think it is)

My copy of ARM says in commentary that multithreaded implementations
should have per-thread values of the set_terminate()/set_unexpected()
handlers ... though of course since the draft standard doesn't say it
one way or the other, this would indeed be "implementation defined".

(I missed most of the discussion on this topic, apologies if this
point's been brought up before.)

> whether set_terminate() applies to a single thread or to all threads,
> it might be better to simply catch all exceptions in each thread,
> taking appropriate action in the catch(...) block.

It's clearly better to catch all exceptions at the "top" of each
thread.  Once you deploy code into the field you'd rather have coding
errors such as unhandled exceptions logged (for later fault diagnosis)
and cleaned up as much as possible rather than just aborting the
application and annoying its users by offering them no chance to
attempt their own recovery.

Mixing C and C++ code in a threaded environment is left as an
exercise for the reader:  how do you know the first C++ routine
on a thread's stack, which would presumably be the one in charge
of that "catch (...)"?  Also, how would pthread_cleanup() routines
interact with C++ destructors and exception handlers?  It's safer
to only have C++ code in your threads, or only C code.

- Dave

--
David Brownell                        db@Eng.Sun.COM.
Distributed Object Management





Author: mattw@cssc-syd.tansu.com.au (Matthew Watson)
Date: 15 Nov 1993 18:27:39 +1100
Raw View
jbn@lulea.trab.se (Johan Bengtsson) writes:

>John Saunders (saunders@eisner.decus.org) wrote:
>: In article <CG13I2.CIJ@uc2372c.DaytonOH.NCR.COM>, trickr@uh2372p03.daytonoh.NC
>R.COM writes:
>: > What should happen to an unhandled C++ exception within a thread?
>: >
>: > Should the run-time library exit the process, or exit the thread, or
>: > pass the exception on to the parent process?
>: >
>: > I can see arguments for all three approaches, although I prefer the last
>: > approach, and was wondering if anyone had any information on what the
>: > standard says, or what the compiler implementors are considering.

>: As has recently been discussed, the standard doesn't mention threads.

>: Personally, I'd like to see the same thing happen as would happen in a
>: single-threaded process, whatever that happens to be on the platform you're
>: using.  In an environment that uses signals, I guess the signal would get
>: passed to the parent?

>The default behaviour for an unhandled exception is to call
>terminate(), which calls abort(), which terminates the program.
>Any other behaviour must be programmed, possibly by installing
>a user-defined terminate() function, by calling set_terminate().

>However, since it is implementation-defined (at least I think it is)
>whether set_terminate() applies to a single thread or to all threads,
>it might be better to simply catch all exceptions in each thread,
>taking appropriate action in the catch(...) block.

Not sure about posix, but in Solaris 2.0, signal masks (vaguely analogous
to where to catch an exception) are set on a per thread behaviour, but
signal actions (what to do with an exception) are set globally. Thus we
should expect an uncaught exception to terminate the whole process, since
it implies something you were not expecting to happen. Also, if memory is
allocated to global pointers in a particular thread and only that thread
was killed by an uncaught exception, then you would get massive memory
leaks, potentially held locks, never to be released and no-notification
that an unexpected event had occurred in your process.

>:But the parent will not be able to catch the exception,
>: since it will be asynchronous to the parent.

>Since the exception mechanism works synchronously, the burden of
>propagating errors to parent threads must be laid on the programmer.
>A similar situation exists for asynchronous signal handlers.  They
>cannnot throw exceptions, since it is (in general) not guaranteed that
>the current execution thread will be in a stable state.

And so we would have to make our signal handlers throw no exceptions, and
made our exceptions MT safe??!?!?!?!
--

-------------------------------------------------------------------------------
     -  Matthew Watson -      mattw@cssc-syd.tansu.com.au
-------------------------------------------------------------------------------




Author: mattw@cssc-syd.tansu.com.au (Matthew Watson)
Date: 15 Nov 1993 18:38:22 +1100
Raw View
db@argon.Eng.Sun.COM (David Brownell) writes:

>(Attributions deleted for brevity:)

>> : > What should happen to an unhandled C++ exception within a thread?
>>
>> : As has recently been discussed, the standard doesn't mention threads.
>>
>> However, since it is implementation-defined (at least I think it is)

>My copy of ARM says in commentary that multithreaded implementations
>should have per-thread values of the set_terminate()/set_unexpected()
>handlers ... though of course since the draft standard doesn't say it
>one way or the other, this would indeed be "implementation defined".

>(I missed most of the discussion on this topic, apologies if this
>point's been brought up before.)

>> whether set_terminate() applies to a single thread or to all threads,
>> it might be better to simply catch all exceptions in each thread,
>> taking appropriate action in the catch(...) block.

>It's clearly better to catch all exceptions at the "top" of each
>thread.  Once you deploy code into the field you'd rather have coding
>errors such as unhandled exceptions logged (for later fault diagnosis)
>and cleaned up as much as possible rather than just aborting the
>application and annoying its users by offering them no chance to
>attempt their own recovery.

This is true of non-threaded apps as well. What the original was
discussing (I think, I missed it too) was what to do with uncaught
exceptions. These should by default trash the entire process or you may be
left with unfreed resources in your process which can cause further and
further exceptions until all your pprogram is doing is raising exceptions
and not dying! In a real-time system this would be a total nightmare!

>Mixing C and C++ code in a threaded environment is left as an
>exercise for the reader:  how do you know the first C++ routine
>on a thread's stack, which would presumably be the one in charge
>of that "catch (...)"?  Also, how would pthread_cleanup() routines
>interact with C++ destructors and exception handlers?  It's safer
>to only have C++ code in your threads, or only C code.

Were we talking about this? (Well maybe you were, but I missed it :-). But
the thread library itself is c code.

>- Dave

>--
>David Brownell                        db@Eng.Sun.COM.
>Distributed Object Management

--

-------------------------------------------------------------------------------
     -  Matthew Watson -      mattw@cssc-syd.tansu.com.au
-------------------------------------------------------------------------------