www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Catching C++ std::exception in D

reply Walter Bright <newshound2 digitalmars.com> writes:
In order to interoperate with modern C++, it has been abundantly clear for some 
time that D needs some support for C++ exception handling:

1. Have D finally blocks executed in D code that sits between a C++ try and
catch
2. Have C++ finally blocks executed in C++ code that sits between a D try and
catch
3. Be able to catch in D code an std::exception* or a C++ class derived from
that.
4. Throw an std::exception* from D code.

That's the minimum credible support, and is likely all D will actually need.

It's also clear that over the years nobody has risen to the challenge to get 
this working in dmd, so it falls to me to do it:

https://www.youtube.com/watch?feature=player_detailpage&v=Nglh-BExEus#t=227

:-)


The Current State
-----------------

Win32: DMC++ and DMD use standard Windows SEH, so this should be fairly easy to 
get to work. Unfortunately, Win32 is the past.

Win64: VC++ uses some bizarre unique scheme. I have no idea how it works. DMD 
uses the DM scheme I invented 30 years ago (!) that is very simple and works 
great, though it does have some performance penalties in the non-EH path.

Linux, OSX, FreeBSD: g++/clang++ use the dwarf eh scheme. DMD uses the DM
scheme.


Action Plan
-----------

Switch to using dwarf eh on Linux 64 (our most important platform). Once that 
works, it can be easily (hopefully) extended to the other dwarf eh platforms. 
Eventually, figure out the V++ Win64 scheme.


Progress
--------

I have started by switching from generating .debug_frame sections to .eh_frame 
sections. It appears that gcc/g++ already do this, and .debug_frame is now
obsolete.

I'll pretty much have to generate .gcc_except_table myself, as well as redo how 
the finally and catch block code is generated.


Can Really Use Help
-------------------

I really appreciate the offers, and here's what will really help:

Writing the druntime end of things, which is really providing just two 
functions: d_throw (d_dwarf_throw to distinguish it) and the libunwind 
personality function: __dmd_personality_v0. The tricky part with the
personality 
function will likely be recognizing std::exception* exceptions. I wonder if 
forwarding the call to __gxx_personality_v0 will work.

Work on this should be independent of the dmd compiler changes.
Nov 11 2015
next sibling parent reply krzaq <dlangmailinglist krzaq.cc> writes:
On Thursday, 12 November 2015 at 06:50:31 UTC, Walter Bright 
wrote:
 In order to interoperate with modern C++, it has been 
 abundantly clear for some time that D needs some support for 
 C++ exception handling:

 [...]
What about rethrowing C++ exceptions? Are we going to use pointer notation for C++ exceptions? This may be the same under the hood, but looks way different.
Nov 11 2015
parent reply Kagamin <spam here.lot> writes:
On Thursday, 12 November 2015 at 07:00:43 UTC, krzaq wrote:
 What about rethrowing C++ exceptions? Are we going to use 
 pointer notation for C++ exceptions? This may be the same under 
 the hood, but looks way different.
std::exception is class, i.e. reference type, so you won't be able to throw or catch it by value in D anyway.
Nov 11 2015
parent krzaq <dlangmailinglist krzaq.cc> writes:
On Thursday, 12 November 2015 at 07:47:16 UTC, Kagamin wrote:
 On Thursday, 12 November 2015 at 07:00:43 UTC, krzaq wrote:
 What about rethrowing C++ exceptions? Are we going to use 
 pointer notation for C++ exceptions? This may be the same 
 under the hood, but looks way different.
std::exception is class, i.e. reference type, so you won't be able to throw or catch it by value in D anyway.
Sure, but it's idiomatic to catch by reference, hence the question.
Nov 11 2015
prev sibling next sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 12 November 2015 at 07:50, Walter Bright via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

 In order to interoperate with modern C++, it has been abundantly clear for
 some time that D needs some support for C++ exception handling:

 1. Have D finally blocks executed in D code that sits between a C++ try
 and catch
 2. Have C++ finally blocks executed in C++ code that sits between a D try
 and catch
 3. Be able to catch in D code an std::exception* or a C++ class derived
 from that.
 4. Throw an std::exception* from D code.

 That's the minimum credible support, and is likely all D will actually
 need.

 It's also clear that over the years nobody has risen to the challenge to
 get this working in dmd, so it falls to me to do it:

 https://www.youtube.com/watch?feature=player_detailpage&v=Nglh-BExEus#t=227

 :-)
