Reverted r35812 because of unwanted triple fault bug.

See issue #3704,3706 for more details.

svn path=/trunk/; revision=35846
This commit is contained in:
Pierre Schweitzer 2008-08-31 21:58:44 +00:00
parent 481f0751b4
commit af64e75b22
5 changed files with 57 additions and 27 deletions

View file

@ -15,6 +15,10 @@
typedef NTSTATUS (NTAPI *USER_CALL)(PVOID Argument, ULONG ArgumentLength); typedef NTSTATUS (NTAPI *USER_CALL)(PVOID Argument, ULONG ArgumentLength);
EXCEPTION_DISPOSITION NTAPI
RtlpExecuteVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context);
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
/* /*
@ -28,16 +32,26 @@ KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord,
EXCEPTION_RECORD NestedExceptionRecord; EXCEPTION_RECORD NestedExceptionRecord;
NTSTATUS Status; NTSTATUS Status;
/* Dispatch the exception and check the result */ /* call the vectored exception handlers */
if (RtlDispatchException(ExceptionRecord, Context)) if(RtlpExecuteVectoredExceptionHandlers(ExceptionRecord,
Context) != ExceptionContinueExecution)
{ {
/* Continue executing */ goto ContinueExecution;
Status = NtContinue(Context, FALSE);
} }
else else
{ {
/* Raise an exception */ /* Dispatch the exception and check the result */
Status = NtRaiseException(ExceptionRecord, Context, FALSE); if(RtlDispatchException(ExceptionRecord, Context))
{
ContinueExecution:
/* Continue executing */
Status = NtContinue(Context, FALSE);
}
else
{
/* Raise an exception */
Status = NtRaiseException(ExceptionRecord, Context, FALSE);
}
} }
/* Setup the Exception record */ /* Setup the Exception record */

View file

@ -183,13 +183,43 @@ _KiRaiseUserExceptionDispatcher@0:
.globl _KiUserExceptionDispatcher@8 .globl _KiUserExceptionDispatcher@8
_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 cld
/* Save the Context and Exception Records */ /* Save the Context and Exception Records */
mov ecx, [esp+4] mov ecx, [esp+4]
mov ebx, [esp] 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 */ /* Dispatch the exception */
sub esp, 8 sub esp, 8
call _RtlDispatchException@8 call _RtlDispatchException@8
@ -198,6 +228,7 @@ _KiUserExceptionDispatcher@8:
or al, al or al, al
jz RaiseException jz RaiseException
ContinueExecution:
/* Pop off the records */ /* Pop off the records */
pop ebx pop ebx
pop ecx pop ecx

View file

@ -74,13 +74,6 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
ULONG_PTR StackLow, StackHigh; ULONG_PTR StackLow, StackHigh;
ULONG_PTR RegistrationFrameEnd; 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 */ /* Get the current stack limits and registration frame */
RtlpGetStackLimits(&StackLow, &StackHigh); RtlpGetStackLimits(&StackLow, &StackHigh);
RegistrationFrame = RtlpGetExceptionList(); RegistrationFrame = RtlpGetExceptionList();

View file

@ -37,13 +37,6 @@ VOID
NTAPI NTAPI
RtlpSetExceptionList(PEXCEPTION_REGISTRATION_RECORD NewExceptionList); RtlpSetExceptionList(PEXCEPTION_REGISTRATION_RECORD NewExceptionList);
BOOLEAN
NTAPI
RtlCallVectoredExceptionHandlers(
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context
);
typedef struct _DISPATCHER_CONTEXT typedef struct _DISPATCHER_CONTEXT
{ {
PEXCEPTION_REGISTRATION_RECORD RegistrationPointer; PEXCEPTION_REGISTRATION_RECORD RegistrationPointer;

View file

@ -28,10 +28,9 @@ typedef struct _RTL_VECTORED_EXCEPTION_HANDLER
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
BOOLEAN EXCEPTION_DISPOSITION NTAPI
NTAPI RtlpExecuteVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
RtlCallVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context)
IN PCONTEXT Context)
{ {
PLIST_ENTRY CurrentEntry; PLIST_ENTRY CurrentEntry;
PRTL_VECTORED_EXCEPTION_HANDLER veh; PRTL_VECTORED_EXCEPTION_HANDLER veh;
@ -56,7 +55,7 @@ RtlCallVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION) if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION)
{ {
return TRUE; return ExceptionContinueSearch;
} }
RtlEnterCriticalSection(&RtlpVectoredExceptionLock); RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
@ -64,7 +63,7 @@ RtlCallVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock); RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
} }
return FALSE; return ExceptionContinueExecution;
} }
VOID VOID