KdDebuggerEnable -> KdDebuggerEnabled
[reactos.git] / reactos / ntoskrnl / ke / catch.c
index b4235c7..11e1e41 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ReactOS kernel
- *  Copyright (C) 2000 David Welch <welch@cwcom.net>
+ *  Copyright (C) 2000  ReactOS Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: catch.c,v 1.9 2001/02/21 18:17:57 ekohl Exp $
+/* $Id: catch.c,v 1.27 2002/12/11 04:39:20 robd Exp $
  *
- * COPYRIGHT:            See COPYING in the top level directory
  * PROJECT:              ReactOS kernel
  * FILE:                 ntoskrnl/ke/catch.c
  * PURPOSE:              Exception handling
  * PROGRAMMER:           David Welch (welch@mcmail.com)
+ *                       Casper S. Hornstrup (chorns@users.sourceforge.net)
  */
 
 /* INCLUDES *****************************************************************/
 
 #include <ddk/ntddk.h>
+#include <roscfg.h>
+#include <internal/ke.h>
+#include <internal/ldr.h>
+#include <internal/ps.h>
+#include <internal/kd.h>
 
+#define NDEBUG
 #include <internal/debug.h>
 
 /* FUNCTIONS ****************************************************************/
 
+ULONG
+RtlpDispatchException(IN PEXCEPTION_RECORD  ExceptionRecord,
+       IN PCONTEXT  Context);
+
+VOID 
+KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
+                   PCONTEXT Context,
+                   PKTRAP_FRAME Tf,
+                   KPROCESSOR_MODE PreviousMode,
+                   BOOLEAN SearchFrames)
+{
+  EXCEPTION_DISPOSITION Value;
+  CONTEXT TContext;
+
+  DPRINT("KiDispatchException() called\n");
+
+  /* PCR->KeExceptionDispatchCount++; */
+
+  if (Context == NULL)
+    {
+      TContext.ContextFlags = CONTEXT_FULL;
+      if (PreviousMode == UserMode)
+       {
+         TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER;
+       }
+  
+      KeTrapFrameToContext(Tf, &TContext);
+
+      Context = &TContext;
+    }
+
+#if 0
+  if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) 
+    {
+      Context->Eip--;
+    }
+#endif
+  if (PreviousMode == UserMode)
+    {
+      if (SearchFrames)
+       {
+         PULONG Stack;
+         ULONG CDest;
+
+         /* FIXME: Give the kernel debugger a chance */
+
+         /* FIXME: Forward exception to user mode debugger */
+
+         /* FIXME: Check user mode stack for enough space */
+
+         
+         /*
+          * Let usermode try and handle the exception
+          */
+         Tf->Esp = Tf->Esp - 
+           (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT));
+         Stack = (PULONG)Tf->Esp;
+         CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4);
+         /* Return address */
+         Stack[0] = 0;    
+         /* Pointer to EXCEPTION_RECORD structure */
+         Stack[1] = (ULONG)&Stack[3];   
+         /* Pointer to CONTEXT structure */
+         Stack[2] = (ULONG)&Stack[CDest];     
+         memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
+         memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
+
+         Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
+         return;
+       }
+      
+      /* FIXME: Forward the exception to the debugger */
+
+      /* FIXME: Forward the exception to the process exception port */
+
+      /* Terminate the offending thread */
+      ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
+
+      /* If that fails then bugcheck */
+      DbgPrint("Could not terminate thread\n");
+      KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
+    }
+  else
+    {
+      KD_CONTINUE_TYPE Action = kdContinue;
+
+      /* PreviousMode == KernelMode */
+      
+      if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB)
+       {
+         Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
+       }
+#ifdef KDBG
+      else if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_KDB)
+       {
+         Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf);
+       }
+#endif /* KDBG */
+      if (Action != kdHandleException)
+       {
+         Value = RtlpDispatchException (ExceptionRecord, Context);
+         
+         DPRINT("RtlpDispatchException() returned with 0x%X\n", Value);
+         /* 
+          * If RtlpDispatchException() does not handle the exception then 
+          * bugcheck 
+          */
+         if (Value != ExceptionContinueExecution)
+           {
+             KeBugCheck (KMODE_EXCEPTION_NOT_HANDLED);       
+           }
+       }
+      else
+        {
+          KeContextToTrapFrame (Context, KeGetCurrentThread()->TrapFrame);
+        }
+    }
+}
+
 VOID STDCALL
 ExRaiseAccessViolation (VOID)
 {
@@ -46,37 +171,39 @@ ExRaiseDatatypeMisalignment (VOID)
 }
 
 VOID STDCALL
-ExRaiseStatus (IN      NTSTATUS        Status)
+ExRaiseStatus (IN NTSTATUS Status)
 {
-  DbgPrint("ExRaiseStatus(%x)\n",Status);
-  for(;;);
-}
+  EXCEPTION_RECORD ExceptionRecord;
 
+  DPRINT("ExRaiseStatus(%x)\n", Status);
 
+  ExceptionRecord.ExceptionRecord = NULL;
+  ExceptionRecord.NumberParameters = 0;
+  ExceptionRecord.ExceptionCode = Status;
+  ExceptionRecord.ExceptionFlags = 0;
 
-NTSTATUS STDCALL
-NtRaiseException (IN   PEXCEPTION_RECORD       ExceptionRecord,
-                 IN    PCONTEXT                Context,
-                 IN    BOOL                    IsDebugger      OPTIONAL)
-{
-  UNIMPLEMENTED;
+  RtlRaiseException(&ExceptionRecord);
 }
 
 
-VOID STDCALL
-RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
+NTSTATUS STDCALL
+NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord,
+                 IN PCONTEXT Context,
+                 IN BOOLEAN SearchFrames)
 {
-
+  KiDispatchException(ExceptionRecord,
+                     Context,
+                     PsGetCurrentThread()->Tcb.TrapFrame,
+                     ExGetPreviousMode(),
+                     SearchFrames);
+  return(STATUS_SUCCESS);
 }
 
 
 VOID STDCALL
-RtlUnwind(ULONG Unknown1,
-         ULONG Unknown2,
-         ULONG Unknown3,
-         ULONG Unknown4)
+RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
 {
-
+  ZwRaiseException(ExceptionRecord, NULL, TRUE);
 }
 
 /* EOF */