From d3f13adaf04cbd186f592832bfef6b072d5ee03c Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Tue, 13 Jun 2017 14:16:13 -0700 Subject: [PATCH v3 2/3] msvcrt: Support rethrowing C++ exceptions. v3: with changes from Piotr - moved whole rethrow handling to cxx_rethrow_filter/call_catch_block Signed-off-by: Daniel Lehman --- dlls/msvcrt/except_x86_64.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c index 6103005..be067fe 100644 --- a/dlls/msvcrt/except_x86_64.c +++ b/dlls/msvcrt/except_x86_64.c @@ -324,6 +324,21 @@ static void cxx_local_unwind(ULONG64 frame, DISPATCHER_CONTEXT *dispatch, unwind_help[0] = trylevel; } +static LONG CALLBACK cxx_rethrow_filter(PEXCEPTION_POINTERS eptrs, void *c) +{ + EXCEPTION_RECORD *rec = eptrs->ExceptionRecord; + thread_data_t *data = msvcrt_get_thread_data(); + cxx_catch_ctx *ctx = c; + + if (rec->ExceptionCode != CXX_EXCEPTION) + return EXCEPTION_CONTINUE_SEARCH; + if (!rec->ExceptionInformation[1] && !rec->ExceptionInformation[2]) + return EXCEPTION_EXECUTE_HANDLER; + if (rec->ExceptionInformation[1] == data->exc_record->ExceptionInformation[1]) + ctx->rethrow = TRUE; + return EXCEPTION_CONTINUE_SEARCH; +} + static void CALLBACK cxx_catch_cleanup(BOOL normal, void *c) { cxx_catch_ctx *ctx = c; @@ -338,7 +353,7 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec) 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; - void *ret_addr; + void *ret_addr = NULL; TRACE("calling handler %p\n", handler); @@ -346,7 +361,19 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec) __CxxRegisterExceptionObject(&prev_rec, &ctx.frame_info); __TRY { - ret_addr = handler(0, frame); + __TRY + { + ret_addr = handler(0, frame); + } + __EXCEPT_CTX(cxx_rethrow_filter, &ctx) + { + TRACE("detect rethrow: exception code: %x\n", prev_rec->ExceptionCode); + ctx.rethrow = TRUE; + + _CxxThrowException((exception *)prev_rec->ExceptionInformation[1], + (const cxx_exception_type *)prev_rec->ExceptionInformation[2]); + } + __ENDTRY } __FINALLY_CTX(cxx_catch_cleanup, &ctx) @@ -538,19 +565,6 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame, } if (!descr->tryblock_count) return ExceptionContinueSearch; - if (rec->ExceptionCode == CXX_EXCEPTION && - rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) - { - *rec = *msvcrt_get_thread_data()->exc_record; - rec->ExceptionFlags &= ~EH_UNWINDING; - if (TRACE_ON(seh)) { - TRACE("detect rethrow: exception code: %x\n", rec->ExceptionCode); - if (rec->ExceptionCode == CXX_EXCEPTION) - TRACE("re-propage: obj: %lx, type: %lx\n", - rec->ExceptionInformation[1], rec->ExceptionInformation[2]); - } - } - if (rec->ExceptionCode == CXX_EXCEPTION) { exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; -- 1.9.5