Support for 1 and 2 already exists, and comes for free it you are using libunwind, all what is needed is a little assistance to make it realised. Though it also helps if you have some supporting backend to generate the magic EH handling for you too. :-) Having your own EH tables has really left you with a shotgun wound in the foot here. I suspect this is the real reason why no one has stepped up. Progress
 --------

 I have started by switching from generating .debug_frame sections to
 .eh_frame sections. It appears that gcc/g++ already do this, and
 .debug_frame is now obsolete.

 I'll pretty much have to generate .gcc_except_table myself, as well as
 redo how the finally and catch block code is generated.
Good luck! Just a small request to on my side to not introduce anything in the frontend! I don't want a repeat of __va_argsave where gdc had supported 64bit for years and years.
 Can Really Use Help
 -------------------

 I really appreciate the offers, and here's what will really help:

 Writing the druntime end of things, which is really providing just two
 functions: d_throw (d_dwarf_throw to distinguish it) and the libunwind
 personality function: __dmd_personality_v0. The tricky part with the
 personality function will likely be recognizing std::exception* exceptions.
 I wonder if forwarding the call to __gxx_personality_v0 will work.
I don't mind the compiler-specific personality, but a new throw function? I guess I should count my lucky stars that I'm still using the original _d_throw callback. You will be able to recognize whether or not the exception object comes from C++, unwind's exception_class field can be compared to some gxx_exception_class enum value (or const symbol). Getting the typeinfo of the C++ exception is straightforward too. In the EH table, I guess you will have to generate an extern reference to C++'s typeinfo object somehow... -- Regards Iain
Nov 12 2015
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/12/2015 12:57 AM, Iain Buclaw via Digitalmars-d wrote:
 I don't mind the compiler-specific personality,
gdc has one, __gcd_personality_v0. I don't see a way out of not having one.
 but a new throw function?  I
 guess I should count my lucky stars that I'm still using the original _d_throw
 callback.
It only has a different name. Not a different API.
 In the EH table, I guess you will have to generate an
 extern reference to C++'s typeinfo object somehow...
That shouldn't be difficult.
Nov 12 2015
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 12 November 2015 at 10:36, Walter Bright via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

 On 11/12/2015 12:57 AM, Iain Buclaw via Digitalmars-d wrote:

 I don't mind the compiler-specific personality,
gdc has one, __gcd_personality_v0. I don't see a way out of not having one.
Correct, there is no way out of having one.
 but a new throw function?  I
 guess I should count my lucky stars that I'm still using the original
 _d_throw
 callback.
It only has a different name. Not a different API.
It's just more ABI differences between D compilers. ;-)
Nov 12 2015
parent reply Johannes Pfau <nospam example.com> writes:
Am Thu, 12 Nov 2015 11:31:39 +0100
schrieb Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com>:

 On 12 November 2015 at 10:36, Walter Bright via Digitalmars-d <
 digitalmars-d puremagic.com> wrote:
 
 On 11/12/2015 12:57 AM, Iain Buclaw via Digitalmars-d wrote:
  
 I don't mind the compiler-specific personality,
  
gdc has one, __gcd_personality_v0. I don't see a way out of not having one.
Correct, there is no way out of having one.
To expand on this: I think we'd prefer one __d_personality_v0 which is implemented in upstream druntime and identical for all compilers. Making the compilers ABI compatible is probably not a high priority, but OTOH we shouldn't introduce new ABI incompatibilities if possible. Think of it this way: At some point it would be nice to have one, system-wide installed druntime shared library (from any compiler) and programs compiled with any other compiler should be able to use it. We've got well-defined name mangling primarily to allow this - but because of many small differences mixing compilers is not possible yet.
 
 
 but a new throw function?  I  
 guess I should count my lucky stars that I'm still using the
 original _d_throw
 callback.
  
It only has a different name. Not a different API.
It's just more ABI differences between D compilers. ;-)
Nov 12 2015
next sibling parent reply Dan Olson <gorox comcast.net> writes:
Johannes Pfau <nospam example.com> writes:
 To expand on this: I think we'd prefer one __d_personality_v0 which is
 implemented in upstream druntime and identical for all compilers.
