msvcrt: Improved _local_unwind2 implementation.

Thanks to Dmitry Timoshkov for a test case.
This commit is contained in:
Alexandre Julliard 2007-03-13 15:53:09 +01:00
parent 4d1d01f266
commit 35d728ef50
1 changed files with 11 additions and 13 deletions

View File

@ -88,7 +88,7 @@ static DWORD MSVCRT_nested_handler(PEXCEPTION_RECORD rec,
PCONTEXT context, PCONTEXT context,
EXCEPTION_REGISTRATION_RECORD** dispatch) EXCEPTION_REGISTRATION_RECORD** dispatch)
{ {
if (rec->ExceptionFlags & 0x6) if (!(rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)))
return ExceptionContinueSearch; return ExceptionContinueSearch;
*dispatch = frame; *dispatch = frame;
return ExceptionCollidedUnwind; return ExceptionCollidedUnwind;
@ -126,28 +126,26 @@ void CDECL _global_unwind2(EXCEPTION_REGISTRATION_RECORD* frame)
*/ */
void CDECL _local_unwind2(MSVCRT_EXCEPTION_FRAME* frame, int trylevel) void CDECL _local_unwind2(MSVCRT_EXCEPTION_FRAME* frame, int trylevel)
{ {
MSVCRT_EXCEPTION_FRAME *curframe = frame;
EXCEPTION_REGISTRATION_RECORD reg; EXCEPTION_REGISTRATION_RECORD reg;
TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel); TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel);
/* Register a handler in case of a nested exception */ /* Register a handler in case of a nested exception */
reg.Handler = (PEXCEPTION_HANDLER)MSVCRT_nested_handler; reg.Handler = MSVCRT_nested_handler;
reg.Prev = NtCurrentTeb()->Tib.ExceptionList; reg.Prev = NtCurrentTeb()->Tib.ExceptionList;
__wine_push_frame(&reg); __wine_push_frame(&reg);
while (frame->trylevel != TRYLEVEL_END && frame->trylevel != trylevel) while (frame->trylevel != TRYLEVEL_END && frame->trylevel != trylevel)
{ {
int curtrylevel = frame->scopetable[frame->trylevel].previousTryLevel; int level = frame->trylevel;
curframe = frame; frame->trylevel = frame->scopetable[level].previousTryLevel;
curframe->trylevel = curtrylevel; if (!frame->scopetable[level].lpfnFilter)
if (!frame->scopetable[curtrylevel].lpfnFilter) {
{ FIXME( "__try block cleanup level %d handler %p not fully implemented\n",
ERR("__try block cleanup not implemented - expect crash!\n"); level, frame->scopetable[level].lpfnHandler );
/* FIXME: Remove current frame, set ebp, call /* FIXME: should probably set ebp to frame->_ebp */
* frame->scopetable[curtrylevel].lpfnHandler() frame->scopetable[level].lpfnHandler();
*/ }
}
} }
__wine_pop_frame(&reg); __wine_pop_frame(&reg);
TRACE("unwound OK\n"); TRACE("unwound OK\n");