From 04c9000eed70920536f140656e7f47c8f667e109 Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Thu, 20 Apr 2017 06:21:14 -0700 Subject: [PATCH] msvcrt: Handle synchronous flag for x64 C++ exceptions adapted from except_i386.c the program below demonstrates the difference the flag can make the destructor is called when /EHa is specified while it is not with /EHs (same is true with /EHsc). separate functions are used because try/catch can't be mixed with __try/__except wine async.exe klass::klass klass::~klass wine sync.exe klass::klass build with: cl /Od /EHa standalone.cpp /link /out:async.exe cl /Od /EHs standalone.cpp /link /out:sync.exe standalone.cpp: &include struct klass { klass(void) {printf("%s\n", __FUNCTION__);} ~klass(void) {printf("%s\n", __FUNCTION__);} }; void cxx_frame_that_throws_segv(void) { klass k; try { int *p = NULL; *p = 0x42; } catch (int i) { } } int main(int argc, char **argv) { __try { cxx_frame_that_throws_segv(); } __except(1) { } return 0; } Signed-off-by: Daniel Lehman --- dlls/msvcrt/cppexcept.h | 2 ++ dlls/msvcrt/except_i386.c | 2 -- dlls/msvcrt/except_x86_64.c | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/dlls/msvcrt/cppexcept.h b/dlls/msvcrt/cppexcept.h index 6ea5818..2091889 100644 --- a/dlls/msvcrt/cppexcept.h +++ b/dlls/msvcrt/cppexcept.h @@ -26,6 +26,8 @@ #define CXX_FRAME_MAGIC_VC8 0x19930522 #define CXX_EXCEPTION 0xe06d7363 +#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs and /EHsc) */ + typedef void (*vtable_ptr)(void); /* type_info object, see cpp.c for implementation */ diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c index d26a864..963bd58 100644 --- a/dlls/msvcrt/except_i386.c +++ b/dlls/msvcrt/except_i386.c @@ -96,8 +96,6 @@ typedef struct __cxx_function_descr UINT flags; /* flags when magic >= VC8 */ } cxx_function_descr; -#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs) */ - typedef struct _SCOPETABLE { int previousTryLevel; diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c index d299608..c7dbe5c 100644 --- a/dlls/msvcrt/except_x86_64.c +++ b/dlls/msvcrt/except_x86_64.c @@ -442,6 +442,11 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame, return ExceptionContinueSearch; } + if (descr->magic >= CXX_FRAME_MAGIC_VC8 && + (descr->flags & FUNC_DESCR_SYNCHRONOUS) && + (rec->ExceptionCode != CXX_EXCEPTION && rec->ExceptionCode != STATUS_UNWIND_CONSOLIDATE)) + return ExceptionContinueSearch; /* handle only c++ exceptions */ + /* update orig_frame if it's a nested exception */ throw_func_off = RtlLookupFunctionEntry(dispatch->ControlPc, &throw_base, NULL)->BeginAddress; throw_func = rva_to_ptr(throw_func_off, throw_base); -- 1.9.5