[Mono-list] Mono Embedding, Runtime Exception Propagation

Jonathan Pryor jonpryor at vt.edu
Tue Nov 20 21:16:13 EST 2007

On Wed, 2007-11-21 at 00:35 +0000, Nindi Singh wrote:
> I have a C++ App and would like to facilitate .NET plug-ins . This is
>  the reverse to what is normally seen, C++ called from C#. I want to call
>  C# functions from C++ with the C++ runtime being in control. As I
>  understand there are two options, PInvoke or directly using the Mono API. I
>  have played with both of these methods. 
> My problem however is to do with exception propagation. I have read in
>  the Mono docs that it is not possible to propagate .NET exceptions to
>  C++.

You wrote in another message:

> What if I call a C# function (B)  from a C++ function (A) and then
> this C# function in turn calls another C++ function (C) which throws ?
> For me this C++ exception seems to get stuck in the Mono runtime
> instead of being propagated to the original C++ function (A)
> A (C++) calls  B(C#) which calls  C (C++) which throws.

The short version is: Don't Do That.

The medium-length answer is: use .NET, as .NET and MSVC both use Win32
SEH to implement exception handling, things will (more or less) work as
expected (as you don't have conflicting exception handling mechanisms
trying to control stack unwinding/cleanup).

>   I would like to know if there is any way around this. Is it for
>  example possible to make a custom patch for Mono to be able to do this ?

The longer answer is to understand why this is a bad idea to begin with:
there is NO binary standard for how exceptions should be propagated and
the stack cleaned up.  It can, has, and likely WILL change at the drop
of a hat.  For example, the g++ ABI -- which handles exceptions and
myriad other things -- changed between g++ 2.x, 3.x, and 4.x (and for a
number of the "minor" releases as well).  Throw in a different compiler
-- say Intel's compiler -- and things change again.  MSVC?  different

No standardization whatsoever. [0]

Mono, of course, does its own thing.

So to get exceptions to work as transparently as you desire would
require, at minimum, getting Mono to use the same exception ABI as g++
(likely possible, though I don't know how difficult), and _then_ to
continually track the g++ ABI throughout any and all future ABI changes,
because if g++ and Mono ever get out of sync things will fail badly.

Obviously, if you want to support > 1 C++ compiler you're in for a world
of pain (or you stick to Windows, where SEH is the OS-provided/mandated
solution that many/most/all? compilers support), assuming you can get
the compilers to agree on an ABI to begin with.  (And lets not mention
any ABI bugs that a given compiler may introduce, rendering it
incompatible in some subtle corner case with everything else you're
linking into your address space...)

In short, don't do that.  It might be possible, but it's bound to be
brittle and a maintenance nightmare.  There are reasons that COM never
did real exception handling....

 - Jon

[0] To be fair, there is a standardization effort.  Itanium has a C++
ABI standard, which iirc gcc re-used for x86/x64 in the 3.x series.
However, they found bugs in their implementation, necessitating that
they change the ABI in subsequent minor releases to fix the corner cases
that they found.

Do you really want to bet that they've found every potential ABI corner
case?  *Especially* when C++ is a still-evolving standard, which may
require future ABI changes?

More information about the Mono-list mailing list