[LLVMdev] RFC: New EH representation for MSVC compatibility

Steve Cheng
Mon, 18 May 2015 21:42:23 -0000

Hi Reid,

> Right, __CxxFrameHandler3 is a lot more constraining than
> __C_specific_handler. The SEH personality doesn't let you rethrow
> exceptions, so once you catch the exception you're done, you're in
the
> parent function. My understanding is that C++ works by having an active
> catch handler on the stack.

Okay, I checked the Wine source code for __CxxFrameHandler3. I stand corrected.

While we are on the topic of Windows EH, I like to know your (and
others', of course) thoughts on the following. It's my wishlist as a
frontend implementor :)

- Win32 (x86) frame-based SEH

For __CxxFrameHandler3, since destructors and catch blocks execute as
funclets while the throwing function's stack frame is still active,
it's not going to be a problem right?

But for __C_specific_handler, I see a potential issue versus x86-64, in
that RtlUnwind can't restore non-volatile registers, so when registers
are garbage when control is transferred to the landing pad.  When I
read the Itanium ABI documentation, it says that landing pads do get
non-volatile registers restored, so I guess that's probably the working
assumption of LLVM.

 __C_specific_handler's registration frame saves down EBP, but no other
registers, even ESP. If we use dynamic alloca or frame pointer
omission, we are dead in the water, right?

- Writing one's own personality functions

This makes a lot of sense if one is implementing a different language
than C++ that has exceptions, and is prepared to provide their own
run-time support.

Say, if the language supports resuming from exceptions, or can query
type information in more flexible ways than C++'s std::type_info
matching. Does it really make sense for the backend, LLVM, to hard-code
knowledge about the language-specific data area (LSDA)? Even in the
Itanium ABI it's explicitly stated that the personality is specific to
the source language, yet multiple personalities can interoperate in the
same program. Ideally, I would prefer the backend to take control of
everything to do with arranging the landing pads, branches within
landing pads, and so on, but NOT the language-dependent exception
matching.

Taken to the extreme, LLVM would have to expose tables that the LLVM
client would have to translate to their own formats, like the garbage
collection "unwind" tables. If that's too complicated at least it
would
be nice to supply custom filter functions for catch clauses. Inspired
by SEH filters obviously, but we might devise a slightly more portable
version.

Even for C++ I actually wouldn't mind being able to arbitrarily replace
the personality, and/or the runtime functions for throwing and
resuming. In my C++ source code I always throw exceptions wrapped in a
macro, because I want to instrument all my throw statements. In
particular, I can construct a reliable stack trace on the spot with
RtlVirtualUnwind (or walking the EBP chain on x86). It would be a nice
bonus if we could implement this kind of instrumentation with Clang.
Encouragement to switch from MSVC :)

Steve