-
Notifications
You must be signed in to change notification settings - Fork 29
MSVC/x86 exception handling: rewrite avoiding VC runtime internals #54
Conversation
rainers
commented
Jan 22, 2016
- setup exception handler for exceptions during cleanup to avoid C++ calling std::terminate
- remove vcruntime hacks
- when converting exception to error, do not rethrow if the catch handles errors, too
- add support for the "safeseh" attribute
} | ||
|
||
extern(C) void _d_leave_cleanup(void* ptr) | ||
// @safeseh to be marked as "safe" for the OS securtity check |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
securtity => security
Could you also make an IR testcase for this? ;-) |
I'll try though I've yet to see any of the IR tests to pass on my system. |
Done. |
I'll try though I've yet to see any of the IR tests to pass on my system. |
Sorry for being slow with this, I've just reported it here: ldc-developers/ldc#1265 |
Finally implemented swapping exception information for fibers and figured why exceptions where never caught in fibers. |
fa62b2e
to
9d8f75e
Compare
I've added support for catching D exceptions in C++, see ldc-developers/dmd-testsuite#15 for a demonstrating test case. |
@@ -4854,16 +4858,21 @@ private: | |||
finalHandler = reg.handler; | |||
} | |||
|
|||
pstack -= EXCEPTION_REGISTRATION.sizeof; | |||
// With safeseh(?), the chain must not extend to the very top |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation and the change, it's a lot clearer to me now. (I thought you were referring to the beginning of the record before instead of to the past-the-end address.)
Shouldn't the change also go into the upstream implementation, though? (We can just cherry-pick the fix from master afterwards.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the change also go into the upstream implementation, though? (We can just cherry-pick the fix from master afterwards.)
I don't think dmd will ever support safeseh. It shouldn't do harm to add it, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to allow any exception type to be mapped to C++. |
{ | ||
auto olength = other._length; other._length = _length; _length = olength; | ||
auto op = other._p; other._p = _p; _p = op; | ||
auto ocap = other._cap; other._cap = _cap; _cap = ocap; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just nit-picking, but how about:
static void swapField(T)(ref T a, ref T b) { T o = b; b = a; a = o; }
swapField(_length, other._length);
swapField(_p, other._p);
swapField(_cap, other._cap);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I think there should be a swap function somewhere in druntime, it is implemented again and again...
I've cherry-picked your upstream commit regarding |
…g std::terminate remove vcruntime hacks when converting to exception to error, do not rethrow if the catch handles errors, too
f0d795f
to
7484da5
Compare
Rebased and squashed some commits. There's still one open issue that doesn't work with this design: cleanup funclets cannot have exception handling themselves, but that's valid in D, e.g. by using try/catch in scope(exit). The LLVM devs don't plan to implement this any time soon. That's why I want to try outlining cleanup code in the front-end. This might also help the x64 implementation, as it is unlikely that you can setup exception information on x64 as done here (emplace an exception frame in the calling functions stack space). |
👍
And I thought it'd be finished. ;) All the best for your next adventure then, you rock! :) |
Not sure it'll work out this time. I expect some troubles regarding cleanups that are already inside nested functions. |
Do you think the current method (setting up the |
I hope I can try the frontend-outling this weekend. If that doesn't work out, merging the two solutions might be the best solution ATM for x64 support. |
FYI: I actually managed to rewrite cleanup blocks, e.g. Unfortunately, it causes some of the expected compile errors when having to access several contexts. In addition, errors show the additional indirection in instantiation traces (_d_cleanup must be a template to inherit function attributes). So it doesn't seem a good solution ATM. I'm currently torn between this and the previous version using the std::terminate hook. Both are rather hacky. I'll investigate how to make the latter safer to avoid skipping a std::terminate call that's not initiated by an exception during cleanup (it would probably also crash). |
Closing this in favor of #60. |