From 26d5b4879290263c98820e13fd23f62bf1834261 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Tue, 30 Dec 2008 04:00:45 +0000 Subject: [PATCH] modified lib/pseh/framebased-gcchack.c modified lib/pseh/i386/framebased-gcchack.S Correctly handle exceptions thrown during unwinding Renamed some internal routines to more appropriate names svn path=/trunk/; revision=38460 --- reactos/lib/pseh/framebased-gcchack.c | 38 ++++++++++++++++------ reactos/lib/pseh/i386/framebased-gcchack.S | 10 +++--- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/reactos/lib/pseh/framebased-gcchack.c b/reactos/lib/pseh/framebased-gcchack.c index d69f7884f91..b33cc566720 100644 --- a/reactos/lib/pseh/framebased-gcchack.c +++ b/reactos/lib/pseh/framebased-gcchack.c @@ -40,7 +40,7 @@ extern DECLSPEC_NORETURN int __SEH2Handle(void *, void *, void *); extern int __cdecl __SEH2FrameHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); -extern int __cdecl __SEH2NestedHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); +extern int __cdecl __SEH2UnwindHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); FORCEINLINE _SEH2Registration_t * __cdecl _SEH2CurrentRegistration(void) @@ -134,8 +134,18 @@ void _SEH2Finally(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) } } +typedef struct __SEH2UnwindFrame +{ + _SEH2Registration_t SUF_Registration; + _SEH2Frame_t * SUF_Frame; + volatile _SEH2TryLevel_t * SUF_TargetTryLevel; +} +_SEH2UnwindFrame_t; + +static void _SEH2LocalUnwind(_SEH2Frame_t *, volatile _SEH2TryLevel_t *); + extern -int __cdecl _SEH2NestedHandler +int __cdecl _SEH2UnwindHandler ( struct _EXCEPTION_RECORD * ExceptionRecord, void * EstablisherFrame, @@ -144,25 +154,33 @@ int __cdecl _SEH2NestedHandler ) { if(ExceptionRecord->ExceptionFlags & (EXCEPTION_EXIT_UNWIND | EXCEPTION_UNWINDING)) - return ExceptionContinueSearch; + { + _SEH2UnwindFrame_t * unwindframe = CONTAINING_RECORD(EstablisherFrame, _SEH2UnwindFrame_t, SUF_Registration); + _SEH2LocalUnwind(unwindframe->SUF_Frame, unwindframe->SUF_TargetTryLevel); + *((void **)DispatcherContext) = EstablisherFrame; + return ExceptionCollidedUnwind; + } - *((void **)DispatcherContext) = EstablisherFrame; - return ExceptionCollidedUnwind; + return ExceptionContinueSearch; } static void _SEH2LocalUnwind(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * dsttrylevel) { volatile _SEH2TryLevel_t * trylevel; - _SEH2Registration_t nestedframe; + _SEH2UnwindFrame_t unwindframe; - nestedframe.SER_Handler = &__SEH2NestedHandler; - __SEH2EnterFrame(&nestedframe); + unwindframe.SUF_Frame = frame; + unwindframe.SUF_TargetTryLevel = dsttrylevel; + + unwindframe.SUF_Registration.SER_Handler = &__SEH2UnwindHandler; + __SEH2EnterFrame(&unwindframe.SUF_Registration); for(trylevel = frame->SF_TopTryLevel; trylevel && trylevel != dsttrylevel; trylevel = trylevel->ST_Next) + { + frame->SF_TopTryLevel = trylevel->ST_Next; _SEH2Finally(frame, trylevel); - - frame->SF_TopTryLevel = dsttrylevel; + } __SEH2LeaveFrame(); } diff --git a/reactos/lib/pseh/i386/framebased-gcchack.S b/reactos/lib/pseh/i386/framebased-gcchack.S index d60f6cf7ccb..f529b432e51 100644 --- a/reactos/lib/pseh/i386/framebased-gcchack.S +++ b/reactos/lib/pseh/i386/framebased-gcchack.S @@ -40,14 +40,14 @@ ___SEH2FrameHandler: jmp __SEH2FrameHandler .endfunc -.func __SEH2NestedHandler -.globl ___SEH2NestedHandler -___SEH2NestedHandler: +.func __SEH2UnwindHandler +.globl ___SEH2UnwindHandler +___SEH2UnwindHandler: -.extern __SEH2NestedHandler +.extern __SEH2UnwindHandler cld - jmp __SEH2NestedHandler + jmp __SEH2UnwindHandler .endfunc // EOF