- Updates to our vectored exception handling:
authorStefan Ginsberg <stefanginsberg@gmail.com>
Sat, 30 Aug 2008 18:40:00 +0000 (18:40 +0000)
committerStefan Ginsberg <stefanginsberg@gmail.com>
Sat, 30 Aug 2008 18:40:00 +0000 (18:40 +0000)
- 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

reactos/dll/ntdll/dispatch/dispatch.c
reactos/dll/ntdll/dispatch/i386/dispatch.S
reactos/lib/rtl/i386/except.c
reactos/lib/rtl/rtlp.h
reactos/lib/rtl/vectoreh.c

index 6fd4f70..c6f749c 100644 (file)
 \r
 typedef NTSTATUS (NTAPI *USER_CALL)(PVOID Argument, ULONG ArgumentLength);\r
 \r
-EXCEPTION_DISPOSITION NTAPI\r
-RtlpExecuteVectoredExceptionHandlers(IN PEXCEPTION_RECORD  ExceptionRecord,\r
-                                     IN PCONTEXT  Context);\r
-\r
 /* FUNCTIONS ****************************************************************/\r
 \r
 /*\r
@@ -32,26 +28,16 @@ KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord,
     EXCEPTION_RECORD NestedExceptionRecord;\r
     NTSTATUS Status;\r
 \r
-    /* call the vectored exception handlers */\r
-    if(RtlpExecuteVectoredExceptionHandlers(ExceptionRecord,\r
-                                            Context) != ExceptionContinueExecution)\r
+    /* Dispatch the exception and check the result */\r
+    if (RtlDispatchException(ExceptionRecord, Context))\r
     {\r
-        goto ContinueExecution;\r
+        /* Continue executing */\r
+        Status = NtContinue(Context, FALSE);\r
     }\r
     else\r
     {\r
-        /* Dispatch the exception and check the result */\r
-        if(RtlDispatchException(ExceptionRecord, Context))\r
-        {\r
-ContinueExecution:\r
-            /* Continue executing */\r
-            Status = NtContinue(Context, FALSE);\r
-        }\r
-        else\r
-        {\r
-            /* Raise an exception */\r
-            Status = NtRaiseException(ExceptionRecord, Context, FALSE);\r
-        }\r
+        /* Raise an exception */\r
+        Status = NtRaiseException(ExceptionRecord, Context, FALSE);\r
     }\r
 \r
     /* Setup the Exception record */\r
index 526e5b8..00a21f4 100644 (file)
@@ -183,43 +183,13 @@ _KiRaiseUserExceptionDispatcher@0:
 .globl _KiUserExceptionDispatcher@8\r
 _KiUserExceptionDispatcher@8:\r
 \r
-    /* clear the direct flag \r
-     * text from bug 2279\r
-     * if it not clear it means that if an exception occurs while\r
-     * the direction flag is set (typically inside memmove), the \r
-     * exception handlers will be called with the direction flag still\r
-     * set.  The Windows x86-32 and x86-64 ABI requires that the \r
-     * direction flag be Calling memset() with a compile-time constant \r
-     * size on both GCC and MSVC will result in inlining a "rep stosd" \r
-     * instruction.  Because of the ABI, they will assume that the \r
-     * direction flag is clear and not emit a "cld" instruction. \r
-     * Using memset() in an exception handler therefore will \r
-     * corrupt memory if the exception occurred during a reverse copy \r
-     * such as a forward overlapping memmove().\r
-     *\r
-     * For reliability and ease of debugging, please add "cld" to the beginning of\r
-     * KiUserExceptionDispatcher.  Note that the same will be true of x86-64 whenever\r
-     * that happens.  This does not affect continuing execution; the CONTEXT of the\r
-     * exception has the direction flag set and will be restored upon NtContinue. \r
-     * KiUserApcDispatcher and KiUserCallbackDispatcher need to be evaluated for this\r
-     * issue.\r
-     */\r
-     \r
+    /* Clear direction flag */\r
     cld\r
 \r
     /* Save the Context and Exception Records */\r
     mov ecx, [esp+4]\r
     mov ebx, [esp]\r
 \r
-    /* Call the vectored exception handler */\r
-    push ecx\r
-    push ebx\r
-    call _RtlpExecuteVectoredExceptionHandlers@8\r
-\r
-    /* Check for success */\r
-    or al, al\r
-    jnz ContinueExecution\r
-\r
     /* Dispatch the exception */\r
     sub esp, 8\r
     call _RtlDispatchException@8\r
@@ -228,7 +198,6 @@ _KiUserExceptionDispatcher@8:
     or al, al\r
     jz RaiseException\r
 \r
-ContinueExecution:\r
     /* Pop off the records */\r
     pop ebx\r
     pop ecx\r
index dc56aed..087ab74 100644 (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();
index 845f625..4bfba09 100644 (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;
index d1a3913..52d6667 100644 (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