Daniel Lehman : msvcrt: Support rethrowing SEH exceptions.

Alexandre Julliard julliard at winehq.org
Wed Jun 14 15:44:58 CDT 2017


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

Author: Daniel Lehman <dlehman at esri.com>
Date:   Wed Jun 14 11:59:19 2017 +0200

msvcrt: Support rethrowing SEH exceptions.

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

---

 dlls/msvcrt/except_x86_64.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c
index df99153..7e9c38d 100644
--- a/dlls/msvcrt/except_x86_64.c
+++ b/dlls/msvcrt/except_x86_64.c
@@ -118,6 +118,7 @@ typedef struct
 {
     ULONG64 dest_frame;
     ULONG64 orig_frame;
+    EXCEPTION_RECORD *seh_rec;
     DISPATCHER_CONTEXT *dispatch;
     const cxx_function_descr *descr;
 } se_translator_ctx;
@@ -350,6 +351,7 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
     ULONG64 frame = rec->ExceptionInformation[1];
     const cxx_function_descr *descr = (void*)rec->ExceptionInformation[2];
     EXCEPTION_RECORD *prev_rec = (void*)rec->ExceptionInformation[4];
+    EXCEPTION_RECORD *untrans_rec = (void*)rec->ExceptionInformation[6];
     void* (__cdecl *handler)(ULONG64 unk, ULONG64 rbp) = (void*)rec->ExceptionInformation[5];
     int *unwind_help = rva_to_ptr(descr->unwind_help, frame);
     cxx_catch_ctx ctx;
@@ -370,8 +372,17 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
             TRACE("detect rethrow: exception code: %x\n", prev_rec->ExceptionCode);
             ctx.rethrow = TRUE;
 
-            RaiseException(prev_rec->ExceptionCode, prev_rec->ExceptionFlags,
-                    prev_rec->NumberParameters, prev_rec->ExceptionInformation);
+            if (untrans_rec)
+            {
+                __DestructExceptionObject(prev_rec);
+                RaiseException(untrans_rec->ExceptionCode, untrans_rec->ExceptionFlags,
+                        untrans_rec->NumberParameters, untrans_rec->ExceptionInformation);
+            }
+            else
+            {
+                RaiseException(prev_rec->ExceptionCode, prev_rec->ExceptionFlags,
+                        prev_rec->NumberParameters, prev_rec->ExceptionInformation);
+            }
         }
         __ENDTRY
     }
@@ -384,12 +395,12 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
 
 static inline BOOL cxx_is_consolidate(const EXCEPTION_RECORD *rec)
 {
-    return rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==6 &&
+    return rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==7 &&
            rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block;
 }
 
-static inline void find_catch_block(EXCEPTION_RECORD *rec, ULONG64 frame,
-                                    DISPATCHER_CONTEXT *dispatch,
+static inline void find_catch_block(EXCEPTION_RECORD *rec, EXCEPTION_RECORD *untrans_rec,
+                                    ULONG64 frame, DISPATCHER_CONTEXT *dispatch,
                                     const cxx_function_descr *descr,
                                     cxx_exception_type *info, ULONG64 orig_frame)
 {
@@ -465,7 +476,7 @@ static inline void find_catch_block(EXCEPTION_RECORD *rec, ULONG64 frame,
             memset(&catch_record, 0, sizeof(catch_record));
             catch_record.ExceptionCode = STATUS_UNWIND_CONSOLIDATE;
             catch_record.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
-            catch_record.NumberParameters = 6;
+            catch_record.NumberParameters = 7;
             catch_record.ExceptionInformation[0] = (ULONG_PTR)call_catch_block;
             catch_record.ExceptionInformation[1] = orig_frame;
             catch_record.ExceptionInformation[2] = (ULONG_PTR)descr;
@@ -473,6 +484,7 @@ static inline void find_catch_block(EXCEPTION_RECORD *rec, ULONG64 frame,
             catch_record.ExceptionInformation[4] = (ULONG_PTR)rec;
             catch_record.ExceptionInformation[5] =
                 (ULONG_PTR)rva_to_ptr(catchblock->handler, dispatch->ImageBase);
+            catch_record.ExceptionInformation[6] = (ULONG_PTR)untrans_rec;
             RtlUnwindEx((void*)frame, (void*)dispatch->ControlPc, &catch_record, NULL, &context, NULL);
         }
     }
@@ -493,7 +505,7 @@ static LONG CALLBACK se_translation_filter(EXCEPTION_POINTERS *ep, void *c)
     }
 
     exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
-    find_catch_block(rec, ctx->dest_frame, ctx->dispatch,
+    find_catch_block(rec, ctx->seh_rec, ctx->dest_frame, ctx->dispatch,
                      ctx->descr, exc_type, ctx->orig_frame);
 
     __DestructExceptionObject(rec);
@@ -590,6 +602,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
 
             ctx.dest_frame = frame;
             ctx.orig_frame = orig_frame;
+            ctx.seh_rec    = rec;
             ctx.dispatch   = dispatch;
             ctx.descr      = descr;
             __TRY
@@ -605,7 +618,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
         }
     }
 
-    find_catch_block(rec, frame, dispatch, descr, exc_type, orig_frame);
+    find_catch_block(rec, NULL, frame, dispatch, descr, exc_type, orig_frame);
     return ExceptionContinueSearch;
 }
 




More information about the wine-cvs mailing list