Daniel Lehman : msvcrt: Clean up registered C++ objects in handler.
Alexandre Julliard
julliard at winehq.org
Wed Jun 14 15:44:58 CDT 2017
Module: wine
Branch: master
Commit: 57266eec5e6e8f3f064e24fa21b7e0bd92a2f1b1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=57266eec5e6e8f3f064e24fa21b7e0bd92a2f1b1
Author: Daniel Lehman <dlehman at esri.com>
Date: Wed Jun 14 11:58:45 2017 +0200
msvcrt: Clean up registered C++ objects in handler.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/msvcrt/except_x86_64.c | 62 +++++++++++++++++++++++++--------------------
1 file changed, 34 insertions(+), 28 deletions(-)
diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c
index baacc94..fffabbb 100644
--- a/dlls/msvcrt/except_x86_64.c
+++ b/dlls/msvcrt/except_x86_64.c
@@ -110,6 +110,12 @@ typedef struct __cxx_function_descr
typedef struct
{
+ cxx_frame_info frame_info;
+ BOOL rethrow;
+} cxx_catch_ctx;
+
+typedef struct
+{
ULONG64 dest_frame;
ULONG64 orig_frame;
DISPATCHER_CONTEXT *dispatch;
@@ -318,17 +324,27 @@ static void cxx_local_unwind(ULONG64 frame, DISPATCHER_CONTEXT *dispatch,
unwind_help[0] = last_level;
}
-static LONG CALLBACK cxx_rethrow_filter(PEXCEPTION_POINTERS eptrs)
+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;
+ __CxxUnregisterExceptionObject(&ctx->frame_info, ctx->rethrow);
+}
+
static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
{
ULONG64 frame = rec->ExceptionInformation[1];
@@ -336,25 +352,31 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
EXCEPTION_RECORD *prev_rec = (void*)rec->ExceptionInformation[4];
void* (__cdecl *handler)(ULONG64 unk, ULONG64 rbp) = (void*)rec->ExceptionInformation[5];
int *unwind_help = rva_to_ptr(descr->unwind_help, frame);
- cxx_frame_info frame_info;
+ cxx_catch_ctx ctx;
void *ret_addr = NULL;
TRACE("calling handler %p\n", handler);
- __CxxRegisterExceptionObject(&prev_rec, &frame_info);
+ ctx.rethrow = FALSE;
+ __CxxRegisterExceptionObject(&prev_rec, &ctx.frame_info);
__TRY
{
- ret_addr = handler(0, frame);
- }
- __EXCEPT(cxx_rethrow_filter)
- {
- TRACE("detect rethrow: exception code: %x\n", prev_rec->ExceptionCode);
+ __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;
- RaiseException(prev_rec->ExceptionCode, prev_rec->ExceptionFlags,
- prev_rec->NumberParameters, prev_rec->ExceptionInformation);
+ RaiseException(prev_rec->ExceptionCode, prev_rec->ExceptionFlags,
+ prev_rec->NumberParameters, prev_rec->ExceptionInformation);
+ }
+ __ENDTRY
}
- __ENDTRY
- __CxxUnregisterExceptionObject(&frame_info, FALSE);
+ __FINALLY_CTX(cxx_catch_cleanup, &ctx)
+
unwind_help[0] = -2;
unwind_help[1] = -1;
return ret_addr;
@@ -534,10 +556,6 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
{
if (cxx_is_consolidate(rec))
{
- EXCEPTION_RECORD *new_rec = (void*)rec->ExceptionInformation[4];
- thread_data_t *data = msvcrt_get_thread_data();
- frame_info *cur;
-
if (rec->ExceptionFlags & EH_TARGET_UNWIND)
{
const cxx_function_descr *orig_descr = (void*)rec->ExceptionInformation[2];
@@ -548,18 +566,6 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
}
else if(frame == orig_frame)
cxx_local_unwind(frame, dispatch, descr, -1);
-
- /* FIXME: we should only unregister frames registered by call_catch_block here */
- for (cur = data->frame_info_head; cur; cur = cur->next)
- {
- if ((ULONG64)cur <= frame)
- {
- __CxxUnregisterExceptionObject((cxx_frame_info*)cur,
- new_rec->ExceptionCode == CXX_EXCEPTION &&
- data->exc_record->ExceptionCode == CXX_EXCEPTION &&
- new_rec->ExceptionInformation[1] == data->exc_record->ExceptionInformation[1]);
- }
- }
return ExceptionContinueSearch;
}
More information about the wine-cvs
mailing list