sfink has asked for the wisdom of the Perl Monks concerning the following question:

I am wrapping a bunch of C++ code using Inline::CPP. When I throw an exception in code called by a wrapped function, the exception doesn't seem to make it through the XS layer up to my catch statement. Perhaps this is actually a C vs C++ problem and not a perl one at all; I'm not sure.

In more detail, I have a C++ try block containing a call to eval_sv, which calls a bunch of functions including both functions in libperl.so (which are compiled as C) and wrapped XS functions (which are compiled as C++). One of those XS functions calls my C++ function, which throws an exception. I get an immediate abort, rather than having the exception caught by my catch(...) clause.

I could change every wrapper function to do a try {} block around everything it does, in order to convert the C++ exception to a Perl exception, but I'd love to avoid the extra work if possible.

Update: It turned out to be a C vs C++ thing, more or less. The problem is that to unwind the stack on an exception, C++ leaves a trail of breadcrumbs all the way up the stack in order to call the appropriate destructors etc. C does not. gcc controls this with the -fexceptions, which is enabled by default for C++ and disabled for C. So, the easiest solution is to recompile perl with the flag added -- I have tried it, and it works great!

Replies are listed 'Best First'.
Re: How to propagate C++ exceptions through XS
by knexus (Hermit) on Mar 11, 2004 at 20:41 UTC
    I think the problem could be related to name munging in C++ and a subsequent linkage problem?

    When C is compiled, the object file output references functions as they were in the source code, ie. foo(). However, in C++ the compiler will change the function name (munge it) to something else by adding characters to it, like foo_whatever(). As I understand it, this is related to supporting polymophism etc.

    So, to call a 'C' function from C++ you have to keep the compiler from munging the 'C' function name by wrapping it in an extern "C" definition. Likewise, to call a C++ function from C.

    Sorry, but I don't recall exact format as it's been too long since I have done any of this.

    Here's a link I found that may be of use: C & CPP

    Anyhow, I hope this helps.