[STORPORT] Fix x64 build
[reactos.git] / ntoskrnl / kdbg / kdb.c
index 9bfd5ec..f3e82a0 100644 (file)
@@ -38,6 +38,7 @@ static PKDB_BREAKPOINT KdbSwBreakPoints[KDB_MAXIMUM_SW_BREAKPOINT_COUNT]; /* Ena
 static PKDB_BREAKPOINT KdbHwBreakPoints[KDB_MAXIMUM_HW_BREAKPOINT_COUNT]; /* Enabled hardware breakpoints, orderless */
 static PKDB_BREAKPOINT KdbBreakPointToReenable = NULL; /* Set to a breakpoint struct when single stepping after
                                                           a software breakpoint was hit, to reenable it */
+static BOOLEAN KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep;
 LONG KdbLastBreakPointNr = -1;  /* Index of the breakpoint which cause KDB to be entered */
 ULONG KdbNumSingleSteps = 0; /* How many single steps to do */
 BOOLEAN KdbSingleStepOver = FALSE; /* Whether to step over calls/reps. */
@@ -57,26 +58,27 @@ extern BOOLEAN KdbpBugCheckRequested;
 static KDB_ENTER_CONDITION KdbEnterConditions[][2] =
 {
     /* First chance       Last chance */
-    { KdbDoNotEnter,      KdbEnterFromKmode },   /* Zero devide */
-    { KdbEnterFromKmode,  KdbDoNotEnter },       /* Debug trap */
-    { KdbDoNotEnter,      KdbEnterAlways },      /* NMI */
-    { KdbEnterFromKmode,  KdbDoNotEnter },       /* INT3 */
-    { KdbDoNotEnter,      KdbEnterFromKmode },   /* Overflow */
-    { KdbDoNotEnter,      KdbEnterFromKmode },
-    { KdbDoNotEnter,      KdbEnterFromKmode },   /* Invalid opcode */
-    { KdbDoNotEnter,      KdbEnterFromKmode },   /* No math coprocessor fault */
-    { KdbEnterAlways,     KdbEnterAlways },
-    { KdbEnterAlways,     KdbEnterAlways },
-    { KdbDoNotEnter,      KdbEnterFromKmode },
-    { KdbDoNotEnter,      KdbEnterFromKmode },
-    { KdbDoNotEnter,      KdbEnterFromKmode },   /* Stack fault */
-    { KdbDoNotEnter,      KdbEnterFromKmode },   /* General protection fault */
-    { KdbDoNotEnter,      KdbEnterFromKmode },   /* Page fault */
-    { KdbEnterAlways,     KdbEnterAlways },      /* Reserved (15) */
-    { KdbDoNotEnter,      KdbEnterFromKmode },   /* FPU fault */
-    { KdbDoNotEnter,      KdbEnterFromKmode },
-    { KdbDoNotEnter,      KdbEnterFromKmode },
-    { KdbDoNotEnter,      KdbEnterFromKmode },   /* SIMD fault */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 0: Zero divide */
+    { KdbEnterFromKmode,  KdbDoNotEnter },       /* 1: Debug trap */
+    { KdbDoNotEnter,      KdbEnterAlways },      /* 2: NMI */
+    { KdbEnterFromKmode,  KdbDoNotEnter },       /* 3: INT3 */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 4: Overflow */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 5: BOUND range exceeded */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 6: Invalid opcode */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 7: No math coprocessor fault */
+    { KdbEnterAlways,     KdbEnterAlways },      /* 8: Double Fault */
+    { KdbEnterAlways,     KdbEnterAlways },      /* 9: Unknown(9) */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 10: Invalid TSS */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 11: Segment Not Present */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 12: Stack fault */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 13: General protection fault */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 14: Page fault */
+    { KdbEnterAlways,     KdbEnterAlways },      /* 15: Reserved (15) */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 16: FPU fault */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 17: Alignment Check */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 18: Machine Check */
+    { KdbDoNotEnter,      KdbEnterFromKmode },   /* 19: SIMD fault */
+    { KdbEnterFromKmode,  KdbDoNotEnter },       /* 20: Assertion failure */
     { KdbDoNotEnter,      KdbEnterFromKmode }    /* Last entry: used for unknown exceptions */
 };
 
