Piotr Caban : msvcrt: Destroy exception object if it' s no longer used when exiting catch.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Mar 16 11:36:40 CDT 2016


Module: wine
Branch: master
Commit: 941e4f7e9ded4db0f2d708f95e2b16c974f2cfdf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=941e4f7e9ded4db0f2d708f95e2b16c974f2cfdf

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Tue Mar 15 13:41:00 2016 +0100

msvcrt: Destroy exception object if it's no longer used when exiting catch.

Thrown object was incorrectly freed in following situation:
try {
     throw obj;
} catch(object &obj) {
     try {
         throw;
     } 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 | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c
index 660fb6d..116a429 100644
--- a/dlls/msvcrt/except_i386.c
+++ b/dlls/msvcrt/except_i386.c
@@ -446,6 +446,7 @@ BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj)
 /* returns the address to continue execution to after the catch block was called */
 static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame *frame,
                                      const cxx_function_descr *descr, int nested_trylevel,
+                                     EXCEPTION_REGISTRATION_RECORD *catch_frame,
                                      cxx_exception_type *info )
 {
     UINT i;
@@ -487,7 +488,7 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame
             }
 
             /* unwind the stack */
-            RtlUnwind( frame, 0, rec, 0 );
+            RtlUnwind( catch_frame ? catch_frame : &frame->frame, 0, rec, 0 );
             cxx_local_unwind( frame, descr, tryblock->start_level );
             frame->trylevel = tryblock->end_level + 1;
 
@@ -511,7 +512,8 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame
             __wine_pop_frame( &nested_frame.frame );
 
             ((DWORD*)frame)[-1] = save_esp;
-            if (info && info->destructor) call_dtor( info->destructor, object );
+            if (info && info->destructor && _IsExceptionObjectToBeDestroyed(object))
+                call_dtor( info->destructor, object );
             TRACE( "done, continuing at %p\n", addr );
 
             continue_after_catch( frame, addr );
@@ -655,7 +657,7 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame
         }
     }
 
-    call_catch_block( rec, frame, descr, frame->trylevel, exc_type );
+    call_catch_block( rec, frame, descr, frame->trylevel, nested_frame, exc_type );
     return ExceptionContinueSearch;
 }
 




More information about the wine-cvs mailing list