- Updates to our vectored exception handling:

- KiUserExceptionDispatcher: RtlDispatchException directly
- RtlDispatchException: Call vectored exception handlers before doing anything else
- Rename RtlpExecuteVectoredExceptionHandlers to RtlCallVectoredExceptionHandlers as this is the real name
- References: "New Vectored Exception Handling in Windows XP" by Matt Pietrek

svn path=/trunk/; revision=35812
This commit is contained in:
Stefan Ginsberg 2008-08-30 18:40:00 +00:00
parent 1f361c34ed
commit 48d386505a
5 changed files with 27 additions and 57 deletions

View file

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

View file

@ -183,43 +183,13 @@ _KiRaiseUserExceptionDispatcher@0:
.globl _KiUserExceptionDispatcher@8
_KiUserExceptionDispatcher@8:
/* 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.
*/
/* Clear direction flag */
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
@ -228,7 +198,6 @@ _KiUserExceptionDispatcher@8:
or al, al
jz RaiseException
ContinueExecution:
/* Pop off the records */
pop ebx
pop ecx

View file

@ -74,6 +74,13 @@ 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();

View file

@ -37,6 +37,13 @@ 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;

View file

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