#include <ntoskrnl.h>
#define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
/* TYPES *********************************************************************/
STATIC KDB_KTRAP_FRAME KdbTrapFrame = { { 0 } }; /* The trapframe which was passed to KdbEnterDebuggerException */
STATIC KDB_KTRAP_FRAME KdbThreadTrapFrame = { { 0 } }; /* The trapframe of the current thread (KdbCurrentThread) */
STATIC KAPC_STATE KdbApcState;
+extern BOOLEAN KdbpBugCheckRequested;
/* Array of conditions when to enter KDB */
STATIC KDB_ENTER_CONDITION KdbEnterConditions[][2] =
if (KeIsExecutingDpc() && Process != KdbCurrentProcess)
{
KdbpPrint("Cannot attach to thread within another process while executing a DPC.\n");
+ ObDereferenceObject(Thread);
return FALSE;
}
KdbCurrentProcess = Process;
}
+ ObDereferenceObject(Thread);
return TRUE;
}
}
Entry = Process->ThreadListHead.Flink;
+ ObDereferenceObject(Process);
if (Entry == &KdbCurrentProcess->ThreadListHead)
{
KdbpPrint("No threads in process 0x%08x, cannot attach to process!\n", (ULONG)ProcessId);
Thread->Tcb.StackLimit = (ULONG)KdbStack;
Thread->Tcb.KernelStack = (char*)KdbStack + KDB_STACK_SIZE;
- /*KdbpPrint("Switching to KDB stack 0x%08x-0x%08x\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase);*/
+ /*KdbpPrint("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);*/
- KdbpStackSwitchAndCall(Thread->Tcb.KernelStack, KdbpCallMainLoop);
+ KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - sizeof(ULONG), KdbpCallMainLoop);
Thread->Tcb.InitialStack = SavedInitialStack;
Thread->Tcb.StackBase = SavedStackBase;
*
* \param ExceptionRecord Unused.
* \param PreviousMode UserMode if the exception was raised from umode, otherwise KernelMode.
- * \param Context Unused.
+ * \param Context Context, IN/OUT parameter.
* \param TrapFrame Exception TrapFrame.
* \param FirstChance TRUE when called before exception frames were serached,
* FALSE for the second call.
KdbEnterDebuggerException(
IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
IN KPROCESSOR_MODE PreviousMode,
- IN PCONTEXT Context OPTIONAL,
+ IN PCONTEXT Context,
IN OUT PKTRAP_FRAME TrapFrame,
IN BOOLEAN FirstChance)
{
if (ExceptionCode == STATUS_BREAKPOINT)
{
- /*
- * The breakpoint will point to the next instruction by default so
- * point it back to the start of original instruction.
- */
- //TrapFrame->Eip--;
-
/*
* ... and restore the original instruction.
*/
if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address,
BreakPoint->Data.SavedInstruction, NULL)))
{
- DbgPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
- KEBUGCHECK(0);
+ KdbpPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
+ KeBugCheck(0); // FIXME: Proper bugcode!
}
}
else if (BreakPoint->Type == KdbBreakPointTemporary &&
BreakPoint->Process == KdbCurrentProcess)
{
- ASSERT((TrapFrame->EFlags & X86_EFLAGS_TF) == 0);
+ ASSERT((TrapFrame->EFlags & EFLAGS_TF) == 0);
/*
* Delete the temporary breakpoint which was used to step over or into the instruction.
if ((KdbSingleStepOver && !KdbpStepOverInstruction(TrapFrame->Eip)) ||
(!KdbSingleStepOver && !KdbpStepIntoInstruction(TrapFrame->Eip)))
{
- TrapFrame->EFlags |= X86_EFLAGS_TF;
+ Context->EFlags |= EFLAGS_TF;
}
goto continue_execution; /* return */
}
BreakPoint->Type == KdbBreakPointTemporary)
{
ASSERT(ExceptionCode == STATUS_BREAKPOINT);
- TrapFrame->EFlags |= X86_EFLAGS_TF;
+ Context->EFlags |= EFLAGS_TF;
KdbBreakPointToReenable = BreakPoint;
}
if (BreakPoint->Type == KdbBreakPointSoftware)
{
- DbgPrint("Entered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
+ KdbpPrint("Entered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
KdbLastBreakPointNr, TrapFrame->SegCs & 0xffff, TrapFrame->Eip);
}
else if (BreakPoint->Type == KdbBreakPointHardware)
{
- DbgPrint("Entered debugger on breakpoint #%d: %s 0x%08x\n",
+ KdbpPrint("Entered debugger on breakpoint #%d: %s 0x%08x\n",
KdbLastBreakPointNr,
(BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address, 0xCC,
&BreakPoint->Data.SavedInstruction)))
{
- DbgPrint("Warning: Couldn't reenable breakpoint %d\n",
+ KdbpPrint("Warning: Couldn't reenable breakpoint %d\n",
BreakPoint - KdbBreakPoints);
}
/* Unset TF if we are no longer single stepping. */
if (KdbNumSingleSteps == 0)
- TrapFrame->EFlags &= ~X86_EFLAGS_TF;
+ Context->EFlags &= ~EFLAGS_TF;
goto continue_execution; /* return */
}
/* Check if we expect a single step */
if ((TrapFrame->Dr6 & 0xf) == 0 && KdbNumSingleSteps > 0)
{
- /*ASSERT((TrapFrame->Eflags & X86_EFLAGS_TF) != 0);*/
+ /*ASSERT((Context->Eflags & EFLAGS_TF) != 0);*/
if (--KdbNumSingleSteps > 0)
{
if ((KdbSingleStepOver && KdbpStepOverInstruction(TrapFrame->Eip)) ||
(!KdbSingleStepOver && KdbpStepIntoInstruction(TrapFrame->Eip)))
{
- TrapFrame->EFlags &= ~X86_EFLAGS_TF;
+ Context->EFlags &= ~EFLAGS_TF;
}
else
{
- TrapFrame->EFlags |= X86_EFLAGS_TF;
+ Context->EFlags |= EFLAGS_TF;
}
- goto continue_execution; /* return */
+ goto continue_execution; /* return */
}
-
- TrapFrame->EFlags &= ~X86_EFLAGS_TF;
- KdbEnteredOnSingleStep = TRUE;
+ else
+ {
+ Context->EFlags &= ~EFLAGS_TF;
+ KdbEnteredOnSingleStep = TRUE;
+ }
}
else
{
if (!EnterConditionMet)
{
- return kdDoNotHandleException;
+ return kdHandleException;
}
- DbgPrint("Entered debugger on unexpected debug trap!\n");
+ KdbpPrint("Entered debugger on unexpected debug trap!\n");
}
}
else if (ExceptionCode == STATUS_BREAKPOINT)
}
if (!EnterConditionMet)
{
- return kdDoNotHandleException;
+ return kdHandleException;
}
- DbgPrint("Entered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
+ KdbpPrint("Entered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
TrapFrame->SegCs & 0xffff, TrapFrame->Eip - 1);
}
else
return ContinueType;
}
- DbgPrint("Entered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
+ KdbpPrint("Entered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
FirstChance ? "first" : "last", ExceptionCode, ExceptionString);
if (ExceptionCode == STATUS_ACCESS_VIOLATION &&
ExceptionRecord != NULL && ExceptionRecord->NumberParameters != 0)
#endif
Err = TrapFrame->ErrCode;
- DbgPrint("Memory at 0x%p could not be %s: ", TrapCr2, (Err & (1 << 1)) ? "written" : "read");
+ KdbpPrint("Memory at 0x%p could not be %s: ", TrapCr2, (Err & (1 << 1)) ? "written" : "read");
if ((Err & (1 << 0)) == 0)
- DbgPrint("Page not present.\n");
+ KdbpPrint("Page not present.\n");
else
{
if ((Err & (1 << 3)) != 0)
- DbgPrint("Reserved bits in page directory set.\n");
+ KdbpPrint("Reserved bits in page directory set.\n");
else
- DbgPrint("Page protection violation.\n");
+ KdbpPrint("Page protection violation.\n");
}
}
}
if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Tf.Eip)) ||
(!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Tf.Eip)))
{
- ASSERT((KdbCurrentTrapFrame->Tf.EFlags & X86_EFLAGS_TF) == 0);
- /*KdbCurrentTrapFrame->Tf.EFlags &= ~X86_EFLAGS_TF;*/
+ ASSERT((KdbCurrentTrapFrame->Tf.EFlags & EFLAGS_TF) == 0);
+ /*KdbCurrentTrapFrame->Tf.EFlags &= ~EFLAGS_TF;*/
}
else
{
- KdbCurrentTrapFrame->Tf.EFlags |= X86_EFLAGS_TF;
+ Context->EFlags |= EFLAGS_TF;
}
}
/* Leave critical section */
Ke386RestoreFlags(OldEflags);
+ /* Check if user requested a bugcheck */
+ if (KdbpBugCheckRequested)
+ {
+ /* Clear the flag and bugcheck the system */
+ KdbpBugCheckRequested = FALSE;
+ KeBugCheck(MANUALLY_INITIATED_CRASH);
+ }
+
continue_execution:
/* Clear debug status */
- if (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT) /* FIXME: Why clear DR6 on INT3? */
+ if (ExceptionCode == STATUS_BREAKPOINT) /* FIXME: Why clear DR6 on INT3? */
{
/* Set the RF flag so we don't trigger the same breakpoint again. */
if (Resume)
{
- TrapFrame->EFlags |= X86_EFLAGS_RF;
+ TrapFrame->EFlags |= EFLAGS_RF;
}
/* Clear dr6 status flags. */
TrapFrame->Dr6 &= ~0x0000e00f;
+ /* Skip the current instruction */
+ Context->Eip++;
}
return ContinueType;
}
VOID
-STDCALL
+NTAPI
KdbpGetCommandLineSettings(PCHAR p1)
{
PCHAR p2;
- while (p1 && (p2 = strchr(p1, '/')))
+ while (p1 && (p2 = strchr(p1, ' ')))
{
p2++;
IN PVOID Src,
IN ULONG Bytes)
{
- NTSTATUS Status = STATUS_SUCCESS;
+ BOOLEAN Result = TRUE;
- _SEH_TRY
- {
- RtlCopyMemory(Dest,
- Src,
- Bytes);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
+ switch (Bytes)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ Result = KdpSafeReadMemory((ULONG_PTR)Src, Bytes, Dest);
+ break;
+ default:
+ {
+ ULONG_PTR Start, End, Write;
+ for (Start = (ULONG_PTR)Src,
+ End = Start + Bytes,
+ Write = (ULONG_PTR)Dest;
+ Result && (Start < End);
+ Start++, Write++)
+ if (!KdpSafeReadMemory(Start, 1, (PVOID)Write))
+ Result = FALSE;
+ break;
+ }
+ }
- return Status;
+ return Result ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION;
}
NTSTATUS
IN PVOID Src,
IN ULONG Bytes)
{
- NTSTATUS Status = STATUS_SUCCESS;
-
- _SEH_TRY
- {
- RtlCopyMemory(Dest,
- Src,
- Bytes);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- return Status;
+ BOOLEAN Result = TRUE;
+ ULONG_PTR Start, End, Write;
+
+ for (Start = (ULONG_PTR)Src,
+ End = Start + Bytes,
+ Write = (ULONG_PTR)Dest;
+ Result && (Start < End);
+ Start++, Write++)
+ if (!KdpSafeWriteMemory(Write, 1, *((PCHAR)Start)))
+ Result = FALSE;
+
+ return Result ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION;
}