mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 12:40:33 +00:00
- Reapply 35812:
- RtlDispatchException: Call vectored exception handlers before doing anything else - KiUserExceptionDispatcher: Call RtlDispatchException directly as it now takes care of vectored handling - Rename RtlpExecuteVectoredExceptionHandlers to RtlCallVectoredExceptionHandlers, and fix return type - References: "New Vectored Exception Handling in Windows XP" by Matt Pietrek - New in this revision: Only call vectored handlers in user mode, as there is no such thing in kernel mode svn path=/trunk/; revision=37137
This commit is contained in:
parent
ed9780429d
commit
ae24c33a4f
5 changed files with 32 additions and 57 deletions
|
@ -15,10 +15,6 @@
|
||||||
|
|
||||||
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 ****************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -32,18 +28,9 @@ KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
EXCEPTION_RECORD NestedExceptionRecord;
|
EXCEPTION_RECORD NestedExceptionRecord;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* call the vectored exception handlers */
|
|
||||||
if(RtlpExecuteVectoredExceptionHandlers(ExceptionRecord,
|
|
||||||
Context) != ExceptionContinueExecution)
|
|
||||||
{
|
|
||||||
goto ContinueExecution;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Dispatch the exception and check the result */
|
/* Dispatch the exception and check the result */
|
||||||
if(RtlDispatchException(ExceptionRecord, Context))
|
if (RtlDispatchException(ExceptionRecord, Context))
|
||||||
{
|
{
|
||||||
ContinueExecution:
|
|
||||||
/* Continue executing */
|
/* Continue executing */
|
||||||
Status = NtContinue(Context, FALSE);
|
Status = NtContinue(Context, FALSE);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +39,6 @@ ContinueExecution:
|
||||||
/* Raise an exception */
|
/* Raise an exception */
|
||||||
Status = NtRaiseException(ExceptionRecord, Context, FALSE);
|
Status = NtRaiseException(ExceptionRecord, Context, FALSE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup the Exception record */
|
/* Setup the Exception record */
|
||||||
NestedExceptionRecord.ExceptionCode = Status;
|
NestedExceptionRecord.ExceptionCode = Status;
|
||||||
|
|
|
@ -183,52 +183,22 @@ _KiRaiseUserExceptionDispatcher@0:
|
||||||
.globl _KiUserExceptionDispatcher@8
|
.globl _KiUserExceptionDispatcher@8
|
||||||
_KiUserExceptionDispatcher@8:
|
_KiUserExceptionDispatcher@8:
|
||||||
|
|
||||||
/* clear the direct flag
|
/* Clear direction 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 */
|
/* Dispatch the exception */
|
||||||
push ecx
|
push ecx
|
||||||
push ebx
|
push ebx
|
||||||
call _RtlpExecuteVectoredExceptionHandlers@8
|
|
||||||
|
|
||||||
/* Check for success */
|
|
||||||
or al, al
|
|
||||||
jnz ContinueExecution
|
|
||||||
|
|
||||||
/* Dispatch the exception */
|
|
||||||
sub esp, 8
|
|
||||||
call _RtlDispatchException@8
|
call _RtlDispatchException@8
|
||||||
|
|
||||||
/* Check for success */
|
/* Check for success */
|
||||||
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
|
||||||
|
|
|
@ -74,6 +74,17 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||||
ULONG_PTR StackLow, StackHigh;
|
ULONG_PTR StackLow, StackHigh;
|
||||||
ULONG_PTR RegistrationFrameEnd;
|
ULONG_PTR RegistrationFrameEnd;
|
||||||
|
|
||||||
|
/* Perform vectored exception handling if we are in user mode */
|
||||||
|
if (RtlpGetMode() != KernelMode)
|
||||||
|
{
|
||||||
|
/* 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();
|
||||||
|
|
|
@ -37,6 +37,13 @@ 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;
|
||||||
|
|
|
@ -28,8 +28,9 @@ typedef struct _RTL_VECTORED_EXCEPTION_HANDLER
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION NTAPI
|
BOOLEAN
|
||||||
RtlpExecuteVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
|
NTAPI
|
||||||
|
RtlCallVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||||
IN PCONTEXT Context)
|
IN PCONTEXT Context)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
@ -55,7 +56,7 @@ RtlpExecuteVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||||
|
|
||||||
if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION)
|
if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION)
|
||||||
{
|
{
|
||||||
return ExceptionContinueSearch;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
||||||
|
@ -63,7 +64,7 @@ RtlpExecuteVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||||
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ExceptionContinueExecution;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
Loading…
Reference in a new issue