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. */
{ KdbDoNotEnter, KdbEnterFromKmode }, /* 17: Alignment Check */
{ KdbDoNotEnter, KdbEnterFromKmode }, /* 18: Machine Check */
{ KdbDoNotEnter, KdbEnterFromKmode }, /* 19: SIMD fault */
- { KdbEnterAlways, KdbEnterAlways }, /* 20: Assertion failure */
+ { KdbEnterFromKmode, KdbDoNotEnter }, /* 20: Assertion failure */
{ KdbDoNotEnter, KdbEnterFromKmode } /* Last entry: used for unknown exceptions */
};
PKTRAP_FRAME TrapFrame,
PKDB_KTRAP_FRAME KdbTrapFrame)
{
- ULONG TrapCr0, TrapCr2, TrapCr3, TrapCr4;
-
/* Copy the TrapFrame only up to Eflags and zero the rest*/
RtlCopyMemory(&KdbTrapFrame->Tf, TrapFrame, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
RtlZeroMemory((PVOID)((ULONG_PTR)&KdbTrapFrame->Tf + FIELD_OFFSET(KTRAP_FRAME, HardwareEsp)),
sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
-#ifndef _MSC_VER
- asm volatile(
- "movl %%cr0, %0" "\n\t"
- "movl %%cr2, %1" "\n\t"
- "movl %%cr3, %2" "\n\t"
- "movl %%cr4, %3" "\n\t"
- : "=r"(TrapCr0), "=r"(TrapCr2),
- "=r"(TrapCr3), "=r"(TrapCr4));
-#else
- __asm
- {
- mov eax, cr0;
- mov TrapCr0, eax;
-
- mov eax, cr2;
- mov TrapCr2, eax;
-
- mov eax, cr3;
- mov TrapCr3, eax;
-/* FIXME: What's the problem with cr4? */
- //mov eax, cr4;
- //mov TrapCr4, eax;
- }
-#endif
-
- KdbTrapFrame->Cr0 = TrapCr0;
- KdbTrapFrame->Cr2 = TrapCr2;
- KdbTrapFrame->Cr3 = TrapCr3;
- KdbTrapFrame->Cr4 = TrapCr4;
+ KdbTrapFrame->Cr0 = __readcr0();
+ KdbTrapFrame->Cr2 = __readcr2();
+ KdbTrapFrame->Cr3 = __readcr3();
+ KdbTrapFrame->Cr4 = __readcr4();
KdbTrapFrame->Tf.HardwareEsp = KiEspFromTrapFrame(TrapFrame);
KdbTrapFrame->Tf.HardwareSegSs = (USHORT)(KiSsFromTrapFrame(TrapFrame) & 0xFFFF);
* Disables interrupts, releases display ownership, ...
*/
static VOID
-KdbpInternalEnter()
+KdbpInternalEnter(VOID)
{
PETHREAD Thread;
PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
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 (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)
{
/* 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)))
{