Merge trunk head (r43756)
[reactos.git] / reactos / ntoskrnl / kd / kdmain.c
index d27472c..4a17c74 100644 (file)
@@ -2,25 +2,25 @@
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Kernel
  * FILE:            ntoskrnl/kd/kdinit.c
- * PURPOSE:         Kernel Debugger Initializtion
+ * PURPOSE:         Kernel Debugger Initialization
  *
  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
  */
 
 #include <ntoskrnl.h>
 #define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
 
 /* VARIABLES ***************************************************************/
 
 BOOLEAN KdDebuggerEnabled = FALSE;
 BOOLEAN KdEnteredDebugger = FALSE;
 BOOLEAN KdDebuggerNotPresent = TRUE;
-BOOLEAN KiEnableTimerWatchdog = FALSE;
 BOOLEAN KdBreakAfterSymbolLoad = FALSE;
-BOOLEAN KdpBreakPending;
+BOOLEAN KdpBreakPending = FALSE;
 BOOLEAN KdPitchDebugger = TRUE;
-VOID STDCALL PspDumpThreads(BOOLEAN SystemThreads);
+BOOLEAN KdIgnoreUmExceptions = FALSE;
+VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
 
 typedef struct
 {
@@ -36,7 +36,7 @@ ULONG Kd_DEFAULT_MASK = 1 << DPFLTR_ERROR_LEVEL;
 /* PRIVATE FUNCTIONS *********************************************************/
 
 ULONG
-STDCALL
+NTAPI
 KdpServiceDispatcher(ULONG Service,
                      PVOID Buffer1,
                      ULONG Buffer1Length)
@@ -49,29 +49,13 @@ KdpServiceDispatcher(ULONG Service,
             Result = KdpPrintString(Buffer1, Buffer1Length);
             break;
 
-#ifdef DBG
-        case TAG('R', 'o', 's', ' '): /* ROS-INTERNAL */
+#if DBG
+        case ' soR': /* ROS-INTERNAL */
         {
-            switch ((ULONG)Buffer1)
+            switch ((ULONG_PTR)Buffer1)
             {
-                case DumpNonPagedPool:
-                    MiDebugDumpNonPagedPool(FALSE);
-                    break;
-
                 case ManualBugCheck:
-                    KEBUGCHECK(MANUALLY_INITIATED_CRASH);
-                    break;
-
-                case DumpNonPagedPoolStats:
-                    MiDebugDumpNonPagedPoolStats(FALSE);
-                    break;
-
-                case DumpNewNonPagedPool:
-                    MiDebugDumpNonPagedPool(TRUE);
-                    break;
-
-                case DumpNewNonPagedPoolStats:
-                    MiDebugDumpNonPagedPoolStats(TRUE);
+                    KeBugCheck(MANUALLY_INITIATED_CRASH);
                     break;
 
                 case DumpAllThreads:
@@ -85,10 +69,22 @@ KdpServiceDispatcher(ULONG Service,
                 case EnterDebugger:
                     DbgBreakPoint();
                     break;
+                    
+                case ThatsWhatSheSaid:
+                    MmDumpPfnDatabase();
+                    break;
 
                 default:
                     break;
             }
+            break;
+        }
+
+        /* Special  case for stack frame dumps */
+        case 'DsoR':
+        {
+            KeRosDumpStackFrames((PULONG)Buffer1, Buffer1Length);
+            break;
         }
 #endif
         default:
@@ -108,11 +104,8 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
                           IN KPROCESSOR_MODE PreviousMode,
                           IN BOOLEAN SecondChance)
 {
-    KD_CONTINUE_TYPE Return;
+    KD_CONTINUE_TYPE Return = kdHandleException;
     ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0];
-#ifdef _M_IX86
-    ULONG EipOld;
-#endif
 
     /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */
     if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
@@ -120,7 +113,8 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
         ((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) ||
          (ExceptionCommand == BREAKPOINT_UNLOAD_SYMBOLS) ||
          (ExceptionCommand == BREAKPOINT_COMMAND_STRING) ||
-         (ExceptionCommand == BREAKPOINT_PRINT)))
+         (ExceptionCommand == BREAKPOINT_PRINT) ||
+         (ExceptionCommand == BREAKPOINT_PROMPT)))
     {
         /* Check if this is a debug print */
         if (ExceptionCommand == BREAKPOINT_PRINT)
@@ -129,54 +123,86 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
             KdpServiceDispatcher(BREAKPOINT_PRINT,
                                  (PVOID)ExceptionRecord->ExceptionInformation[1],
                                  ExceptionRecord->ExceptionInformation[2]);
+
+            /* Return success */
+            KeSetContextReturnRegister(Context, STATUS_SUCCESS);
         }
+#ifdef KDBG
         else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS)
         {
+            PLDR_DATA_TABLE_ENTRY LdrEntry;
+
             /* Load symbols. Currently implemented only for KDBG! */
-            KDB_SYMBOLFILE_HOOK((PANSI_STRING)ExceptionRecord->ExceptionInformation[1],
-                (PKD_SYMBOLS_INFO)ExceptionRecord->ExceptionInformation[2]);
+            if(KdbpSymFindModule(((PKD_SYMBOLS_INFO)ExceptionRecord->ExceptionInformation[2])->BaseOfDll, NULL, -1, &LdrEntry))
+                KdbSymProcessSymbols(LdrEntry);
+        }
+        else if (ExceptionCommand == BREAKPOINT_PROMPT)
+        {
+            ULONG ReturnValue;
+            LPSTR OutString;
+            USHORT OutStringLength;
+
+            /* Get the response string  and length */
+            OutString = (LPSTR)Context->Ebx;
+            OutStringLength = (USHORT)Context->Edi;
+
+            /* Call KDBG */
+            ReturnValue = KdpPrompt((LPSTR)ExceptionRecord->
+                                    ExceptionInformation[1],
+                                    (USHORT)ExceptionRecord->
+                                    ExceptionInformation[2],
+                                    OutString,
+                                    OutStringLength);
+
+            /* Return the number of characters that we received */
+            Context->Eax = ReturnValue;
         }