Speacking of upstream support. GDC support SjLj exceptions. In 2.067, it became obvious that Fiber needed separate SjLj context stacks which are normally thread specific. I have a change in my iOS LDC fork which I suppose could go to upstream thread.d file so GDC can pick it up to. https://github.com/smolt/druntime/commit/5d32e9e68cc6bd8b13cacfdb18a4d91374bf6b3e See, I even included GNU_SjLj_Exceptions :-) Sound like a good idea? It is getting queued up soon as a PR to LDC once we get an iOS version officially in the compiler frontend. -- Dan
Nov 12 2015
parent reply Johannes Pfau <nospam example.com> writes:
Am Thu, 12 Nov 2015 09:59:14 -0800
schrieb Dan Olson <gorox comcast.net>:

 Johannes Pfau <nospam example.com> writes:
 To expand on this: I think we'd prefer one __d_personality_v0 which
 is implemented in upstream druntime and identical for all
 compilers.  
Speacking of upstream support. GDC support SjLj exceptions. In 2.067, it became obvious that Fiber needed separate SjLj context stacks which are normally thread specific. I have a change in my iOS LDC fork which I suppose could go to upstream thread.d file so GDC can pick it up to. https://github.com/smolt/druntime/commit/5d32e9e68cc6bd8b13cacfdb18a4d91374bf6b3e See, I even included GNU_SjLj_Exceptions :-) Sound like a good idea? It is getting queued up soon as a PR to LDC once we get an iOS version officially in the compiler frontend.
Nice work. We certainly want that in GDC or even better in upstream. I guess we don't have a unittest yet which can detect this problem. Is it possible to add a unittest for this?
Nov 12 2015
parent reply Dan Olson <gorox comcast.net> writes:
Johannes Pfau <nospam example.com> writes:

 Am Thu, 12 Nov 2015 09:59:14 -0800
 schrieb Dan Olson <gorox comcast.net>:

 Johannes Pfau <nospam example.com> writes:
 To expand on this: I think we'd prefer one __d_personality_v0 which
 is implemented in upstream druntime and identical for all
 compilers.  
Speacking of upstream support. GDC support SjLj exceptions. In 2.067, it became obvious that Fiber needed separate SjLj context stacks which are normally thread specific. I have a change in my iOS LDC fork which I suppose could go to upstream thread.d file so GDC can pick it up to. https://github.com/smolt/druntime/commit/5d32e9e68cc6bd8b13cacfdb18a4d91374bf6b3e See, I even included GNU_SjLj_Exceptions :-) Sound like a good idea? It is getting queued up soon as a PR to LDC once we get an iOS version officially in the compiler frontend.
Nice work. We certainly want that in GDC or even better in upstream. I guess we don't have a unittest yet which can detect this problem. Is it possible to add a unittest for this?
I had 2.067 unittest failures without this change, I don't recall which. I know it made me laugh becase exceptions were being thrown from Fiber A but being caught by Fiber B. I can easily find out what fails by rerunning without the change. I'll report back later.
Nov 13 2015
next sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 13 November 2015 at 18:45, Dan Olson via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

 Johannes Pfau <nospam example.com> writes:

 Am Thu, 12 Nov 2015 09:59:14 -0800
 schrieb Dan Olson <gorox comcast.net>:

 Johannes Pfau <nospam example.com> writes:
 To expand on this: I think we'd prefer one __d_personality_v0 which
 is implemented in upstream druntime and identical for all
 compilers.
Speacking of upstream support. GDC support SjLj exceptions. In 2.067, it became obvious that Fiber needed separate SjLj context stacks which are normally thread specific. I have a change in my iOS LDC fork which I suppose could go to upstream thread.d file so GDC can pick it up to.
https://github.com/smolt/druntime/commit/5d32e9e68cc6bd8b13cacfdb18a4d91374bf6b3e
 See, I even included GNU_SjLj_Exceptions :-)

 Sound like a good idea?  It is getting queued up soon as a PR to LDC
 once we get an iOS version officially in the compiler frontend.
Nice work. We certainly want that in GDC or even better in upstream. I guess we don't have a unittest yet which can detect this problem. Is it possible to add a unittest for this?
I had 2.067 unittest failures without this change, I don't recall which. I know it made me laugh becase exceptions were being thrown from Fiber A but being caught by Fiber B. I can easily find out what fails by rerunning without the change. I'll report back later.
There may be a few other holes between how Fibers and EH interact. https://github.com/D-Programming-Language/druntime/commit/f6633abb43ea1f2464d3a772b8f8fe78216ffd8e
Nov 13 2015
parent reply David Nadlinger <code klickverbot.at> writes:
On Friday, 13 November 2015 at 18:40:06 UTC, Iain Buclaw wrote:
 There may be a few other holes between how Fibers and EH 
 interact.

 https://github.com/D-Programming-Language/druntime/commit/f6633abb43ea1f2464d3a772b8f8fe78216ffd8e