@@ -102,7 +104,8 @@ static const CHAR *ExceptionNrToString[] =
     "Math Fault",
     "Alignment Check",
     "Machine Check",
-    "SIMD Fault"
+    "SIMD Fault",
+    "Assertion Failure"
 };
 
 ULONG
@@ -1234,7 +1237,7 @@ KdbpCallMainLoop(VOID)
  * Disables interrupts, releases display ownership, ...
  */
 static VOID
-KdbpInternalEnter()
+KdbpInternalEnter(VOID)
 {
     PETHREAD Thread;
     PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
@@ -1250,8 +1253,8 @@ KdbpInternalEnter()
         InbvAcquireDisplayOwnership();
         InbvResetDisplay();
 
-        /* Display blue screen */
-        InbvSolidColorFill(0, 0, 639, 479, 6);
+        /* Display debugger prompt */
+        InbvSolidColorFill(0, 0, 639, 479, 0);
         InbvSetTextColor(15);
         InbvInstallDisplayStringFilter(NULL);
         InbvEnableDisplayString(TRUE);
@@ -1320,6 +1323,9 @@ KdbpGetExceptionNumberFromStatus(
         case STATUS_FLOAT_MULTIPLE_TRAPS:
             Ret = 18;
             break;
+        case STATUS_ASSERTION_FAILURE:
+            Ret = 20;
+            break;
 
         default:
             Ret = RTL_NUMBER_OF(KdbEnterConditions) - 1;
@@ -1366,8 +1372,12 @@ KdbEnterDebuggerException(
     KdbCurrentProcess = PsGetCurrentProcess();
 
     /* Set continue type to kdContinue for single steps and breakpoints */
-    if (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT)
+    if (ExceptionCode == STATUS_SINGLE_STEP ||
+        ExceptionCode == STATUS_BREAKPOINT ||
+        ExceptionCode == STATUS_ASSERTION_FAILURE)
+    {
         ContinueType = kdContinue;
+    }
 
     /* Check if we should handle the exception. */
     /* FIXME - won't get all exceptions here :( */
@@ -1398,6 +1408,15 @@ KdbEnterDebuggerException(
                 KdbpPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
                 KeBugCheck(0); // FIXME: Proper bugcode!
             }
+
+            /* Also since we are past the int3 now, decrement EIP in the
+               TrapFrame. This is only needed because KDBG insists on working
+               with the TrapFrame instead of with the Context, as it is supposed
+               to do. The context has already EIP point to the int3, since
+               KiDispatchException accounts for that. Whatever we do here with
+               the TrapFrame does not matter anyway, since KiDispatchException
+               will overwrite it with the values from the Context! */
+            TrapFrame->Eip--;
         }
 
         if ((BreakPoint->Type == KdbBreakPointHardware) &&
@@ -1419,8 +1438,6 @@ KdbEnterDebuggerException(
             /* Delete the temporary breakpoint which was used to step over or into the instruction. */
             KdbpDeleteBreakPoint(-1, BreakPoint);
 
-            TrapFrame->Eip--;
-
             if (--KdbNumSingleSteps > 0)
             {
                 if ((KdbSingleStepOver && !KdbpStepOverInstruction(TrapFrame->Eip)) ||
@@ -1472,12 +1489,12 @@ KdbEnterDebuggerException(
 
         if (BreakPoint->Type == KdbBreakPointSoftware)
         {
-            KdbpPrint("Entered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
+            KdbpPrint("\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
                       KdbLastBreakPointNr, TrapFrame->SegCs & 0xffff, TrapFrame->Eip);
         }
         else if (BreakPoint->Type == KdbBreakPointHardware)
         {
-            KdbpPrint("Entered debugger on breakpoint #%d: %s 0x%08x\n",
+            KdbpPrint("\nEntered debugger on breakpoint #%d: %s 0x%08x\n",
                       KdbLastBreakPointNr,
                      (BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
                      ((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
@@ -1511,9 +1528,15 @@ KdbEnterDebuggerException(
             if (KdbNumSingleSteps == 0)
                 Context->EFlags &= ~EFLAGS_TF;
 
-            goto continue_execution; /* return */
+            if (!KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep)
+            {
+                goto continue_execution; /* return */
+            }
         }
 
+        /* Quoth the raven, 'Nevermore!' */
+        KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep = FALSE;
+
         /* Check if we expect a single step */
         if ((TrapFrame->Dr6 & 0xf) == 0 && KdbNumSingleSteps > 0)
         {
@@ -1545,7 +1568,7 @@ KdbEnterDebuggerException(
                 return kdHandleException;
             }
 
-            KdbpPrint("Entered debugger on unexpected debug trap!\n");
+            KdbpPrint("\nEntered debugger on unexpected debug trap!\n");
         }
     }
     else if (ExceptionCode == STATUS_BREAKPOINT)
@@ -1560,7 +1583,7 @@ KdbEnterDebuggerException(
             return kdHandleException;
         }
 
-        KdbpPrint("Entered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
+        KdbpPrint("\nEntered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
                   TrapFrame->SegCs & 0xffff, TrapFrame->Eip - 1);
     }
     else
@@ -1574,7 +1597,7 @@ KdbEnterDebuggerException(
             return ContinueType;
         }
 
-        KdbpPrint("Entered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
+        KdbpPrint("\nEntered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
                   FirstChance ? "first" : "last", ExceptionCode, ExceptionString);
 
         if (ExceptionCode == STATUS_ACCESS_VIOLATION &&
@@ -1636,6 +1659,9 @@ KdbEnterDebuggerException(
     /* Check if we should single step */
     if (KdbNumSingleSteps > 0)
     {
+        /* Variable explains itself! */
+        KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep = TRUE;
+
         if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Tf.Eip)) ||
             (!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Tf.Eip)))
         {
@@ -1662,7 +1688,7 @@ KdbEnterDebuggerException(
     /* Decrement the entry count */
     InterlockedDecrement(&KdbEntryCount);
 
-    /* HACK: Raise back to old IRWL */
+    /* HACK: Raise back to old IRQL */
     KeRaiseIrql(OldIrql, &OldIrql);
 
     /* Leave critical section */
@@ -1705,30 +1731,29 @@ INIT_FUNCTION
 KdbpGetCommandLineSettings(
     PCHAR p1)
 {
-    PCHAR p2;
+#define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1)
 
-    while (p1 && (p2 = strchr(p1, ' ')))
+    while (p1 && (p1 = strchr(p1, ' ')))
     {
-        p2 += 2;
+        /* Skip other spaces */
+        while (*p1 == ' ') ++p1;
 
-        if (!_strnicmp(p2, "KDSERIAL", 8))
+        if (!_strnicmp(p1, "KDSERIAL", CONST_STR_LEN("KDSERIAL")))
         {
-            p2 += 8;
+            p1 += CONST_STR_LEN("KDSERIAL");
             KdbDebugState |= KD_DEBUG_KDSERIAL;
             KdpDebugMode.Serial = TRUE;
         }
-        else if (!_strnicmp(p2, "KDNOECHO", 8))
+        else if (!_strnicmp(p1, "KDNOECHO", CONST_STR_LEN("KDNOECHO")))
         {
-            p2 += 8;
+            p1 += CONST_STR_LEN("KDNOECHO");
             KdbDebugState |= KD_DEBUG_KDNOECHO;
         }
-        else if (!_strnicmp(p2, "FIRSTCHANCE", 11))
+        else if (!_strnicmp(p1, "FIRSTCHANCE", CONST_STR_LEN("FIRSTCHANCE")))
         {
-            p2 += 11;
+            p1 += CONST_STR_LEN("FIRSTCHANCE");
             KdbpSetEnterCondition(-1, TRUE, KdbEnterAlways);
         }
-
-        p1 = p2;
     }
 }