Hi Jeff,
Mystery solved, suggested fix below.
I caught another of those exceptions on linux-x86 (although from a
different thread) yesterday and this time I got a core dump:
epics> CA client library tcp receive thread terminating due to a C++ exception
FATAL: exception not rethrown
Abort (core dumped)
Unfortunately the backtrace didn't give me any clues where the exception
was thrown from, but it was very repeatable. I tried deriving all your
exception classes from std::exception, but still only ever hit the last
resort exception handler, so I knew it wasn't something you were throwing.
Finally I Googled the above "FATAL:" error message, and found the
following posting:
From: Boris Kolpackov <[email protected]>
Newsgroups: comp.programming.threads
Subject: Re: "exception not rethrown" problem
Date: Thu, 15 Jun 2006 08:26:18 +0000 (UTC)
"D'artagnan" <[email protected]> writes:
I'm using Pthreads in a C++ program that uses exceptions. When one
thread is cancelled (cancellation state is deferred) by the main
thread, it throws some mysterious exception which cannot even be caught
by "catch(...)". The program aborts with the following error message:
FATAL: exception not rethrown
Abort
Anybody have ideas how to avoid this problem? Specifically, how to
catch the cancellation exception, or how to ignore it? Thanks a lot.
I am pretty sure you are using NPTL on GNU/Linux. NPTL implements
thread cancellation by throwing an (implementation-defined) exception
that you are not allowed to finalize (i.e., you can catch it but you
have to rethrow). The problem is that you cannot identify this
exception in your C++ program. If all your exceptions are derived from
one base or a set of base exceptions, then you can write something
like this:
extern "C"
void*
thread_func (void*)
{
try
{
...
}
catch (std::exception const&)
{
// Handle application exceptions here.
}
catch (...)
{
// Assuming thread cancellation - must rethrow.
throw;
}
}
By adding a 'throw;' statement to the end of the 'catch ( ... )' block
in tcpiiu.cpp I can prevent the FATAL message, but I then get an error
from epicsThread::epicsThreadCallEntryPoint instead, and I still see the
message from
epics> CA client library tcp receive thread terminating due to a C++ exception
epicsThread: Unknown C++ exception in thread "CAC-TCP-recv" at Tue Dec 19 2006 16:56:15.182832000
There's a lot more discussion about this topic on the c++-pthreads
mailing list, and in fact a huge thread from last July that starts here
talks about how this issue might be solved, although I don't think they
came to a final conclusion:
http://www.codesourcery.com/archives/c++-pthreads/msg00324.html
The upshot of this is that on Linux using NPTL there is currently no way
to portably use pthread_cancel() with a C++ program because on NPTL the
pthread_cleanup_push/pop mechanism is coded using the C++ exception
mechanism. Our posix implementation of osdThread.c registers an
atexit() handler which calls pthread_cancel() for each of the threads we
have started, thus confirming that we're in exactly the situation that
is recognizably broken on Linux.
I have a suggestion for our code: I'd like to introduce a new macro into
epicsThread.h (which will be overridden in os/linux/osdThread.h) called
something like epicsThreadRethrow (better name welcomed). On linux this
will expand to 'throw', and to something like '(void)0' in all other
implementations. We then suggest that this be placed in all last-ditch
catch clauses after any necessary cleanup operations but before printing
warning messages. The result will be to suppress those warning messages
on Linux since we expect this exception at thread closedown.
This does mean that we should change all our exception classes to derive
from std::exception (or from our own standard exception class preferably
based on std::exception) in order to be able to identify them when
caught, since we can't rely on the last-ditch handler on Linux. I don't
think we should do this for R3.14.9 since it's going to need some
development work, but it should be a goal for the next release.
Comments, questions, objections?
There may be another solution on NPTL that avoids rethrowing the
exception, but it still requires inserting code into all last-ditch
exception handlers to suppress the FATAL: message, as it doesn't prevent
the exception from being thrown in the first place. I don't think it's
possible to distinguish a cancellation exception, although that would be
the best solution if someone can work out how to do that.
- Andrew
--
There is considerable overlap between the intelligence of the smartest
bears and the dumbest tourists -- Yosemite National Park Ranger
- References:
- RE: C++ Exceptions from CAC-UDP on exit Jeff Hill
- Navigate by Date:
- Prev:
EPICS R3.14.9 experiences Rees, NP (Nick)
- Next:
Re: EPICS R3.14.9 experiences Andrew Johnson
- Index:
2002
2003
2004
2005
<2006>
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
RE: C++ Exceptions from CAC-UDP on exit Jeff Hill
- Next:
Re: C++ Exceptions from CAC-UDP on exit Ernest L. Williams Jr.
- Index:
2002
2003
2004
2005
<2006>
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|