The SJLJ stack switching should probably be added to this mechanism. — David
Nov 14 2015
parent Dan Olson <gorox comcast.net> writes:
David Nadlinger <code klickverbot.at> writes:

 On Friday, 13 November 2015 at 18:40:06 UTC, Iain Buclaw wrote:
 There may be a few other holes between how Fibers and EH interact.

 https://github.com/D-Programming-Language/druntime/commit/f6633abb43ea1f2464d3a772b8f8fe78216ffd8e
The SJLJ stack switching should probably be added to this mechanism. — David
I did a quick experiment to merge the two approaches and it failed in unittests. I am not sure why yet. They are implemented slightly different in that SjLj context is saved in the Fiber object, whereas _d_eh_swapContext is saving in a Thread.Context object.
Nov 14 2015
prev sibling parent Dan Olson <gorox comcast.net> writes:
Dan Olson <gorox comcast.net> writes:

 Johannes Pfau <nospam example.com> writes:

 Am Thu, 12 Nov 2015 09:59:14 -0800
 schrieb Dan Olson <gorox comcast.net>:

 Johannes Pfau <nospam example.com> writes:
 To expand on this: I think we'd prefer one __d_personality_v0 which
 is implemented in upstream druntime and identical for all
 compilers.  
Speacking of upstream support. GDC support SjLj exceptions. In 2.067, it became obvious that Fiber needed separate SjLj context stacks which are normally thread specific. I have a change in my iOS LDC fork which I suppose could go to upstream thread.d file so GDC can pick it up to. https://github.com/smolt/druntime/commit/5d32e9e68cc6bd8b13cacfdb18a4d91374bf6b3e See, I even included GNU_SjLj_Exceptions :-) Sound like a good idea? It is getting queued up soon as a PR to LDC once we get an iOS version officially in the compiler frontend.
Nice work. We certainly want that in GDC or even better in upstream. I guess we don't have a unittest yet which can detect this problem. Is it possible to add a unittest for this?
I had 2.067 unittest failures without this change, I don't recall which. I know it made me laugh becase exceptions were being thrown from Fiber A but being caught by Fiber B. I can easily find out what fails by rerunning without the change. I'll report back later.
I removed my SjLj change in core.thread to see what fails. Running 2.067 unittests, std.concurrency fails with a memory access error. Latest core.thread has a unittest for "Test exception chaining when switching contexts in finally blocks" that also fails with a memory access error.
Nov 14 2015
prev sibling parent David Nadlinger <code klickverbot.at> writes:
On Thursday, 12 November 2015 at 16:55:09 UTC, Johannes Pfau 
wrote:
 To expand on this: I think we'd prefer one __d_personality_v0 
 which is implemented in upstream druntime and identical for all 
 compilers.

 Making the compilers ABI compatible is probably not a high 
 priority, but OTOH we shouldn't introduce new ABI 
 incompatibilities if possible.
It should probably be based on the LDC implementation then, as it supports the most target platforms (Posix/libunwind, Win64/MSVC, iOS/SJLJ, and, as work in progress, Win32/SEH) and GDC's implementation is probably GPL-licensed (with runtime exceptions, but still definitely not Boost-compatible).
 Think of it this way: At some point it would be nice to have 
 one, system-wide installed druntime shared library (from any 
 compiler) and programs compiled with any other compiler should 
 be able to use it. We've got well-defined name mangling 
 primarily to allow this - but because of many small differences 
 mixing compilers is not possible yet.
The biggest of which is probably that GDC and DMD disagree on parameter passing orders. — David
Nov 12 2015
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-11-12 07:50, Walter Bright wrote:

 3. Be able to catch in D code an std::exception* or a C++ class derived
 from that.
In would be nice if we were able to catch Objective-C exceptions as well (it uses the same exception handling as C++). They have their own tree of exception classes which do not inherit from std::exception. We don't need to support this right away but it would be nice to avoid any artificial limitations preventing this. -- /Jacob Carlborg
Nov 12 2015
next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 12 November 2015 at 09:59, Jacob Carlborg via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

 On 2015-11-12 07:50, Walter Bright wrote:

 3. Be able to catch in D code an std::exception* or a C++ class derived
 from that.
