msvcrt: Handle rethrowing from nested try blocks on x64.

Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Paul Gofman 2020-09-09 19:12:06 +03:00 committed by Alexandre Julliard
parent 4765c5ffe2
commit f65fb09dff
1 changed files with 9 additions and 2 deletions

View File

@ -90,6 +90,7 @@ typedef struct
{ {
cxx_frame_info frame_info; cxx_frame_info frame_info;
BOOL rethrow; BOOL rethrow;
EXCEPTION_RECORD *prev_rec;
} cxx_catch_ctx; } cxx_catch_ctx;
typedef struct typedef struct
@ -306,14 +307,13 @@ static void cxx_local_unwind(ULONG64 frame, DISPATCHER_CONTEXT *dispatch,
static LONG CALLBACK cxx_rethrow_filter(PEXCEPTION_POINTERS eptrs, void *c) static LONG CALLBACK cxx_rethrow_filter(PEXCEPTION_POINTERS eptrs, void *c)
{ {
EXCEPTION_RECORD *rec = eptrs->ExceptionRecord; EXCEPTION_RECORD *rec = eptrs->ExceptionRecord;
thread_data_t *data = msvcrt_get_thread_data();
cxx_catch_ctx *ctx = c; cxx_catch_ctx *ctx = c;
if (rec->ExceptionCode != CXX_EXCEPTION) if (rec->ExceptionCode != CXX_EXCEPTION)
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
if (!rec->ExceptionInformation[1] && !rec->ExceptionInformation[2]) if (!rec->ExceptionInformation[1] && !rec->ExceptionInformation[2])
return EXCEPTION_EXECUTE_HANDLER; return EXCEPTION_EXECUTE_HANDLER;
if (rec->ExceptionInformation[1] == data->exc_record->ExceptionInformation[1]) if (rec->ExceptionInformation[1] == ctx->prev_rec->ExceptionInformation[1])
ctx->rethrow = TRUE; ctx->rethrow = TRUE;
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
} }
@ -340,6 +340,7 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
TRACE("calling handler %p\n", handler); TRACE("calling handler %p\n", handler);
ctx.rethrow = FALSE; ctx.rethrow = FALSE;
ctx.prev_rec = prev_rec;
__CxxRegisterExceptionObject(&ep, &ctx.frame_info); __CxxRegisterExceptionObject(&ep, &ctx.frame_info);
msvcrt_get_thread_data()->processing_throw--; msvcrt_get_thread_data()->processing_throw--;
__TRY __TRY
@ -565,6 +566,12 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
if (rec->ExceptionCode == CXX_EXCEPTION) if (rec->ExceptionCode == CXX_EXCEPTION)
{ {
if (!rec->ExceptionInformation[1] && !rec->ExceptionInformation[2])
{
TRACE("rethrow detected.\n");
*rec = *msvcrt_get_thread_data()->exc_record;
}
exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
if (TRACE_ON(seh)) if (TRACE_ON(seh))