msvcrt: Improved _local_unwind2 implementation.
Thanks to Dmitry Timoshkov for a test case.
This commit is contained in:
parent
4d1d01f266
commit
35d728ef50
|
@ -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(®);
|
__wine_push_frame(®);
|
||||||
|
|
||||||
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(®);
|
__wine_pop_frame(®);
|
||||||
TRACE("unwound OK\n");
|
TRACE("unwound OK\n");
|
||||||
|
|
Loading…
Reference in New Issue