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]

Re: Exception problem in C++


On 05-Jan-2001, Robert Schweikert <rjschwei@mindspring.com> wrote:
> Does anyone have any ideas what could have gone wrong when the traceback
> includes __throw() as follows?
>
> Program terminated with signal 6, Aborted.
> #0  0x411c44e1 in __kill () from /lib/libc.so.6
> #0  0x411c44e1 in __kill () from /lib/libc.so.6
> #1  0x4119b1eb in raise (sig=6) at signals.c:64
> #2  0x411c5868 in abort () at ../sysdeps/generic/abort.c:88
> #3  0x404b340b in __default_terminate ()
>    from /usr/abaqus60/5-adb/object/linux32/exec/lbr/libHKSodbO.so
> #4  0x404b342c in __terminate ()
>    from /usr/abaqus60/5-adb/object/linux32/exec/lbr/libHKSodbO.so
>     my_udata=0xbfffecf8, offset_p=0xbfffecf4)
>    from /usr/abaqus60/5-adb/object/linux32/exec/lbr/libHKSodbO.so
> #6  0x404b3edc in __throw ()

Look for "terminate()" in the C++ standard:

 |   15.5.1 - The terminate() function [except.terminate]
 | 
 |    -1- In the following situations exception handling must be abandoned for less subtle error
 |    handling techniques:
 |      * when the exception handling mechanism, after completing evaluation of the expression
 |        to be thrown but before the exception is caught (except.throw), calls a user function
 |        that exits via an uncaught exception,*
 | 
 |      [Footnote: For example, if the object being thrown is of a class with a copy
 |      constructor, terminate() will be called if that copy constructor exits with an
 |      exception during a throw. --- end foonote]
 | 
 |      * when the exception handling mechanism cannot find a handler for a thrown exception
 |        (except.handle), or
 | 
 |      * when the destruction of an object during stack unwinding (except.ctor) exits using an
 |        exception, or
 | 
 |      * when construction or destruction of a non-local object with static storage duration
 |        exits using an exception (basic.start.init), or
 | 
 |      * when execution of a function registered with atexit exits using an exception
 |        (lib.support.start.term), or
 | 
 |      * when a throw-expression with no operand attempts to rethrow an exception and no
 |        exception is being handled (except.throw), or
 | 
 |      * when unexpected throws an exception which is not allowed by the previously violated


>    from /usr/abaqus60/5-adb/object/linux32/exec/lbr/libHKSodbO.so
> #7  0x4085f2ed in ipc_Monitor::ShutDown ()
>    from /usr/abaqus60/6-0/object/linux32/exec/lbr/libHKSipc.so
> 
> This happens on shutdown of an application. There is an exception being
> thrown in "ipc_Monitor::ShutDown ()", which is in a shared library. This
> exception is suppossed to be caught by main, which is further down in
> the call stack. The problem is that we never get to the "catch" and
> things gow wrong somewhere in between.

A brief examination of the source code for `__throw', which is in the libgcc2.c file
<http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgcc2.c>, suggests that it is
probably one of these two:

 |      * when the exception handling mechanism cannot find a handler for a thrown exception
 |        (except.handle), or
 ...
 |      * when a throw-expression with no operand attempts to rethrow an exception and no
 |        exception is being handled (except.throw), or
 | 

That is, either (a) this is `throw;' with no argument, and there's no active
exception, or (b) main doesn't have an exception handler around this
call (e.g. perhaps because the call was registered with atexit() rather
than being called from main).  A third alternative is (c) GNU C++ is
broken, but IMHO (c) is unlikely.

P.S. Some other vaguely relevant extracts from the C++ standard
(I think only 15.1/8 and 15.3/9 are really relevant here):

 | 15.1 - Throwing an exception [except.throw]
...
 |    -8- If no exception is presently being handled, executing a throw-expression with no
 |    operand calls terminate() (except.terminate).
...
 | 15.2 - Constructors and destructors [except.ctor]
...
 |    -3- The process of calling destructors for automatic objects constructed on the path from
 |    a try block to a throw-expression is called ``stack unwinding.'' [Note: If a destructor
 |    called during stack unwinding exits with an exception, terminate is called
 |    (except.terminate). So destructors should generally catch exceptions and not let them
 |    propagate out of the destructor.
 |    --- end note]
...
 | 15.3 - Handling an exception [except.handle]
...
 |   -9- If no matching handler is found in a program, the function terminate() is called;
...
 | 15.4 - Exception specifications [except.spec]
...
 |    -8- Whenever an exception is thrown and the search for a handler (except.handle)
 |    encounters the outermost block of a function with an exception-specification, the function
 |    unexpected() is called (except.unexpected) if the exception-specification does not allow
 |    the exception. [Example: ...]
 | 
 |    -9- The function unexpected() may throw an exception that will satisfy the
 |    exception-specification for which it was invoked, and in this case the search for another
 |    handler will continue at the call of the function with this exception-specification (see
 |    except.unexpected), or it may call terminate().
...

-- 
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.

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