Daniel Lehman : msvcrt: Handle synchronous flag for x64 C++ exceptions.

Alexandre Julliard julliard at winehq.org
Mon Apr 24 16:11:23 CDT 2017


Module: wine
Branch: master
Commit: b0326bea747c4f789f0fb36cf317df1b98816f22
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b0326bea747c4f789f0fb36cf317df1b98816f22

Author: Daniel Lehman <dlehman at esri.com>
Date:   Thu Apr 20 06:21:14 2017 -0700

msvcrt: Handle synchronous flag for x64 C++ exceptions.

Signed-off-by: Daniel Lehman <dlehman at esri.com>
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/cppexcept.h     |  2 ++
 dlls/msvcrt/except_i386.c   |  2 --
 dlls/msvcrt/except_x86_64.c | 16 ++++++++++++++--
 3 files changed, 16 insertions(+), 4 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..8210f7b 100644
--- a/dlls/msvcrt/except_x86_64.c
+++ b/dlls/msvcrt/except_x86_64.c
@@ -331,6 +331,12 @@ static inline void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
     return ret_addr;
 }
 
+static inline BOOL cxx_is_consolidate(const EXCEPTION_RECORD *rec)
+{
+    return rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==6 &&
+           rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block;
+}
+
 static inline void find_catch_block(EXCEPTION_RECORD *rec, ULONG64 frame,
                                     DISPATCHER_CONTEXT *dispatch,
                                     const cxx_function_descr *descr,
@@ -442,6 +448,13 @@ 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 &&
+        !cxx_is_consolidate(rec) &&
+        rec->ExceptionCode != STATUS_LONGJUMP))
+        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);
@@ -470,8 +483,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
 
     if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND))
     {
-        if (rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==6 &&
-                rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block)
+        if (cxx_is_consolidate(rec))
         {
             EXCEPTION_RECORD *new_rec = (void*)rec->ExceptionInformation[4];
             thread_data_t *data = msvcrt_get_thread_data();




More information about the wine-cvs mailing list