In would be nice if we were able to catch Objective-C exceptions as well (it uses the same exception handling as C++). They have their own tree of exception classes which do not inherit from std::exception. We don't need to support this right away but it would be nice to avoid any artificial limitations preventing this. -- /Jacob Carlborg
C++ can catch exceptions thrown in D and ObjC using `catch(...)`, and there's no technical limitation on why we can't do the same from a D `catch { }`. But I don't think Walter wants C++-style catch-all support in D, and currently our version of catch-all is lowered to `catch(Throwable)` which does not have the same semantic meaning. -- Regards Iain
Nov 12 2015
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/12/2015 12:59 AM, Jacob Carlborg wrote:
 In would be nice if we were able to catch Objective-C exceptions as well (it
 uses the same exception handling as C++). They have their own tree of exception
 classes which do not inherit from std::exception. We don't need to support this
 right away but it would be nice to avoid any artificial limitations preventing
 this.
I don't anticipate that would be too difficult to add.
Nov 12 2015
parent Jacob Carlborg <doob me.com> writes:
On 2015-11-12 10:40, Walter Bright wrote:

 I don't anticipate that would be too difficult to add.
Great :) -- /Jacob Carlborg
Nov 12 2015
prev sibling next sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 12 November 2015 at 07:50, Walter Bright via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

 I really appreciate the offers, and here's what will really help:

 Writing the druntime end of things, which is really providing just two
 functions: d_throw (d_dwarf_throw to distinguish it) and the libunwind
 personality function: __dmd_personality_v0. The tricky part with the
 personality function will likely be recognizing std::exception* exceptions.
 I wonder if forwarding the call to __gxx_personality_v0 will work.
I'll have to check, but I'm pretty certain that libunwind will call the C++ personality for you if you return `nothing found` from D personality function.
Nov 12 2015
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/12/2015 2:08 AM, Iain Buclaw via Digitalmars-d wrote:
     Writing the druntime end of things, which is really providing just two
     functions: d_throw (d_dwarf_throw to distinguish it) and the libunwind
     personality function: __dmd_personality_v0. The tricky part with the
     personality function will likely be recognizing std::exception* exceptions.
     I wonder if forwarding the call to __gxx_personality_v0 will work.


 I'll have to check, but I'm pretty certain that libunwind will call the C++
 personality for you if you return `nothing found` from D personality function.
Why should it? What tells libunwind to call the C++ personality function? The generated EH tables only say call the D personality function.
Nov 12 2015
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Thursday, 12 November 2015 at 10:09:10 UTC, Iain Buclaw wrote:
 On 12 November 2015 at 07:50, Walter Bright via Digitalmars-d < 
 digitalmars-d puremagic.com> wrote:

 I really appreciate the offers, and here's what will really 
 help:

 Writing the druntime end of things, which is really providing 
 just two functions: d_throw (d_dwarf_throw to distinguish it) 
 and the libunwind personality function: __dmd_personality_v0. 
 The tricky part with the personality function will likely be 
 recognizing std::exception* exceptions. I wonder if forwarding 
 the call to __gxx_personality_v0 will work.
I'll have to check, but I'm pretty certain that libunwind will call the C++ personality for you if you return `nothing found` from D personality function.
The personality function is in the landingpad metadata. Why would libunwind call the C++ one out of nowhere ?
Nov 12 2015
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 12 November 2015 at 11:17, deadalnix via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

 On Thursday, 12 November 2015 at 10:09:10 UTC, Iain Buclaw wrote:

 On 12 November 2015 at 07:50, Walter Bright via Digitalmars-d <
 digitalmars-d puremagic.com> wrote:


 I really appreciate the offers, and here's what will really help:

 Writing the druntime end of things, which is really providing just two
 functions: d_throw (d_dwarf_throw to distinguish it) and the libunwind
 personality function: __dmd_personality_v0. The tricky part with the
 personality function will likely be recognizing std::exception* exceptions.
 I wonder if forwarding the call to __gxx_personality_v0 will work.


 I'll have to check, but I'm pretty certain that libunwind will call the
C++ personality for you if you return `nothing found` from D personality function.
The personality function is in the landingpad metadata. Why would libunwind call the C++ one out of nowhere ?
I did say that I'd have to check. :-) In any case, I'm doubtful that forwarding to C++'s personality would work.
Nov 12 2015
parent reply Jacob Carlborg <doob me.com> writes:
On 2015-11-12 11:37, Iain Buclaw via Digitalmars-d wrote:

 In any case, I'm doubtful that forwarding to C++'s personality would work.
