Thread overview
Win64 exception handling
Mar 23, 2015
Johan Engelen
Mar 24, 2015
Kai Nacke
Mar 24, 2015
kink
Mar 24, 2015
Johan Engelen
Mar 25, 2015
Kai Nacke
Mar 29, 2015
Johan Engelen
Mar 30, 2015
Kai Nacke
March 23, 2015
Hi all,
  I have been trying to work on exception handling on Windows x64 (with LLVM 3.6), but for a long time now, I am stuck on something perhaps very simple.

My test case is this program:
int main() {
    try {
        throw new Exception("johan");
    } catch (Exception jow) {
    }
    return 0;
}

This crashes, and Visual Studio's debugger tells me it's because of an unhandled exception. As far as I understand it, we call RtlRaiseException() from _d_throw_exception() and that should call the personality function _d_eh_personality(). However, _d_eh_personality() is never entered. Instead, RtlRaiseException() returns and the program crashes. I am stuck on how to continue from here. I have tried many different things, but I cannot get the OS to call _d_eh_personality().

One thing that strikes me is that the exception code STATUS_LDC_D_EXCEPTION is passed to RtlRaiseException(), but is not used anywhere else in our source.
Does LLVM not correctly register _d_eh_personality() with the OS? Or is there some filtering done on the exception code?

I'd appreciate any help.

-Johan
March 24, 2015
On Monday, 23 March 2015 at 22:55:18 UTC, Johan Engelen wrote:
> Hi all,
>   I have been trying to work on exception handling on Windows x64 (with LLVM 3.6), but for a long time now, I am stuck on something perhaps very simple.
>
> My test case is this program:
> int main() {
>     try {
>         throw new Exception("johan");
>     } catch (Exception jow) {
>     }
>     return 0;
> }
>
> This crashes, and Visual Studio's debugger tells me it's because of an unhandled exception. As far as I understand it, we call RtlRaiseException() from _d_throw_exception() and that should call the personality function _d_eh_personality(). However, _d_eh_personality() is never entered. Instead, RtlRaiseException() returns and the program crashes. I am stuck on how to continue from here. I have tried many different things, but I cannot get the OS to call _d_eh_personality().
>
> One thing that strikes me is that the exception code STATUS_LDC_D_EXCEPTION is passed to RtlRaiseException(), but is not used anywhere else in our source.
> Does LLVM not correctly register _d_eh_personality() with the OS? Or is there some filtering done on the exception code?
>
> I'd appreciate any help.
>
> -Johan

Hi Johan!

A quick check revealed: it works with current LLVM trunk but not with 3.6. I hvae no clue why.

The connection between RtlRaiseException() and _d_eh_personality() is the unwind information. You can "disassemble" the unwind information with llvm-objdump -u. If the code range is wrong or some other data is corrupt then the personality function is not called. You should also disassemble the object file and check .xdata and .pdata sections.

(The unwind information from LLVM 3.6 has no flag set. I believe that at least UNW_ExceptionHandler must be set.)

Regards,
Kai
March 24, 2015
Also see https://github.com/ldc-developers/ldc/issues/758#issuecomment-76863220 (I've used LLVM master, i.e., 3.7 at the time). It appears as if the broken EH accounts for nearly all Phobos failures on Win64 and seriously corrupts the stack.

I've given up for the time being. I think it would be wiser to wait until LLVM supports MSVC exceptions, which is currently active work in progress, e.g., see http://reviews.llvm.org/rL232003 and http://www.llvm.org/docs/ExceptionHandling.html. We could then probably use MSVCRT's personality function __CxxFrameHandler3 or __C_specific_handler.
March 24, 2015
On Tuesday, 24 March 2015 at 15:55:38 UTC, kink wrote:
> Also see https://github.com/ldc-developers/ldc/issues/758#issuecomment-76863220 (I've used LLVM master, i.e., 3.7 at the time). It appears as if the broken EH accounts for nearly all Phobos failures on Win64 and seriously corrupts the stack.

Yep I had seen it. I was wondering how you got that far, and thought perhaps it had something to do with my build. (well, it _has_ something to do with my build using LLVM 3.6 :)

Thanks for your hints Kai and kink. It gave me some new pointers. I'll bang my head against my monitor some more, and move to some other thing if that doesn't work.

:)
 Johan
March 25, 2015
On Tuesday, 24 March 2015 at 21:05:31 UTC, Johan Engelen wrote:
> Thanks for your hints Kai and kink. It gave me some new pointers. I'll bang my head against my monitor some more, and move to some other thing if that doesn't work.

Hi Johan,

if you like to learn more about ldc then checkout the merge-2.067 branch and have have a look at issue #868. :-)

Regards,
Kai
March 29, 2015
On Wednesday, 25 March 2015 at 05:46:07 UTC, Kai Nacke wrote:
> On Tuesday, 24 March 2015 at 21:05:31 UTC, Johan Engelen wrote:
>> Thanks for your hints Kai and kink. It gave me some new pointers. I'll bang my head against my monitor some more, and move to some other thing if that doesn't work.
>
> Hi Johan,
>
> if you like to learn more about ldc then checkout the merge-2.067 branch and have have a look at issue #868. :-)

Hi Kai,
  I've been working on something else :-)
https://github.com/JohanEngelen/ldc/tree/coverage

-Johan
March 30, 2015
On Sunday, 29 March 2015 at 16:30:16 UTC, Johan Engelen wrote:
> On Wednesday, 25 March 2015 at 05:46:07 UTC, Kai Nacke wrote:
>> On Tuesday, 24 March 2015 at 21:05:31 UTC, Johan Engelen wrote:
>>> Thanks for your hints Kai and kink. It gave me some new pointers. I'll bang my head against my monitor some more, and move to some other thing if that doesn't work.
>>
>> Hi Johan,
>>
>> if you like to learn more about ldc then checkout the merge-2.067 branch and have have a look at issue #868. :-)
>
> Hi Kai,
>   I've been working on something else :-)
> https://github.com/JohanEngelen/ldc/tree/coverage
>
> -Johan

Hi Johan!

Looks really nice! Looking forward to your pull request. :-)

Regards,
Kai