Piotr Caban : msvcrt: Destroy exception object when frame storing it is unwound.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Mar 16 11:36:40 CDT 2016
Module: wine
Branch: master
Commit: f085be3028e86ebc6666d20a4802831bf7b3f3bc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f085be3028e86ebc6666d20a4802831bf7b3f3bc
Author: Piotr Caban <piotr at codeweavers.com>
Date: Tue Mar 15 13:41:20 2016 +0100
msvcrt: Destroy exception object when frame storing it is unwound.
Thrown object was incorrectly freed in following situation:
try {
throw obj;
} catch(object &obj) {
try {
throw 1;
} catch(...) {}
//use object here
}
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/msvcrt/except_i386.c | 27 ++++++++++-----------------
1 file changed, 10 insertions(+), 17 deletions(-)
diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c
index 56165c0..78ce488 100644
--- a/dlls/msvcrt/except_i386.c
+++ b/dlls/msvcrt/except_i386.c
@@ -131,6 +131,7 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame
PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch,
const cxx_function_descr *descr,
EXCEPTION_REGISTRATION_RECORD* nested_frame, int nested_trylevel );
+BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void*);
/* call a function with a given ebp */
static inline void *call_ebp_func( void *func, void *ebp )
@@ -361,9 +362,18 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG
CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
{
struct catch_func_nested_frame *nested_frame = (struct catch_func_nested_frame *)frame;
+ PEXCEPTION_RECORD prev_rec = nested_frame->rec;
if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
{
+ if (prev_rec->ExceptionCode == CXX_EXCEPTION)
+ {
+ void *object = (void*)prev_rec->ExceptionInformation[1];
+ cxx_exception_type *info = (cxx_exception_type*) prev_rec->ExceptionInformation[2];
+ if (info && info->destructor && _IsExceptionObjectToBeDestroyed(object))
+ call_dtor( info->destructor, object);
+ }
+
msvcrt_get_thread_data()->exc_record = nested_frame->prev_rec;
return ExceptionContinueSearch;
}
@@ -372,7 +382,6 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG
if(rec->ExceptionCode == CXX_EXCEPTION)
{
- PEXCEPTION_RECORD prev_rec = nested_frame->rec;
if((rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) ||
(prev_rec->ExceptionCode == CXX_EXCEPTION &&
rec->ExceptionInformation[1] == prev_rec->ExceptionInformation[1] &&
@@ -388,22 +397,6 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG
rec->ExceptionInformation[1], rec->ExceptionInformation[2]);
}
}
- else if (nested_frame->prev_rec && nested_frame->prev_rec->ExceptionCode == CXX_EXCEPTION &&
- nested_frame->prev_rec->ExceptionInformation[1] == prev_rec->ExceptionInformation[1] &&
- nested_frame->prev_rec->ExceptionInformation[2] == prev_rec->ExceptionInformation[2])
- {
- TRACE("detect threw new exception in catch block - not owning old(obj: %lx type: %lx)\n",
- prev_rec->ExceptionInformation[1], prev_rec->ExceptionInformation[2]);
- }
- else if (prev_rec->ExceptionCode == CXX_EXCEPTION) {
- /* new exception in exception handler, destroy old */
- void *object = (void*)prev_rec->ExceptionInformation[1];
- cxx_exception_type *info = (cxx_exception_type*) prev_rec->ExceptionInformation[2];
- TRACE("detect threw new exception in catch block - destroy old(obj: %p type: %p)\n",
- object, info);
- if(info && info->destructor)
- call_dtor( info->destructor, object );
- }
else
{
TRACE("detect threw new exception in catch block\n");
More information about the wine-cvs
mailing list