Module: wine Branch: master Commit: f1d307cae5eb72e6f1ec3fd3faaf3bcbb08f4692 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f1d307cae5eb72e6f1ec3fd3fa...
Author: Daniel Lehman dlehman@esri.com Date: Wed Jun 14 11:59:05 2017 +0200
msvcrt: Only unwind current catch block when handling nested exception.
Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msvcrt/except_x86_64.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-)
diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c index fffabbb..df99153 100644 --- a/dlls/msvcrt/except_x86_64.c +++ b/dlls/msvcrt/except_x86_64.c @@ -306,7 +306,7 @@ static void cxx_local_unwind(ULONG64 frame, DISPATCHER_CONTEXT *dispatch, }
TRACE("current level: %d, last level: %d\n", trylevel, last_level); - while (trylevel != last_level) + while (trylevel > last_level) { if (trylevel<0 || trylevel>=descr->unwind_count) { @@ -321,7 +321,7 @@ static void cxx_local_unwind(ULONG64 frame, DISPATCHER_CONTEXT *dispatch, } trylevel = unwind_table[trylevel].prev; } - unwind_help[0] = last_level; + unwind_help[0] = trylevel; }
static LONG CALLBACK cxx_rethrow_filter(PEXCEPTION_POINTERS eptrs, void *c) @@ -512,6 +512,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame, DWORD throw_func_off; void *throw_func; UINT i, j; + int unwindlevel = -1;
if (descr->magic<CXX_FRAME_MAGIC_VC6 || descr->magic>CXX_FRAME_MAGIC_VC8) { @@ -545,6 +546,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame, if (rva_to_ptr(catchblock->handler, dispatch->ImageBase) == throw_func) { TRACE("nested exception detected\n"); + unwindlevel = tryblock->end_level; orig_frame = *(ULONG64*)rva_to_ptr(catchblock->frame, frame); TRACE("setting orig_frame to %lx\n", orig_frame); } @@ -554,23 +556,11 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND)) { - if (cxx_is_consolidate(rec)) - { - if (rec->ExceptionFlags & EH_TARGET_UNWIND) - { - const cxx_function_descr *orig_descr = (void*)rec->ExceptionInformation[2]; - int end_level = rec->ExceptionInformation[3]; - orig_frame = rec->ExceptionInformation[1]; - - cxx_local_unwind(orig_frame, dispatch, orig_descr, end_level); - } - else if(frame == orig_frame) - cxx_local_unwind(frame, dispatch, descr, -1); - return ExceptionContinueSearch; - } - - if (frame == orig_frame) - cxx_local_unwind(frame, dispatch, descr, rec->ExceptionFlags & EH_TARGET_UNWIND ? trylevel : -1); + if (rec->ExceptionFlags & EH_TARGET_UNWIND) + cxx_local_unwind(orig_frame, dispatch, descr, + cxx_is_consolidate(rec) ? rec->ExceptionInformation[3] : trylevel); + else + cxx_local_unwind(orig_frame, dispatch, descr, unwindlevel); return ExceptionContinueSearch; } if (!descr->tryblock_count) return ExceptionContinueSearch;