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. */
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 */
};
"Math Fault",
"Alignment Check",
"Machine Check",
- "SIMD Fault"
+ "SIMD Fault",
+ "Assertion Failure"
};
ULONG
* Disables interrupts, releases display ownership, ...
*/
static VOID
-KdbpInternalEnter()
+KdbpInternalEnter(VOID)
{
PETHREAD Thread;
PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
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);
case STATUS_FLOAT_MULTIPLE_TRAPS:
Ret = 18;
break;
+ case STATUS_ASSERTION_FAILURE:
+ Ret = 20;
+ break;
default:
Ret = RTL_NUMBER_OF(KdbEnterConditions) - 1;
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 :( */
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) &&
/* 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)) ||
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" :
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)
{
return kdHandleException;
}
- KdbpPrint("Entered debugger on unexpected debug trap!\n");
+ KdbpPrint("\nEntered debugger on unexpected debug trap!\n");
}
}
else if (ExceptionCode == STATUS_BREAKPOINT)
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
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 &&
/* 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)))
{
/* Decrement the entry count */
InterlockedDecrement(&KdbEntryCount);
- /* HACK: Raise back to old IRWL */
+ /* HACK: Raise back to old IRQL */
KeRaiseIrql(OldIrql, &OldIrql);
/* Leave critical section */
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;
}
}