Bug 19620 - exception not caught when passing through C code
Summary: exception not caught when passing through C code
Status: RESOLVED DUPLICATE of bug 11813
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 3.4.3
: P2 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-01-25 09:27 UTC by James Kanze
Modified: 2005-07-23 22:49 UTC (History)
2 users (show)

See Also:
Host: sparc-sun-solaris2.8
Target: sparc-sun-solaris2.8
Build: sparc-sun-solaris2.8
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description James Kanze 2005-01-25 09:27:02 UTC
When an exception is thrown, terminate is called, even though
there is an appropriate handler, if there is any C code between
the exception and the handler.  This is a serious problem because
a lot of third party software uses a C ABI and callbacks.
(Note that this works with Sun CC.)

---------- main.cc ------------

#include <ostream>
#include <iostream>
#include <stdexcept>

extern "C"
{
    extern void enrollCallback( void (*pf)() ) ;
    extern void doCallback() ;
}

void
f()
{
    throw std::runtime_error( "Just a test" ) ;
}


extern "C" void callback()
{
    f() ;
}

int
main()
{
    enrollCallback( &callback ) ;
    try {
        doCallback() ;
    } catch ( std::exception const& error ) {
        std::cout << "Exception caught: " << error.what() << std::endl ;
    } catch ( ... ) {
        std::cout << "Unknown exception caught" << std::endl ;
    }
    return 0 ;
}
------------ test.c -----------

static void (*pf)() ;

void
enrollCallback( void (*cb)() )
{
    pf = cb ;
}

void
doCallback()
{
    (*pf)() ;
}
-------------- end sources -----------
Desired behavior: Program outputs:
>   Exception caught: Just a test
when run.  (This is the behavior of Sun CC.)

Actual behavior: terminate is called.
Comment 1 Gabriel Dos Reis 2005-01-25 15:53:33 UTC
Subject: Re:  New: exception not caught when passing through C code

"jkanze at cheuvreux dot com" <gcc-bugzilla@gcc.gnu.org> writes:

| When an exception is thrown, terminate is called, even though
| there is an appropriate handler, if there is any C code between
| the exception and the handler.  This is a serious problem because
| a lot of third party software uses a C ABI and callbacks.
| (Note that this works with Sun CC.)

This is documented somewhere in the docs, I think.  
If you mix C codes with C++ and exceptions are raised (through
callbacks) and you need exceptions to smoothly travel across language
boundaries, you need to compile the C code with -fexceptions.

And yes, I too believe that Sun's approach is very sensible.

Ah, I found the doc:

======================
@item -fexceptions
@opindex fexceptions
Enable exception handling.  Generates extra code needed to propagate
exceptions.  For some targets, this implies GCC will generate frame
unwind information for all functions, which can produce significant data
size overhead, although it does not affect execution.  If you do not
specify this option, GCC will enable it by default for languages like
C++ which normally require exception handling, and disable it for
languages like C that do not normally require it.  However, you may need
to enable this option when compiling C code that needs to interoperate
properly with exception handlers written in C++.  You may also wish to
disable this option if you are compiling older C++ programs that don't
use exception handling.
======================

I thinks the PR can be closed.

-- Gaby
Comment 2 Andrew Pinski 2005-01-25 16:11:32 UTC

*** This bug has been marked as a duplicate of 11813 ***
Comment 3 James Kanze 2005-01-31 09:55:10 UTC
Subject: Re:  exception not caught when passing through C code



> This is documented somewhere in the docs, I think.  If you mix C
> codes with C++ and exceptions are raised (through callbacks) and
> you need exceptions to smoothly travel across language
> boundaries, you need to compile the C code with -fexceptions.

The problem is that you don't always have the sources for the C
code.  Most of the time, it is in some third party library for
which you only have the .h's and the .a (or .so).  (And the
third party library has likely been compiled with Sun's cc, not
gcc.)

I'll admit that I don't understand the problem, at least on
Sparc.  There is an ABI which defines what the C stack looks
like; the C++ stack is, in fact, identical.  Walking back the
stack is trivial.  The only thing you need the tables for is for
finding destructor or handler code.  So you won't find them in
the C code which doesn't have the tables; that's no problem,
because I'm pretty sure that the C code doesn't have any
destructors, nor any exception handlers.

Is there something linked with portability which precludes this
approach.  (I know that the stack walkback code is NOT portable.
But I would have thought that this was true with or without the
tables.)

--
James Kanze        GABI Software       mailto: jkanze@cheuvreux.com
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

"This message, including any attachments may contain confidential and
privileged material; it is intended only for the person to whom it is
addressed. Its contents do not constitute a commitment by Credit Agricole
Cheuvreux except where provided for in a written agreement. Credit Agricole
Cheuvreux assumes no liability or responsibility for the consequences
arising out of a delay and/or loss in transit of this message, or for
corruption or other error(s) arising in its transmission and for any misuse
or fraudulent use which may be made thereof. If you are not the intended
recipient, please contact us and abstain from any disclosure, use or
dissemination. To the extent that this message contains research
information and/or recommendations, these are provided on the same basis as
Credit Agricole Cheuvreux's published research and the recipient must have
regard to all disclosures and disclaimers contained therein."



Comment 4 Eric Botcazou 2005-01-31 10:54:01 UTC
> I'll admit that I don't understand the problem, at least on
> Sparc.  There is an ABI which defines what the C stack looks
> like; the C++ stack is, in fact, identical.  Walking back the
> stack is trivial.  The only thing you need the tables for is for
> finding destructor or handler code.

This indeed may be true on SPARC.

> So you won't find them in the C code which doesn't have the tables; that's no
> problem, because I'm pretty sure that the C code doesn't have any
> destructors, nor any exception handlers.

Sure, but GCC nevertheless needs unwind info describing that there is no table
and how to further unwind.

> Is there something linked with portability which precludes this
> approach.  (I know that the stack walkback code is NOT portable.
> But I would have thought that this was true with or without the
> tables.)

The exception propagation mechanism is generic and doesn't special-case SPARC at
the moment.