-
-        /* This we can handle: simply bump EIP */
-#ifdef _M_IX86
-        Context->Eip++;
 #endif
+
+        /* This we can handle: simply bump the Program Counter */
+        KeSetContextPc(Context, KeGetContextPc(Context) + KD_BREAKPOINT_SIZE);
         return TRUE;
     }
 
-    /* Get out of here if the Debugger isn't connected */
-    if (KdDebuggerNotPresent) return FALSE;
+#ifdef KDBG
+    /* Check if this is an assertion failure */
+    if (ExceptionRecord->ExceptionCode == STATUS_ASSERTION_FAILURE)
+    {
+        /* Warn about it */
+        DbgPrint("\n!!! Assertion Failure at Address 0x%p !!!\n\n",
+                 (PVOID)Context->Eip);
 
-    /* Save old EIP value */
-#ifdef _M_IX86
-    EipOld = Context->Eip;
+        /* Bump EIP to the instruction following the int 2C and return */
+        Context->Eip += 2;
+        return TRUE;
+    }
 #endif
 
+    /* Get out of here if the Debugger isn't connected */
+    if (KdDebuggerNotPresent) return FALSE;
+
+#ifdef KDBG
     /* Call KDBG if available */
     Return = KdbEnterDebuggerException(ExceptionRecord,
                                        PreviousMode,
                                        Context,
                                        TrapFrame,
                                        !SecondChance);
-
-    /* Bump EIP over int 3 if debugger did not already change it */
-    if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
+#else /* not KDBG */
+    if (WrapperInitRoutine)
     {
-#ifdef KDBG
-        if (Context->Eip == EipOld)
-            Context->Eip++;
-#else
-        /* We simulate the original behaviour when KDBG is turned off.
-           Return var is set to kdHandleException, thus we always return FALSE */
-#ifdef _M_IX86
-        Context->Eip = EipOld;
-#endif
-#endif
+        /* Call GDB */
+        Return = WrapperTable.KdpExceptionRoutine(ExceptionRecord,
+                                                  Context,
+                                                  TrapFrame);
     }
+#endif /* not KDBG */
 
-    /* Convert return to BOOLEAN */
-    if (Return == kdContinue) return TRUE;
-    return FALSE;
+    /* Debugger didn't handle it, please handle! */
+    if (Return == kdHandleException) return FALSE;
+
+    /* Debugger handled it */
+    return TRUE;
 }
 
 BOOLEAN
@@ -203,18 +229,43 @@ KdpCallGdb(IN PKTRAP_FRAME TrapFrame,
                                                   TrapFrame);
     }
 
-    /* Convert return to BOOLEAN */
-    if (Return == kdContinue) return TRUE;
+    /* Debugger didn't handle it, please handle! */
+    if (Return == kdHandleException) return FALSE;
+
+    /* Debugger handled it */
+    return TRUE;
+}
+
+BOOLEAN
+NTAPI
+KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord,
+                IN PCONTEXT Context,
+                IN KPROCESSOR_MODE PreviousMode)
+{
+    /* KDBG has its own mechanism for ignoring user mode exceptions */
     return FALSE;
 }
 
 /* PUBLIC FUNCTIONS *********************************************************/
 
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+KdRefreshDebuggerNotPresent(VOID)
+{
+    UNIMPLEMENTED;
+
+    /* Just return whatever was set previously -- FIXME! */
+    return KdDebuggerNotPresent;
+}
+
 /*
  * @implemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 KdDisableDebugger(VOID)
 {
     KIRQL OldIrql;
@@ -238,7 +289,7 @@ KdDisableDebugger(VOID)
  * @implemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 KdEnableDebugger(VOID)
 {
     KIRQL OldIrql;
@@ -262,7 +313,7 @@ KdEnableDebugger(VOID)
  * @implemented
  */
 BOOLEAN
-STDCALL
+NTAPI
 KdPollBreakIn(VOID)
 {
     return KdpBreakPending;
@@ -272,7 +323,7 @@ KdPollBreakIn(VOID)
  * @unimplemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 KdPowerTransition(ULONG PowerState)
 {
     UNIMPLEMENTED;
@@ -317,13 +368,13 @@ NtQueryDebugFilterState(IN ULONG ComponentId,
             if (ComponentId == KdComponentTable[i].ComponentId)
             {
                 /* Check if mask are matching */
-                return (Level & KdComponentTable[i].Level) != 0;
+                return (Level & KdComponentTable[i].Level) ? TRUE : FALSE;
             }
         }
     }
 
     /* Entry not found in the table, use default mask */
-    return (Level & Kd_DEFAULT_MASK) != 0;
+    return (Level & Kd_DEFAULT_MASK) ? TRUE : FALSE;
 }
 
 NTSTATUS
@@ -337,6 +388,7 @@ NtSetDebugFilterState(IN ULONG ComponentId,
     /* Convert Level to mask if it isn't already one */
     if (Level < 32)
         Level = 1 << Level;
+    Level &= ~DPFLTR_MASK;
 
     /* Check if it is the default component */
     if (ComponentId == DPFLTR_DEFAULT_ID)