This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Exception problem in C++
Fergus,
> 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.
I might have to vote for (c) as this code runs on a number of other platforms. The curious thing is
that other exceptions in the code are handled properly, only this specific one, which is actually
one of the more simple cases is messing up. The throw definitely occurs within a try block in
main.
I'd like to understand more about the implementation of exception handling and what is supposed to
happen to see if I can spot anything when I follow the execution path in the debugger.
Currently when the exception is being thrown the first place the code is going is to a "fixup"
routine (what is that and why is the code going there? ); Then it starts looking in the shared
shared libraries to find various symbols, the first being "__eh_alloc" the second being the copy
constructor of the exception object, I have not been able to determine with 100% accuracy whether
this is ever found or not. The code continues to look up symbols in shared libraries and then
eventually fails. I don't think I ever get to the place where a match to the thrown exception is
being sought. Looking at the documentation I think I should be getting to an "__unwind" function
eventually, but that never happens.
Since I don't know what is supposed to happen after an exception is being thrown and how the stack
unwinding is supposed to work I am certainly in the dark. A brief description on how the mechanism
is supposed to work in g++ and some pointers to the code where this is going to happen would of
great help.
Further I am still concerned with the definition of the symbols (shown below) in a number of shared
libraries, how did they get there and what happens when two libraries that have these exception
symbols defined get loaded (link to another library)?
-> nm -Bg libHKSodbO.so | grep throw
00088f08 T __rethrow
000886d4 T __sjpopnthrow
000885c4 T __sjthrow
00088e48 T __throw
00089534 T __throw_bad_cast
000895d8 T __throw_bad_typeid
00088438 T __throw_type_match
0008af28 T __throw_type_match_rtti
0009a75f R nothrow
Another question concerns the compile flags. Right now neither -frtti nor -fno-rtti are set
explicitly, I probably missed the point in the documentation where that specifies the default,
which is the default? Further, a more detailed explanation what either option does would be very
helpful.
Any help is appreciated. So far I am chasing this problem for the better part of 2 days and am
still no further than when I started.
Thanks,
Robert
Fergus Henderson wrote:
> 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.
--
Robert Schweikert MAY THE SOURCE BE WITH YOU
rjschwei@mindspring.com LINUX