From af64e75b22ffb2060f39520e263b1c4c3c7e705f Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 31 Aug 2008 21:58:44 +0000 Subject: [PATCH] Reverted r35812 because of unwanted triple fault bug. See issue #3704,3706 for more details. svn path=/trunk/; revision=35846 --- reactos/dll/ntdll/dispatch/dispatch.c | 26 +++++++++++++---- reactos/dll/ntdll/dispatch/i386/dispatch.S | 33 +++++++++++++++++++++- reactos/lib/rtl/i386/except.c | 7 ----- reactos/lib/rtl/rtlp.h | 7 ----- reactos/lib/rtl/vectoreh.c | 11 ++++---- 5 files changed, 57 insertions(+), 27 deletions(-) diff --git a/reactos/dll/ntdll/dispatch/dispatch.c b/reactos/dll/ntdll/dispatch/dispatch.c index c6f749c70bd..6fd4f70024f 100644 --- a/reactos/dll/ntdll/dispatch/dispatch.c +++ b/reactos/dll/ntdll/dispatch/dispatch.c @@ -15,6 +15,10 @@ typedef NTSTATUS (NTAPI *USER_CALL)(PVOID Argument, ULONG ArgumentLength); +EXCEPTION_DISPOSITION NTAPI +RtlpExecuteVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context); + /* FUNCTIONS ****************************************************************/ /* @@ -28,16 +32,26 @@ KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord, EXCEPTION_RECORD NestedExceptionRecord; NTSTATUS Status; - /* Dispatch the exception and check the result */ - if (RtlDispatchException(ExceptionRecord, Context)) + /* call the vectored exception handlers */ + if(RtlpExecuteVectoredExceptionHandlers(ExceptionRecord, + Context) != ExceptionContinueExecution) { - /* Continue executing */ - Status = NtContinue(Context, FALSE); + goto ContinueExecution; } else { - /* Raise an exception */ - Status = NtRaiseException(ExceptionRecord, Context, FALSE); + /* Dispatch the exception and check the result */ + if(RtlDispatchException(ExceptionRecord, Context)) + { +ContinueExecution: + /* Continue executing */ + Status = NtContinue(Context, FALSE); + } + else + { + /* Raise an exception */ + Status = NtRaiseException(ExceptionRecord, Context, FALSE); + } } /* Setup the Exception record */ diff --git a/reactos/dll/ntdll/dispatch/i386/dispatch.S b/reactos/dll/ntdll/dispatch/i386/dispatch.S index 00a21f47b82..526e5b8f189 100644 --- a/reactos/dll/ntdll/dispatch/i386/dispatch.S +++ b/reactos/dll/ntdll/dispatch/i386/dispatch.S @@ -183,13 +183,43 @@ _KiRaiseUserExceptionDispatcher@0: .globl _KiUserExceptionDispatcher@8 _KiUserExceptionDispatcher@8: - /* Clear direction flag */ + /* clear the direct flag + * text from bug 2279 + * if it not clear it means that if an exception occurs while + * the direction flag is set (typically inside memmove), the + * exception handlers will be called with the direction flag still + * set. The Windows x86-32 and x86-64 ABI requires that the + * direction flag be Calling memset() with a compile-time constant + * size on both GCC and MSVC will result in inlining a "rep stosd" + * instruction. Because of the ABI, they will assume that the + * direction flag is clear and not emit a "cld" instruction. + * Using memset() in an exception handler therefore will + * corrupt memory if the exception occurred during a reverse copy + * such as a forward overlapping memmove(). + * + * For reliability and ease of debugging, please add "cld" to the beginning of + * KiUserExceptionDispatcher. Note that the same will be true of x86-64 whenever + * that happens. This does not affect continuing execution; the CONTEXT of the + * exception has the direction flag set and will be restored upon NtContinue. + * KiUserApcDispatcher and KiUserCallbackDispatcher need to be evaluated for this + * issue. + */ + cld /* Save the Context and Exception Records */ mov ecx, [esp+4] mov ebx, [esp] + /* Call the vectored exception handler */ + push ecx + push ebx + call _RtlpExecuteVectoredExceptionHandlers@8 + + /* Check for success */ + or al, al + jnz ContinueExecution + /* Dispatch the exception */ sub esp, 8 call _RtlDispatchException@8 @@ -198,6 +228,7 @@ _KiUserExceptionDispatcher@8: or al, al jz RaiseException +ContinueExecution: /* Pop off the records */ pop ebx pop ecx diff --git a/reactos/lib/rtl/i386/except.c b/reactos/lib/rtl/i386/except.c index 087ab74fcb1..dc56aed3ec0 100644 --- a/reactos/lib/rtl/i386/except.c +++ b/reactos/lib/rtl/i386/except.c @@ -74,13 +74,6 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, ULONG_PTR StackLow, StackHigh; ULONG_PTR RegistrationFrameEnd; - /* Call any registered vectored handlers */ - if (RtlCallVectoredExceptionHandlers(ExceptionRecord, Context)) - { - /* Exception handled, continue execution */ - return TRUE; - } - /* Get the current stack limits and registration frame */ RtlpGetStackLimits(&StackLow, &StackHigh); RegistrationFrame = RtlpGetExceptionList(); diff --git a/reactos/lib/rtl/rtlp.h b/reactos/lib/rtl/rtlp.h index 4bfba098a83..845f625cbee 100644 --- a/reactos/lib/rtl/rtlp.h +++ b/reactos/lib/rtl/rtlp.h @@ -37,13 +37,6 @@ VOID NTAPI RtlpSetExceptionList(PEXCEPTION_REGISTRATION_RECORD NewExceptionList); -BOOLEAN -NTAPI -RtlCallVectoredExceptionHandlers( - IN PEXCEPTION_RECORD ExceptionRecord, - IN PCONTEXT Context -); - typedef struct _DISPATCHER_CONTEXT { PEXCEPTION_REGISTRATION_RECORD RegistrationPointer; diff --git a/reactos/lib/rtl/vectoreh.c b/reactos/lib/rtl/vectoreh.c index 52d6667cce6..d1a39138622 100644 --- a/reactos/lib/rtl/vectoreh.c +++ b/reactos/lib/rtl/vectoreh.c @@ -28,10 +28,9 @@ typedef struct _RTL_VECTORED_EXCEPTION_HANDLER /* FUNCTIONS ***************************************************************/ -BOOLEAN -NTAPI -RtlCallVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord, - IN PCONTEXT Context) +EXCEPTION_DISPOSITION NTAPI +RtlpExecuteVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context) { PLIST_ENTRY CurrentEntry; PRTL_VECTORED_EXCEPTION_HANDLER veh; @@ -56,7 +55,7 @@ RtlCallVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord, if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION) { - return TRUE; + return ExceptionContinueSearch; } RtlEnterCriticalSection(&RtlpVectoredExceptionLock); @@ -64,7 +63,7 @@ RtlCallVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord, RtlLeaveCriticalSection(&RtlpVectoredExceptionLock); } - return FALSE; + return ExceptionContinueExecution; } VOID