Objective-C does that [1]. [1] http://www.opensource.apple.com/source/objc4/objc4-647/runti e/objc-exception.mm search for "__objc_personality_v0" -- /Jacob Carlborg
Nov 12 2015
parent deadalnix <deadalnix gmail.com> writes:
On Thursday, 12 November 2015 at 10:56:01 UTC, Jacob Carlborg 
wrote:
 On 2015-11-12 11:37, Iain Buclaw via Digitalmars-d wrote:

 In any case, I'm doubtful that forwarding to C++'s personality 
 would work.
Objective-C does that [1]. [1] http://www.opensource.apple.com/source/objc4/objc4-647/runti e/objc-exception.mm search for "__objc_personality_v0"
ObjC doesn't do cleanup, so that's a bit different.
Nov 12 2015
prev sibling next sibling parent Elie Morisse <syniurge gmail.com> writes:
On Thursday, 12 November 2015 at 06:50:31 UTC, Walter Bright 
wrote:
 In order to interoperate with modern C++, it has been 
 abundantly clear for some time that D needs some support for 
 C++ exception handling:

 1. Have D finally blocks executed in D code that sits between a 
 C++ try and catch
 2. Have C++ finally blocks executed in C++ code that sits 
 between a D try and catch
 3. Be able to catch in D code an std::exception* or a C++ class 
 derived from that.
 4. Throw an std::exception* from D code.

 That's the minimum credible support, and is likely all D will 
 actually need.
I also started working on C++ exception handling for LDC/Calypso, I almost caught my first std::exception yesterday! (it went into the right catch and the IR looks right but _cxa_begin_catch() seems to return null instead of the exception object for some reason) Clang and Calypso made the std::type_info stuff a breeze, getting the type_info value for any C++ type was one line of code. I'll push the changes as is into a branch tonight, it's about ~400 lines.
 The tricky part with the personality function will likely be 
 recognizing std::exception* exceptions. I wonder if forwarding 
 the call to __gxx_personality_v0 will work.
From what I gathered even if you manage to make the format of the LSDA tables compatible with __gxx_personality_v0, one blocker is that it still expects std::type_info pointers in the action table so will choke if it encounters D's TypeInfo_Class in there. To check if a type_info from a catch clause handles the thrown exception it calls the virtual method type_info::__do_catch (which is what Calypso does too) so can't work with D classes.
Nov 12 2015
prev sibling next sibling parent David Nadlinger <code klickverbot.at> writes:
On Thursday, 12 November 2015 at 06:50:31 UTC, Walter Bright 
wrote:
 The tricky part with the personality function will likely be 
 recognizing std::exception* exceptions. I wonder if forwarding 
 the call to __gxx_personality_v0 will work.
This should be rather simple; you know it is C++ because of the metadata, and if you have access to RTTI (can just be hacked together with pragma(mangle, …)), you just do the type comparison then. What has me quite a bit more worried is the lifetime handling involved in the usual "throw std::exception subclass by value, catch base class by reference" idiom. If I remember correctly, both GCC and Clang handle this by injecting a runtime function call into the end of the catch blocks. Their implementation must also support keeping the value around for rethrowing. At this point, I'm not aware of any fundamental incompatibilities, but it will certainly add to the complexity of the solution. — David
Nov 12 2015
prev sibling parent Elie Morisse <syniurge gmail.com> writes:
Sorry for the delay, here's the initial commit for C++ exception 
catching in Calypso:

https://github.com/Syniurge/Calypso/commit/8b55ec1f013c29df86455ab055fbba91a72d92af
https://github.com/Syniurge/druntime/commit/d33d8bf32c739bf9a30705dfc764718c817f16b1

The main files of interest are:

https://github.com/Syniurge/druntime/blob/release-0.16.1/src/ldc/eh/cpp/gnu.d
https://github.com/Syniurge/Calypso/blob/master/gen/cpp/cppeh.cpp

And a basic example which segfaults at e.what() because 
__cxa_begin_catch returns null:

https://github.com/Syniurge/Calypso/blob/master/tests/calypso/eh/std_exception.d

Resulting IR : https://paste.kde.org/pvi2bokqx

catch (C++) were added to be able to catch any type, and that's 
the only cost for being able to catch any C++ exception and not 
just std::exception I think, Clang and the libstdc++ makes 
working with std::type_info very easy.

For the time the handler uses unwind-cxx.h copied from GNU's 
libstdc++ (it's an internal header which doesn't ship with any 
Ubuntu package). Its license is more permissive than the GPL, but 
if it isn't compatible it could be replaced by its libc++ 
equivalent.
Nov 14 2015