msvcrt: Handle seh exception rethrowing in catch_function_nested_handler.

This commit is contained in:
Piotr Caban 2014-04-30 13:50:25 +02:00 committed by Alexandre Julliard
parent b4d30e92c9
commit b5b454c504
1 changed files with 16 additions and 7 deletions

View File

@ -374,23 +374,28 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG
{ {
PEXCEPTION_RECORD prev_rec = nested_frame->rec; PEXCEPTION_RECORD prev_rec = nested_frame->rec;
if((rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) || if((rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) ||
(rec->ExceptionInformation[1] == prev_rec->ExceptionInformation[1] && (prev_rec->ExceptionCode == CXX_EXCEPTION &&
rec->ExceptionInformation[1] == prev_rec->ExceptionInformation[1] &&
rec->ExceptionInformation[2] == prev_rec->ExceptionInformation[2])) rec->ExceptionInformation[2] == prev_rec->ExceptionInformation[2]))
{ {
/* exception was rethrown */ /* exception was rethrown */
rec->ExceptionInformation[1] = prev_rec->ExceptionInformation[1]; *rec = *prev_rec;
rec->ExceptionInformation[2] = prev_rec->ExceptionInformation[2]; rec->ExceptionFlags &= ~EH_UNWINDING;
TRACE("detect rethrow: re-propagate: obj: %lx, type: %lx\n", if(TRACE_ON(seh)) {
rec->ExceptionInformation[1], rec->ExceptionInformation[2]); TRACE("detect rethrow: exception code: %x\n", rec->ExceptionCode);
if(rec->ExceptionCode == CXX_EXCEPTION)
TRACE("re-propage: obj: %lx, type: %lx\n",
rec->ExceptionInformation[1], rec->ExceptionInformation[2]);
}
} }
else if (nested_frame->prev_rec && 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[1] == prev_rec->ExceptionInformation[1] &&
nested_frame->prev_rec->ExceptionInformation[2] == prev_rec->ExceptionInformation[2]) 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", TRACE("detect threw new exception in catch block - not owning old(obj: %lx type: %lx)\n",
prev_rec->ExceptionInformation[1], prev_rec->ExceptionInformation[2]); prev_rec->ExceptionInformation[1], prev_rec->ExceptionInformation[2]);
} }
else { else if (prev_rec->ExceptionCode == CXX_EXCEPTION) {
/* new exception in exception handler, destroy old */ /* new exception in exception handler, destroy old */
void *object = (void*)prev_rec->ExceptionInformation[1]; void *object = (void*)prev_rec->ExceptionInformation[1];
cxx_exception_type *info = (cxx_exception_type*) prev_rec->ExceptionInformation[2]; cxx_exception_type *info = (cxx_exception_type*) prev_rec->ExceptionInformation[2];
@ -399,6 +404,10 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG
if(info && info->destructor) if(info && info->destructor)
call_dtor( info->destructor, object ); call_dtor( info->destructor, object );
} }
else
{
TRACE("detect threw new exception in catch block\n");
}
} }
return cxx_frame_handler( rec, nested_frame->cxx_frame, context, return cxx_frame_handler( rec, nested_frame->cxx_frame, context,