Module: wine Branch: refs/heads/master Commit: 62dc7f52f47f8a406d3b8a155b7d81cb19f3c98b URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=62dc7f52f47f8a406d3b8a15...
Author: Peter Beutner p.beutner@gmx.net Date: Wed Feb 22 12:04:13 2006 +0100
msvcrt: Fix handling of nested exceptions. Move handling of nested exceptions completely in the catch_function_nested_handler(). If a new exception was thrown inside a catch block destroy the old exception object, if it is a rethrow re-propagate the previous object.
---
dlls/msvcrt/cppexcept.c | 37 +++++++++++++++++++++++++++---------- 1 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/dlls/msvcrt/cppexcept.c b/dlls/msvcrt/cppexcept.c index 073674a..d42e88e 100644 --- a/dlls/msvcrt/cppexcept.c +++ b/dlls/msvcrt/cppexcept.c @@ -242,13 +242,34 @@ static DWORD catch_function_nested_handl msvcrt_get_thread_data()->exc_record = nested_frame->prev_rec; return ExceptionContinueSearch; } - else + + TRACE( "got nested exception in catch function\n" ); + + if(rec->ExceptionCode == CXX_EXCEPTION) { - TRACE( "got nested exception in catch function\n" ); - return cxx_frame_handler( rec, nested_frame->cxx_frame, context, - NULL, nested_frame->descr, &nested_frame->frame, - nested_frame->trylevel ); + PEXCEPTION_RECORD prev_rec = msvcrt_get_thread_data()->exc_record; + if(rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) + { + /* exception was rethrown */ + rec->ExceptionInformation[1] = prev_rec->ExceptionInformation[1]; + rec->ExceptionInformation[2] = prev_rec->ExceptionInformation[2]; + TRACE("detect rethrow: re-propagate: obj: %lx, type: %lx\n", + rec->ExceptionInformation[1], rec->ExceptionInformation[2]); + } + else { + /* 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 ); + } } + + return cxx_frame_handler( rec, nested_frame->cxx_frame, context, + NULL, nested_frame->descr, &nested_frame->frame, + nested_frame->trylevel ); }
/* find and call the appropriate catch block for an exception */ @@ -359,11 +380,7 @@ DWORD cxx_frame_handler( PEXCEPTION_RECO return exc_type->custom_handler( rec, frame, context, dispatch, descr, nested_trylevel, nested_frame, 0 ); } - if (!exc_type) /* nested exception, fetch info from original exception */ - { - rec = msvcrt_get_thread_data()->exc_record; - exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; - } + if (TRACE_ON(seh)) { TRACE("handling C++ exception rec %p frame %p trylevel %d descr %p nested_frame %p\n",