Author: sginsberg
Date: Sat Oct 17 16:31:38 2009
New Revision: 43530
URL:
http://svn.reactos.org/svn/reactos?rev=43530&view=rev
Log:
- Add STATUS_SUCCESS to asm.h and make use of it.
- Implement Bus and I/O space read and write support.
- Implement support for AUTOENABLE, DISABLE and NOUMEX subparameters to /debug. Add the
missing string scan and set and respect the related globals properly. Add support for
disabling the debugger and suspending breakpoints.
- Add and implement KdIsThisAKdTrap to determine if the kernel debugger can't ignore a
particular trap -- returns true for software breakpoints and debug service calls (DbgPrint
for example). Called from KiDispatchException to determine whether to override NOUMEX
(otherwise, DbgPrint and friends will kill user mode applications). Stub this for KDBG as
it implements its own scheme for ignoring user mode.
- KiDispatchException: Clean up some goto and support NOUMEX. Also don't check if
KiDebugRoutine is NULL -- it will never be.
- KdEnableDebuggerWithLock should initialize the debugger even if KdDisableCount is 0 (but
only if called internally) as this means that the debugger was never initialized in the
first place. Required for AUTOENABLE and for enabling the debugger during a bugcheck. Add
the globals to kdbg too but don't set or respect them there as kdbg does not support
it.
- Enable KdEnableDebugger and implement KdDisableDebugger for KD as
KdDisableDebuggerWithLock is now implemented.
- Only build kdmemsup.c if KDBG is defined.
Modified:
trunk/reactos/include/ndk/i386/asm.h
trunk/reactos/ntoskrnl/include/internal/kd.h
trunk/reactos/ntoskrnl/include/internal/kd64.h
trunk/reactos/ntoskrnl/kd/kdmain.c
trunk/reactos/ntoskrnl/kd64/amd64/kdsup.c
trunk/reactos/ntoskrnl/kd64/arm/kdsup.c
trunk/reactos/ntoskrnl/kd64/i386/kdsup.c
trunk/reactos/ntoskrnl/kd64/kdapi.c
trunk/reactos/ntoskrnl/kd64/kdbreak.c
trunk/reactos/ntoskrnl/kd64/kddata.c
trunk/reactos/ntoskrnl/kd64/kdinit.c
trunk/reactos/ntoskrnl/kd64/kdtrap.c
trunk/reactos/ntoskrnl/ke/i386/exp.c
trunk/reactos/ntoskrnl/ke/i386/trap.s
trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
Modified: trunk/reactos/include/ndk/i386/asm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/i386/asm.h?rev…
==============================================================================
--- trunk/reactos/include/ndk/i386/asm.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/i386/asm.h [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -527,6 +527,7 @@
// NTSTATUS, Bugcheck Codes and Debug Codes
//
#ifdef __ASM__
+#define STATUS_SUCCESS 0x00000000
#define STATUS_ACCESS_VIOLATION 0xC0000005
#define STATUS_IN_PAGE_ERROR 0xC0000006
#define STATUS_GUARD_PAGE_VIOLATION 0x80000001
Modified: trunk/reactos/ntoskrnl/include/internal/kd.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/kd.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/kd.h [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -22,6 +22,7 @@
extern BOOLEAN _KdDebuggerNotPresent;
extern BOOLEAN KdBreakAfterSymbolLoad;
extern BOOLEAN KdPitchDebugger;
+extern BOOLEAN KdIgnoreUmExceptions;
BOOLEAN
NTAPI
@@ -131,6 +132,14 @@
PEXCEPTION_RECORD ExceptionRecord,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame
+);
+
+BOOLEAN
+NTAPI
+KdIsThisAKdTrap(
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT Context,
+ IN KPROCESSOR_MODE PreviousMode
);
/* INIT ROUTINES *************************************************************/
Modified: trunk/reactos/ntoskrnl/include/internal/kd64.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/kd64.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/kd64.h [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -72,6 +72,17 @@
);
//
+// Determines if the kernel debugger must handle a particular trap
+//
+BOOLEAN
+NTAPI
+KdIsThisAKdTrap(
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT Context,
+ IN KPROCESSOR_MODE PreviousMode
+);
+
+//
// Multi-Processor Switch Support
//
BOOLEAN
@@ -147,7 +158,7 @@
);
//
-// Debugger Enable, Enter and Exit
+// Debugger Enter, Exit, Enable and Disable
//
BOOLEAN
NTAPI
@@ -165,6 +176,12 @@
NTSTATUS
NTAPI
KdEnableDebuggerWithLock(
+ IN BOOLEAN NeedLock
+);
+
+NTSTATUS
+NTAPI
+KdDisableDebuggerWithLock(
IN BOOLEAN NeedLock
);
@@ -242,10 +259,10 @@
//
// Breakpoint Support
//
-VOID
-NTAPI
-KdpRestoreAllBreakpoints(
- VOID
+ULONG
+NTAPI
+KdpAddBreakpoint(
+ IN PVOID Address
);
BOOLEAN
@@ -261,10 +278,22 @@
IN PVOID Limit
);
-ULONG
-NTAPI
-KdpAddBreakpoint(
- IN PVOID Address
+VOID
+NTAPI
+KdpSuspendBreakPoint(
+ IN ULONG BpEntry
+);
+
+VOID
+NTAPI
+KdpRestoreAllBreakpoints(
+ VOID
+);
+
+VOID
+NTAPI
+KdpSuspendAllBreakPoints(
+ VOID
);
//
@@ -323,8 +352,8 @@
IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
+ IN ULONG Offset,
IN PVOID Buffer,
- IN ULONG Offset,
IN ULONG Length,
OUT PULONG ActualLength
);
@@ -335,8 +364,8 @@
IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
+ IN ULONG Offset,
IN PVOID Buffer,
- IN ULONG Offset,
IN ULONG Length,
OUT PULONG ActualLength
);
@@ -428,6 +457,8 @@
extern BOOLEAN _KdDebuggerNotPresent;
extern BOOLEAN _KdDebuggerEnabled;
extern BOOLEAN KdAutoEnableOnEvent;
+extern BOOLEAN KdBlockEnable;
+extern BOOLEAN KdIgnoreUmExceptions;
extern BOOLEAN KdPreviouslyEnabled;
extern BOOLEAN KdpDebuggerStructuresInitialized;
extern BOOLEAN KdEnteredDebugger;
Modified: trunk/reactos/ntoskrnl/kd/kdmain.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd/kdmain.c?rev=4…
==============================================================================
--- trunk/reactos/ntoskrnl/kd/kdmain.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd/kdmain.c [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -18,8 +18,9 @@
BOOLEAN KdDebuggerNotPresent = TRUE;
BOOLEAN KiEnableTimerWatchdog = FALSE;
BOOLEAN KdBreakAfterSymbolLoad = FALSE;
-BOOLEAN KdpBreakPending;
+BOOLEAN KdpBreakPending = FALSE;
BOOLEAN KdPitchDebugger = TRUE;
+BOOLEAN KdIgnoreUmExceptions = FALSE;
VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
typedef struct
@@ -200,6 +201,16 @@
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 *********************************************************/
/*
Modified: trunk/reactos/ntoskrnl/kd64/amd64/kdsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/amd64/kdsup.…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/amd64/kdsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/amd64/kdsup.c [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -68,8 +68,8 @@
KdpSysReadBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
+ IN ULONG Offset,
IN PVOID Buffer,
- IN ULONG Offset,
IN ULONG Length,
OUT PULONG ActualLength)
{
@@ -83,8 +83,8 @@
KdpSysWriteBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
+ IN ULONG Offset,
IN PVOID Buffer,
- IN ULONG Offset,
IN ULONG Length,
OUT PULONG ActualLength)
{
Modified: trunk/reactos/ntoskrnl/kd64/arm/kdsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/arm/kdsup.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/arm/kdsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/arm/kdsup.c [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -68,8 +68,8 @@
KdpSysReadBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
+ IN ULONG Offset,
IN PVOID Buffer,
- IN ULONG Offset,
IN ULONG Length,
OUT PULONG ActualLength)
{
@@ -83,8 +83,8 @@
KdpSysWriteBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
+ IN ULONG Offset,
IN PVOID Buffer,
- IN ULONG Offset,
IN ULONG Length,
OUT PULONG ActualLength)
{
Modified: trunk/reactos/ntoskrnl/kd64/i386/kdsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/i386/kdsup.c…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/i386/kdsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/i386/kdsup.c [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -11,9 +11,6 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
-
-#undef UNIMPLEMENTED
-#define UNIMPLEMENTED KdpDprintf("%s is unimplemented\n", __FUNCTION__)
/* FUNCTIONS *****************************************************************/
@@ -148,14 +145,21 @@
KdpSysReadBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
+ IN ULONG Offset,
IN PVOID Buffer,
- IN ULONG Offset,
IN ULONG Length,
OUT PULONG ActualLength)
{
- UNIMPLEMENTED;
- while (TRUE);
- return STATUS_UNSUCCESSFUL;
+ /* Just forward to HAL */
+ *ActualLength = HalGetBusDataByOffset(BusDataType,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ Offset,
+ Length);
+
+ /* Return status */
+ return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
NTSTATUS
@@ -163,14 +167,21 @@
KdpSysWriteBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
+ IN ULONG Offset,
IN PVOID Buffer,
- IN ULONG Offset,
IN ULONG Length,
OUT PULONG ActualLength)
{
- UNIMPLEMENTED;
- while (TRUE);
- return STATUS_UNSUCCESSFUL;
+ /* Just forward to HAL */
+ *ActualLength = HalSetBusDataByOffset(BusDataType,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ Offset,
+ Length);
+
+ /* Return status */
+ return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
NTSTATUS
@@ -185,7 +196,7 @@
ULONG RealLength;
/* Make sure that this is a valid request */
- if (((ULONG)BaseAddress < sizeof(KPROCESSOR_STATE)) &&
+ if ((BaseAddress < sizeof(KPROCESSOR_STATE)) &&
(Processor < KeNumberProcessors))
{
/* Get the actual length */
@@ -223,7 +234,7 @@
PVOID ControlStart;
/* Make sure that this is a valid request */
- if ((((ULONG)BaseAddress + Length) <= sizeof(KPROCESSOR_STATE)) &&
+ if (((BaseAddress + Length) <= sizeof(KPROCESSOR_STATE)) &&
(Processor < KeNumberProcessors))
{
/* Set the proper address */
@@ -256,9 +267,75 @@
IN ULONG DataSize,
OUT PULONG ActualDataSize)
{
- UNIMPLEMENTED;
- while (TRUE);
- return STATUS_UNSUCCESSFUL;
+ NTSTATUS Status;
+
+ /* Verify parameters */
+ if ((InterfaceType != Isa) ||
+ (BusNumber != 0) ||
+ (AddressSpace != 1))
+ {
+ /* Fail, we don't support this */
+ *ActualDataSize = 0;
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Check the size */
+ switch (DataSize)
+ {
+ case sizeof(UCHAR):
+
+ /* Read 1 byte */
+ *(PUCHAR)DataValue =
+ READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress);
+ *ActualDataSize = sizeof(UCHAR);
+ Status = STATUS_SUCCESS;
+ break;
+
+ case sizeof(USHORT):
+
+ /* Make sure the address is aligned */
+ if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
+ {
+ /* It isn't, bail out */
+ *ActualDataSize = 0;
+ Status = STATUS_DATATYPE_MISALIGNMENT;
+ break;
+ }
+
+ /* Read 2 bytes */
+ *(PUSHORT)DataValue =
+ READ_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress);
+ *ActualDataSize = sizeof(USHORT);
+ Status = STATUS_SUCCESS;
+ break;
+
+ case sizeof(ULONG):
+
+ /* Make sure the address is aligned */
+ if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
+ {
+ /* It isn't, bail out */
+ *ActualDataSize = 0;
+ Status = STATUS_DATATYPE_MISALIGNMENT;
+ break;
+ }
+
+ /* Read 4 bytes */
+ *(PULONG)DataValue =
+ READ_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress);
+ *ActualDataSize = sizeof(ULONG);
+ Status = STATUS_SUCCESS;
+ break;
+
+ default:
+
+ /* Invalid size, fail */
+ *ActualDataSize = 0;
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ /* Return status */
+ return Status;
}
NTSTATUS
@@ -271,16 +348,81 @@
IN ULONG DataSize,
OUT PULONG ActualDataSize)
{
- UNIMPLEMENTED;
- while (TRUE);
+ NTSTATUS Status;
+
+ /* Verify parameters */
+ if ((InterfaceType != Isa) ||
+ (BusNumber != 0) ||
+ (AddressSpace != 1))
+ {
+ /* Fail, we don't support this */
+ *ActualDataSize = 0;
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Check the size */
+ switch (DataSize)
+ {
+ case sizeof(UCHAR):
+
+ /* Write 1 byte */
+ WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress,
+ *(PUCHAR)DataValue);
+ *ActualDataSize = sizeof(UCHAR);
+ Status = STATUS_SUCCESS;
+ break;
+
+ case sizeof(USHORT):
+
+ /* Make sure the address is aligned */
+ if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
+ {
+ /* It isn't, bail out */
+ *ActualDataSize = 0;
+ Status = STATUS_DATATYPE_MISALIGNMENT;
+ break;
+ }
+
+ /* Write 2 bytes */
+ WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress,
+ *(PUSHORT)DataValue);
+ *ActualDataSize = sizeof(USHORT);
+ Status = STATUS_SUCCESS;
+ break;
+
+ case sizeof(ULONG):
+
+ /* Make sure the address is aligned */
+ if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
+ {
+ /* It isn't, bail out */
+ *ActualDataSize = 0;
+ Status = STATUS_DATATYPE_MISALIGNMENT;
+ break;
+ }
+
+ /* Write 4 bytes */
+ WRITE_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress,
+ *(PULONG)DataValue);
+ *ActualDataSize = sizeof(ULONG);
+ Status = STATUS_SUCCESS;
+ break;
+
+ default:
+
+ /* Invalid size, fail */
+ *ActualDataSize = 0;
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ /* Return status */
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+KdpSysCheckLowMemory(IN ULONG Flags)
+{
+ /* Stubbed as we don't support PAE */
return STATUS_UNSUCCESSFUL;
}
-
-NTSTATUS
-NTAPI
-KdpSysCheckLowMemory(IN ULONG Flags)
-{
- UNIMPLEMENTED;
- while (TRUE);
- return STATUS_UNSUCCESSFUL;
-}
Modified: trunk/reactos/ntoskrnl/kd64/kdapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdapi.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -602,7 +602,7 @@
else
{
/* SMP not yet handled */
- KdpDprintf("SMP UNHANDLED\n");
+ KdpDprintf("KdpGetContext: SMP UNHANDLED\n");
ControlStart = NULL;
while (TRUE);
}
@@ -653,7 +653,7 @@
else
{
/* SMP not yet handled */
- KdpDprintf("SMP UNHANDLED\n");
+ KdpDprintf("KdpSetContext: SMP UNHANDLED\n");
ControlStart = NULL;
while (TRUE);
}
@@ -770,8 +770,8 @@
State->ReturnStatus = KdpSysReadBusData(GetBusData->BusDataType,
GetBusData->BusNumber,
GetBusData->SlotNumber,
+ GetBusData->Offset,
Data->Buffer,
- GetBusData->Offset,
Length,
&Length);
@@ -803,8 +803,8 @@
State->ReturnStatus = KdpSysWriteBusData(SetBusData->BusDataType,
SetBusData->BusNumber,
SetBusData->SlotNumber,
+ SetBusData->Offset,
Data->Buffer,
- SetBusData->Offset,
SetBusData->Length,
&Length);
@@ -1476,6 +1476,22 @@
return KeQueryPerformanceCounter(NULL);
}
+NTSTATUS
+NTAPI
+KdpAllowDisable(VOID)
+{
+ /* Check if we are on MP */
+ if (KeNumberProcessors > 1)
+ {
+ /* TODO */
+ KdpDprintf("KdpAllowDisable: SMP UNHANDLED\n");
+ while (TRUE);
+ }
+
+ /* Allow disable */
+ return STATUS_SUCCESS;
+}
+
BOOLEAN
NTAPI
KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,
@@ -1575,6 +1591,13 @@
OldIrql = PASSIVE_LEVEL;
#endif
+ /* Check if enabling the debugger is blocked */
+ if (KdBlockEnable)
+ {
+ /* It is, fail the enable */
+ return STATUS_ACCESS_DENIED;
+ }
+
/* Check if we need to acquire the lock */
if (NeedLock)
{
@@ -1592,10 +1615,21 @@
/* Do the unlock */
KeLowerIrql(OldIrql);
KdpPortUnlock();
- }
-
- /* Fail: We're already enabled */
- return STATUS_INVALID_PARAMETER;
+
+ /* Fail: We're already enabled */
+ return STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ /*
+ * This can only happen if we are called from a bugcheck
+ * and were never initialized, so initialize the debugger now.
+ */
+ KdInitSystem(0, NULL);
+
+ /* Return success since we initialized */
+ return STATUS_SUCCESS;
+ }
}
/* Decrease the disable count */
@@ -1609,6 +1643,98 @@
KdpRestoreAllBreakpoints();
}
}
+
+ /* Check if we had locked the port before */
+ if (NeedLock)
+ {
+ /* Yes, now unlock it */
+ KeLowerIrql(OldIrql);
+ KdpPortUnlock();
+ }
+
+ /* We're done */
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+KdDisableDebuggerWithLock(IN BOOLEAN NeedLock)
+{
+ KIRQL OldIrql;
+ NTSTATUS Status;
+
+#if defined(__GNUC__)
+ /* Make gcc happy */
+ OldIrql = PASSIVE_LEVEL;
+#endif
+
+ /*
+ * If enabling the debugger is blocked
+ * then there is nothing to disable (duh)
+ */
+ if (KdBlockEnable)
+ {
+ /* Fail */
+ return STATUS_ACCESS_DENIED;
+ }
+
+ /* Check if we need to acquire the lock */
+ if (NeedLock)
+ {
+ /* Lock the port */
+ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+ KdpPortLock();
+ }
+
+ /* Check if we're not disabled */
+ if (!KdDisableCount)
+ {
+ /* Check if the debugger was never actually initialized */
+ if (!(KdDebuggerEnabled) && !(KdPitchDebugger))
+ {
+ /* It wasn't, so don't re-enable it later */
+ KdPreviouslyEnabled = FALSE;
+ }
+ else
+ {
+ /* It was, so we will re-enable it later */
+ KdPreviouslyEnabled = TRUE;
+ }
+
+ /* Check if we were called from the exported API and are enabled */
+ if ((NeedLock) && (KdPreviouslyEnabled))
+ {
+ /* Check if it is safe to disable the debugger */
+ Status = KdpAllowDisable();
+ if (!NT_SUCCESS(Status))
+ {
+ /* Release the lock and fail */
+ KeLowerIrql(OldIrql);
+ KdpPortUnlock();
+ return Status;
+ }
+ }
+
+ /* Only disable the debugger if it is enabled */
+ if (KdDebuggerEnabled)
+ {
+ /*
+ * Disable the debugger; suspend breakpoints
+ * and reset the debug stub
+ */
+ KdpSuspendAllBreakPoints();
+ KiDebugRoutine = KdpStub;
+
+ /* We are disabled now */
+ KdDebuggerEnabled = FALSE;
+#undef KdDebuggerEnabled
+ SharedUserData->KdDebuggerEnabled = FALSE;
+#define KdDebuggerEnabled _KdDebuggerEnabled
+ }
+ }
+
+ /* Increment the disable count */
+ KdDisableCount++;
/* Check if we had locked the port before */
if (NeedLock)
@@ -1632,9 +1758,18 @@
KdEnableDebugger(VOID)
{
/* Use the internal routine */
- KdpDprintf("KdEnableDebugger called\n");
- while (TRUE);
return KdEnableDebuggerWithLock(TRUE);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+KdDisableDebugger(VOID)
+{
+ /* Use the internal routine */
+ return KdDisableDebuggerWithLock(TRUE);
}
/*
@@ -1684,17 +1819,6 @@
/*
* @unimplemented
*/
-NTSTATUS
-NTAPI
-KdDisableDebugger(VOID)
-{
- /* HACK */
- return STATUS_SUCCESS;
-}
-
-/*
- * @unimplemented
- */
BOOLEAN
NTAPI
KdRefreshDebuggerNotPresent(VOID)
@@ -1721,4 +1845,3 @@
/* HACK */
return STATUS_SUCCESS;
}
-
Modified: trunk/reactos/ntoskrnl/kd64/kdbreak.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdbreak.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdbreak.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kdbreak.c [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -183,7 +183,7 @@
BreakpointsSuspended = FALSE;
/* Loop the breakpoints */
- for (BpIndex = 0; BpIndex < KD_BREAKPOINT_MAX; BpIndex++ )
+ for (BpIndex = 0; BpIndex < KD_BREAKPOINT_MAX; BpIndex++)
{
/* Check if they are valid, suspended breakpoints */
if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&
@@ -195,3 +195,36 @@
}
}
}
+
+VOID
+NTAPI
+KdpSuspendBreakPoint(IN ULONG BpEntry)
+{
+ ULONG BpIndex = BpEntry - 1;
+
+ /* Check if this is a valid, unsuspended breakpoint */
+ if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&
+ !(KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended))
+ {
+ /* Suspend it */
+ KdpBreakpointTable[BpIndex].Flags |= KdpBreakpointSuspended;
+ KdpLowWriteContent(BpIndex);
+ }
+}
+
+VOID
+NTAPI
+KdpSuspendAllBreakPoints(VOID)
+{
+ ULONG BpEntry;
+
+ /* Breakpoints are suspended */
+ BreakpointsSuspended = TRUE;
+
+ /* Loop every breakpoint */
+ for (BpEntry = 1; BpEntry <= KD_BREAKPOINT_MAX; BpEntry++)
+ {
+ /* Suspend it */
+ KdpSuspendBreakPoint(BpEntry);
+ }
+}
Modified: trunk/reactos/ntoskrnl/kd64/kddata.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kddata.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kddata.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kddata.c [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -68,6 +68,8 @@
BOOLEAN _KdDebuggerNotPresent;
BOOLEAN _KdDebuggerEnabled;
BOOLEAN KdAutoEnableOnEvent;
+BOOLEAN KdBlockEnable;
+BOOLEAN KdIgnoreUmExceptions;
BOOLEAN KdPreviouslyEnabled;
BOOLEAN KdpDebuggerStructuresInitialized;
BOOLEAN KdEnteredDebugger;
@@ -83,6 +85,9 @@
BOOLEAN BreakpointsSuspended;
ULONG KdpNumInternalBreakpoints;
+//
+// Symbol Data
+//
ULONG KdpCurrentSymbolStart, KdpCurrentSymbolEnd;
//
Modified: trunk/reactos/ntoskrnl/kd64/kdinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdinit.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdinit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kdinit.c [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -72,14 +72,19 @@
KdInitSystem(IN ULONG BootPhase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
- BOOLEAN EnableKd;
- LPSTR CommandLine, DebugLine;
+ BOOLEAN EnableKd, DisableKdAfterInit = FALSE, BlockEnable;
+ LPSTR CommandLine, DebugLine, DebugOptionStart, DebugOptionEnd;
ANSI_STRING ImageName;
PLDR_DATA_TABLE_ENTRY LdrEntry;
PLIST_ENTRY NextEntry;
- ULONG i, j, Length;
+ ULONG i, j, Length, DebugOptionLength;
CHAR NameBuffer[256];
PWCHAR Name;
+
+#if defined(__GNUC__)
+ /* Make gcc happy */
+ BlockEnable = FALSE;
+#endif
/* Check if this is Phase 1 */
if (BootPhase)
@@ -166,10 +171,87 @@
/* Enable KD */
EnableKd = TRUE;
- /* Check if there was additional data */
+ /* Check if there are any options */
if (DebugLine[5] == '=')
{
- /* FIXME: Check for NOUMEX, DISABLE, AUTOENABLE */
+ /* Save pointers */
+ DebugOptionStart = DebugOptionEnd = &DebugLine[6];
+
+ /* Scan the string for debug options */
+ for (;;)
+ {
+ /* Loop until we reach the end of the string */
+ while (*DebugOptionEnd != ANSI_NULL)
+ {
+ /* Check if this is a comma, a space or a tab */
+ if ((*DebugOptionEnd == ',') ||
+ (*DebugOptionEnd == ' ') ||
+ (*DebugOptionEnd == ' '))
+ {
+ /*
+ * We reached the end of the option or
+ * the end of the string, break out
+ */
+ break;
+ }
+ else
+ {
+ /* Move on to the next character */
+ DebugOptionEnd++;
+ }
+ }
+
+ /* Calculate the length of the current option */
+ DebugOptionLength = ((ULONG_PTR)DebugOptionEnd -
+ (ULONG_PTR)DebugOptionStart);
+
+ /*
+ * Break out if we reached the last option
+ * or if there were no options at all
+ */
+ if (!DebugOptionLength) break;
+
+ /* Now check which option this is */
+ if ((DebugOptionLength == 10) &&
+ !(strncmp(DebugOptionStart, "AUTOENABLE", 10)))
+ {
+ /*
+ * Disable the debugger, but
+ * allow it to be reenabled
+ */
+ DisableKdAfterInit = TRUE;
+ BlockEnable = FALSE;
+ KdAutoEnableOnEvent = TRUE;
+ }
+ else if ((DebugOptionLength == 7) &&
+ !(strncmp(DebugOptionStart, "DISABLE", 7)))
+ {
+ /* Disable the debugger */
+ DisableKdAfterInit = TRUE;
+ BlockEnable = TRUE;
+ KdAutoEnableOnEvent = FALSE;
+ }
+ else if ((DebugOptionLength == 6) &&
+ !(strncmp(DebugOptionStart, "NOUMEX", 6)))
+ {
+ /* Ignore user mode exceptions */
+ KdIgnoreUmExceptions = TRUE;
+ }
+
+ /*
+ * If there are more options then
+ * the next character should be a comma
+ */
+ if (*DebugOptionEnd != ',')
+ {
+ /* It isn't, break out */
+ break;
+ }
+
+ /* Move on to the next option */
+ DebugOptionEnd++;
+ DebugOptionStart = DebugOptionEnd;
+ }
}
}
}
@@ -182,7 +264,7 @@
}
else
{
- /* Called from a bugcheck...Save the Kernel Base */
+ /* Called from a bugcheck or a re-enable. Save the Kernel Base */
KdVersionBlock.KernBase = (ULONG64)(LONG_PTR)PsNtosImageBase;
/* Unconditionally enable KD */
@@ -225,6 +307,20 @@
#undef KdDebuggerEnabled
SharedUserData->KdDebuggerEnabled = TRUE;
#define KdDebuggerEnabled _KdDebuggerEnabled
+
+ /* Check if the debugger should be disabled initially */
+ if (DisableKdAfterInit)
+ {
+ /* Disable it */
+ KdDisableDebuggerWithLock(FALSE);
+
+ /*
+ * Save the enable block state and return initialized
+ * (the debugger is active but disabled).
+ */
+ KdBlockEnable = BlockEnable;
+ return TRUE;
+ }
/* Check if we have a loader block */
if (LoaderBlock)
Modified: trunk/reactos/ntoskrnl/kd64/kdtrap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdtrap.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdtrap.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kdtrap.c [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -289,3 +289,24 @@
return FALSE;
}
}
+
+BOOLEAN
+NTAPI
+KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT Context,
+ IN KPROCESSOR_MODE PreviousMode)
+{
+ /* Check if this is a breakpoint or a valid debug service */
+ if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
+ (ExceptionRecord->NumberParameters > 0) &&
+ (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK))
+ {
+ /* Then we have to handle it */
+ return TRUE;
+ }
+ else
+ {
+ /* We don't have to handle it */
+ return FALSE;
+ }
+}
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/exp.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/exp.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/exp.c [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -928,11 +928,19 @@
/* User mode exception, was it first-chance? */
if (FirstChance)
{
- /* Make sure a debugger is present, and ignore user-mode if requested */
- if ((KiDebugRoutine) &&
- (!(PsGetCurrentProcess()->DebugPort)))
- {
- /* Call the debugger */
+ /*
+ * Break into the kernel debugger unless a user mode debugger
+ * is present or user mode exceptions are ignored, unless this is
+ * a breakpoint or a debug service in which case we have to
+ * handle it.
+ */
+ if ((!(PsGetCurrentProcess()->DebugPort) &&
+ !(KdIgnoreUmExceptions)) ||
+ (KdIsThisAKdTrap(ExceptionRecord,
+ &Context,
+ PreviousMode)))
+ {
+ /* Call the kernel debugger */
if (KiDebugRoutine(TrapFrame,
ExceptionFrame,
ExceptionRecord,
@@ -946,7 +954,7 @@
}
/* Forward exception to user mode debugger */
- if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) goto Exit;
+ if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) return;
/* Set up the user-stack */
DispatchToUser:
@@ -1032,12 +1040,12 @@
if (DbgkForwardException(ExceptionRecord, TRUE, TRUE))
{
/* Handled, get out */
- goto Exit;
+ return;
}
else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE))
{
/* Handled, get out */
- goto Exit;
+ return;
}
/* 3rd strike, kill the process */
@@ -1061,7 +1069,6 @@
TrapFrame,
Context.ContextFlags,
PreviousMode);
-Exit:
return;
}
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -781,7 +781,7 @@
TRAP_PROLOG kit3_a, kit3_t
/* Set status code */
- mov eax, 0 //STATUS_SUCCESS
+ mov eax, STATUS_SUCCESS
/* Check for V86 */
PrepareInt3:
Modified: trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl-generic.…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] Sat Oct 17 16:31:38 2009
@@ -271,13 +271,15 @@
<file>pnproot.c</file>
</directory>
</directory>
- <directory name="kd">
- <if property="ARCH" value="i386">
- <directory name="i386">
- <file>kdmemsup.c</file>
- </directory>
- </if>
- </directory>
+ <if property="KDBG" value="1">
+ <directory name="kd">
+ <if property="ARCH" value="i386">
+ <directory name="i386">
+ <file>kdmemsup.c</file>
+ </directory>
+ </if>
+ </directory>
+ </if>
<if property="_WINKD_" value="0">
<directory name="kdbg">
<if property="ARCH" value="i386">