KD System Rewrite:

- Totally dynamic based on the principle of Native Providers built-in the Kernel (like Screen, 
      FileLog and Serial) and a pluggable Wrapper which is optionally compiled (Bochs, GDB)
    - Nothing changed in KDBG, except for that its settings (KDSERIAL/KDNOECHO) are now stored in
      KdbDebugState instead.
    - Wrappers are currently built uncondtionally. With rbuild, I'll make them easily removable.
    - Debug Log code simplified greatly, sped up and now supports printing even the first boot messages,
      which wasn't supported before.
    - Removed most of KDBG compile-time settings, ones which are needed are in include/dbg as macros now.
    - Left in some kdbg init code and break code, but it could be made to be used as a 'wrapper' for those
      functions. I will do it later.
    - Made a hack for KdpEnterDebuggerException..it seems to be called differently and at different times
      for GDB vs KDBG and I couldn't unite them.
    - KdpServiceDispatcher now does both the documented and ros-internal debug functions and will eventually
      be called through INT2D from keyboard.sys instead of as an API.

All in all, this patch makes KD  separated from KDBG and creates a pluggable architecture for creating future wrappers that don't require changing tons of code in the future. It improves the debug
log by printing even the earliest debug messages to it and it removes many of the manual ifdef(KDBG) but making them automatic though a single macro file. It makes extra debugging functionality optional and it
allows removal of a private API from our exports.

svn path=/trunk/; revision=14799
This commit is contained in:
Alex Ionescu 2005-04-25 14:44:48 +00:00
parent 753a3c0e99
commit e160c0fb26
35 changed files with 1229 additions and 1202 deletions

View file

@ -114,7 +114,7 @@ static const BYTE asciiTable4[37]=
};
VOID STDCALL
KdSystemDebugControl(ULONG Code);
KdpServiceDispatcher(ULONG Code, PVOID Context1, PVOID Context2);
static LONG DoSystemDebug = -1;
static BOOLEAN InSysRq = FALSE;
@ -421,7 +421,7 @@ KbdWorkItemRoutine(IN PDEVICE_OBJECT DeviceObject,
Debug = InterlockedExchange(&DoSystemDebug, -1);
if (Debug != -1)
{
KdSystemDebugControl(Debug);
KdpServiceDispatcher(TAG('R', 'o', 's', ' '), (PVOID)Debug, NULL);
}
}
@ -447,7 +447,7 @@ KbdDpcRoutine(PKDPC Dpc,
}
else
{
KdSystemDebugControl(DoSystemDebug);
KdpServiceDispatcher(TAG('R', 'o', 's', ' '), (PVOID)DoSystemDebug, NULL);
DoSystemDebug = -1;
}
return;

View file

@ -22,6 +22,10 @@ KeSaveFloatingPointState(
VOID STDCALL KeAttachProcess(struct _KPROCESS *Process);
BOOLEAN
STDCALL
KeIsAttachedProcess(VOID);
VOID FASTCALL KiAcquireSpinLock(PKSPIN_LOCK SpinLock);
VOID FASTCALL KiReleaseSpinLock(PKSPIN_LOCK SpinLock);
@ -379,9 +383,6 @@ KeRosDumpStackFrames ( PULONG Frame, ULONG FrameCount );
ULONG STDCALL
KeRosGetStackFrames ( PULONG Frames, ULONG FrameCount );
BOOLEAN STDCALL
KeRosPrintAddress(PVOID address);
NTSTATUS STDCALL
KeSetAffinityThread(PKTHREAD Thread,
KAFFINITY Affinity);

View file

@ -329,11 +329,13 @@ OBJECTS_CC = \
# Kernel Debugger Support (Kd)
OBJECTS_KD = \
kd/dlog.o \
kd/gdbstub.o \
kd/kdebug.o \
kd/service.o
kd/kdinit.o \
kd/kdmain.o \
kd/kdio.o \
kd/service.o \
kd/wrappers/gdbstub.o \
kd/wrappers/bochs.o
# User-Mode Debugging (Dbgk)
OBJECTS_DBGK = \
dbgk/dbgkutil.o \

View file

@ -11,7 +11,6 @@
#include <ntoskrnl.h>
#include <ntos/bootvid.h>
#include <internal/kdb.h>
#define NDEBUG
#include <internal/debug.h>
@ -416,8 +415,8 @@ ExpInitializeExecutive(VOID)
/* Parse the Loaded Modules (by FreeLoader) and cache the ones we'll need */
ParseAndCacheLoadedModules(&SetupBoot);
/* Initialize the kernel debugger */
KdInitSystem (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
/* Initialize the kernel debugger parameters */
KdInitSystem(0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
/* Initialize the Dispatcher, Clock and Bug Check Mechanisms. */
KeInit2();
@ -489,8 +488,8 @@ ExpInitializeExecutive(VOID)
/* initialize callbacks */
ExpInitializeCallbacks();
/* Initialize the GDB Stub and break */
KdInit1();
/* Call KD Providers at Phase 1 */
KdInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
/* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
IoInit();
@ -506,9 +505,6 @@ ExpInitializeExecutive(VOID)
/* Initialize Cache Views */
CcInit();
/* Hook System Interrupt for the Debugger */
KdInit2();
/* Initialize File Locking */
FsRtlpInitFileLockingImplementation();
@ -537,8 +533,8 @@ ExpInitializeExecutive(VOID)
(KeLoaderBlock.MemHigher + 1088)/ 1024);
HalDisplayString(str);
/* Print which Debugger is being used */
KdInit3();
/* Call KD Providers at Phase 2 */
KdInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
/* Import and create NLS Data and Sections */
RtlpInitNls();
@ -549,10 +545,8 @@ ExpInitializeExecutive(VOID)
/* Initialize the time zone information from the registry */
ExpInitTimeZoneInfo();
/* Enter the kernel debugger before starting up the boot drivers */
#ifdef KDBG
/* Enter the kernel debugger before starting up the boot drivers */
KdbEnter();
#endif /* KDBG */
/* Setup Drivers and Root Device Node */
IoInit2(BootLog);

View file

@ -6,9 +6,35 @@
#define KdPrintEx(_x_) DbgPrintEx _x_
NTSTATUS STDCALL
LpcSendDebugMessagePort(PEPORT Port,
PLPC_DBG_MESSAGE Message,
PLPC_DBG_MESSAGE Reply);
#if defined(KDBG) || defined(DBG)
# define KDB_LOADUSERMODULE_HOOK(LDRMOD) KdbSymLoadUserModuleSymbols(LDRMOD)
# define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) KdbSymLoadDriverSymbols(FILENAME, MODULE)
# define KDB_UNLOADDRIVER_HOOK(MODULE) KdbSymUnloadDriverSymbols(MODULE)
# define KDB_LOADERINIT_HOOK(NTOS, HAL) KdbSymInit(NTOS, HAL)
# define KDB_SYMBOLFILE_HOOK(FILENAME) KdbSymProcessBootSymbols(FILENAME)
# define KDB_DELETEPROCESS_HOOK(PROCESS) KdbDeleteProcessHook(PROCESS)
#else
# define KDB_LOADUSERMODULE_HOOK(LDRMOD) do { } while (0)
# define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) do { } while (0)
# define KDB_UNLOADDRIVER_HOOK(MODULE) do { } while (0)
# define KDB_LOADERINIT_HOOK(NTOS, HAL) do { } while (0)
# define KDB_SYMBOLFILE_HOOK(FILENAME) do { } while (0)
# define KDB_CREATE_THREAD_HOOK(CONTEXT) do { } while (0)
# define KDB_DELETEPROCESS_HOOK(PROCESS) do { } while (0)
#endif
#ifdef KDBG
# define KeRosPrintAddress(ADDRESS) KdbSymPrintAddress(ADDRESS)
# define KdbInit() KdbpCliInit()
# define KdbModuleLoaded(FILENAME) KdbpCliModuleLoaded(FILENAME)
//# define KdbBreak() KdbBreak()
#else
# define KeRosPrintAddress(ADDRESS) KiRosPrintAddress(ADDRESS)
# define KdbEnterDebuggerException(ER, PM, C, TF, F) kdHandleException
# define KdbInit() do { } while (0)
# define KdbEnter() do { } while (0)
# define KdbModuleLoaded(X) do { } while (0)
//# define KdbBreak() do { } while (0)
#endif
#endif /* __INCLUDE_INTERNAL_DBG_H */

View file

@ -10,160 +10,169 @@
#include <internal/ldr.h>
#include <ntdll/ldr.h>
#define KD_DEBUG_DISABLED 0x00
#define KD_DEBUG_GDB 0x01
#define KD_DEBUG_PICE 0x02
#define KD_DEBUG_SCREEN 0x04
#define KD_DEBUG_SERIAL 0x08
#define KD_DEBUG_BOCHS 0x10
#define KD_DEBUG_FILELOG 0x20
#define KD_DEBUG_MDA 0x40
#define KD_DEBUG_KDB 0x80
#define KD_DEBUG_KDSERIAL 0x100
#define KD_DEBUG_KDNOECHO 0x200
struct _KD_DISPATCH_TABLE;
extern ULONG KdDebugState;
#ifdef GDB
#include "kdgdb.h"
#endif
#ifdef BOCHS
#include "kdbochs.h"
#endif
KD_PORT_INFORMATION GdbPortInfo;
KD_PORT_INFORMATION LogPortInfo;
/* KD ROUTINES ***************************************************************/
typedef enum _KD_CONTINUE_TYPE
{
kdContinue = 0,
kdDoNotHandleException,
kdHandleException
kdContinue = 0,
kdDoNotHandleException,
kdHandleException
} KD_CONTINUE_TYPE;
typedef
VOID
KbdDisableMouse();
STDCALL
(*PKDP_INIT_ROUTINE)(struct _KD_DISPATCH_TABLE *DispatchTable,
ULONG BootPhase);
typedef
VOID
STDCALL
(*PKDP_PRINT_ROUTINE)(PCH String);
typedef
VOID
STDCALL
(*PKDP_PROMPT_ROUTINE)(PCH String);
typedef
KD_CONTINUE_TYPE
STDCALL
(*PKDP_EXCEPTION_ROUTINE)(PEXCEPTION_RECORD ExceptionRecord,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame);
/* INIT ROUTINES *************************************************************/
VOID
KbdEnableMouse();
STDCALL
KdpScreenInit(struct _KD_DISPATCH_TABLE *DispatchTable,
ULONG BootPhase);
VOID
STDCALL
KdpSerialInit(struct _KD_DISPATCH_TABLE *DispatchTable,
ULONG BootPhase);
VOID
STDCALL
KdpInitDebugLog(struct _KD_DISPATCH_TABLE *DispatchTable,
ULONG BootPhase);
/* KD ROUTINES ***************************************************************/
KD_CONTINUE_TYPE
STDCALL
KdpEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
KPROCESSOR_MODE PreviousMode,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame,
BOOLEAN FirstChance,
BOOLEAN Gdb);
ULONG
KdpPrintString (PANSI_STRING String);
VOID
DebugLogWrite(PCH String);
VOID
DebugLogInit(VOID);
VOID
DebugLogInit2(VOID);
VOID
STDCALL
KdDisableDebugger(
VOID
);
VOID
STDCALL
KdEnableDebugger(
VOID
);
NTSTATUS
STDCALL
KdPowerTransition(
ULONG PowerState
);
KdpPrintString(PANSI_STRING String);
BOOLEAN
STDCALL
KeIsAttachedProcess(
VOID
);
KdpDetectConflicts(PCM_RESOURCE_LIST DriverList);
/* KD GLOBALS ***************************************************************/
VOID
KdInit1(VOID);
/* serial debug connection */
#define DEFAULT_DEBUG_PORT 2 /* COM2 */
#define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */
#define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
#define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
VOID
KdInit2(VOID);
/* KD Native Modes */
#define KdScreen 0
#define KdSerial 1
#define KdFile 2
#define KdMax 3
VOID
KdInit3(VOID);
/* KD Private Debug Modes */
typedef struct _KDP_DEBUG_MODE
{
union {
struct {
/* Native Modes */
UCHAR Screen :1;
UCHAR Serial :1;
UCHAR File :1;
/* Currently Supported Wrappers */
UCHAR Pice :1;
UCHAR Gdb :1;
UCHAR Bochs :1;
};
/* Generic Value */
ULONG Value;
};
} KDP_DEBUG_MODE;
VOID
KdPutChar(UCHAR Value);
/* KD Internal Debug Services */
typedef enum _KDP_DEBUG_SERVICE
{
DumpNonPagedPool = 0,
ManualBugCheck,
DumpNonPagedPoolStats,
DumpNewNonPagedPool,
DumpNewNonPagedPoolStats,
DumpAllThreads,
DumpUserThreads,
KdSpare1,
KdSpare2,
KdSpare3,
EnterDebugger
} KDP_DEBUG_SERVICE;
UCHAR
KdGetChar(VOID);
/* Dispatch Table for Wrapper Functions */
typedef struct _KD_DISPATCH_TABLE
{
LIST_ENTRY KdProvidersList;
PKDP_INIT_ROUTINE KdpInitRoutine;
PKDP_PRINT_ROUTINE KdpPrintRoutine;
PKDP_PROMPT_ROUTINE KdpPromptRoutine;
PKDP_EXCEPTION_ROUTINE KdpExceptionRoutine;
} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
VOID
KdGdbStubInit(ULONG Phase);
/* The current Debugging Mode */
extern KDP_DEBUG_MODE KdpDebugMode;
VOID
KdGdbDebugPrint (LPSTR Message);
/* The current Port IRQ */
extern ULONG KdpPortIrq;
VOID
KdDebugPrint (LPSTR Message);
/* The current Port */
extern ULONG KdpPort;
KD_CONTINUE_TYPE
KdEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame);
VOID KdInitializeMda(VOID);
VOID KdPrintMda(PCH pch);
/* Port Information for the Serial Native Mode */
extern KD_PORT_INFORMATION SerialPortInfo;
#if !defined(KDBG) && !defined(DBG)
# define KDB_LOADUSERMODULE_HOOK(LDRMOD) do { } while (0)
# define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) do { } while (0)
# define KDB_UNLOADDRIVER_HOOK(MODULE) do { } while (0)
# define KDB_LOADERINIT_HOOK(NTOS, HAL) do { } while (0)
# define KDB_SYMBOLFILE_HOOK(FILENAME) do { } while (0)
# define KDB_CREATE_THREAD_HOOK(CONTEXT) do { } while (0)
#else
# define KDB_LOADUSERMODULE_HOOK(LDRMOD) KdbSymLoadUserModuleSymbols(LDRMOD)
# define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) KdbSymLoadDriverSymbols(FILENAME, MODULE)
# define KDB_UNLOADDRIVER_HOOK(MODULE) KdbSymUnloadDriverSymbols(MODULE)
# define KDB_LOADERINIT_HOOK(NTOS, HAL) KdbSymInit(NTOS, HAL)
# define KDB_SYMBOLFILE_HOOK(FILENAME) KdbSymProcessBootSymbols(FILENAME)
/*#define KDB_CREATE_THREAD_HOOK(CONTEXT) \
KdbCreateThreadHook(CONTEXT)
*/
/* Init Functions for Native Providers */
extern PKDP_INIT_ROUTINE InitRoutines[KdMax];
VOID
KdbSymLoadUserModuleSymbols(IN PLDR_MODULE LdrModule);
/* Wrapper Init Function */
extern PKDP_INIT_ROUTINE WrapperInitRoutine;
/* Dispatch Tables for Native Providers */
extern KD_DISPATCH_TABLE DispatchTable[KdMax];
VOID
KdbSymFreeProcessSymbols(IN PEPROCESS Process);
VOID
KdbSymLoadDriverSymbols(IN PUNICODE_STRING Filename,
IN PMODULE_OBJECT Module);
VOID
KdbSymUnloadDriverSymbols(IN PMODULE_OBJECT ModuleObject);
VOID
KdbSymProcessBootSymbols(IN PCHAR FileName);
VOID
KdbSymInit(IN PMODULE_TEXT_SECTION NtoskrnlTextSection,
IN PMODULE_TEXT_SECTION LdrHalTextSection);
BOOLEAN
KdbSymPrintAddress(IN PVOID Address);
KD_CONTINUE_TYPE
KdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
KPROCESSOR_MODE PreviousMode,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame,
BOOLEAN FirstChance);
#endif /* KDBG || DBG */
#if !defined(KDBG)
# define KDB_DELETEPROCESS_HOOK(PROCESS) do { } while (0)
#else
# define KDB_DELETEPROCESS_HOOK(PROCESS) KdbDeleteProcessHook(PROCESS)
VOID
KdbDeleteProcessHook(IN PEPROCESS Process);
#endif /* KDBG */
VOID
DebugLogDumpMessages(VOID);
/* Dispatch Table for the Wrapper */
extern KD_DISPATCH_TABLE WrapperTable;
/* The KD Native Provider List */
extern LIST_ENTRY KdProviders;
#endif /* __INCLUDE_INTERNAL_KERNEL_DEBUGGER_H */

View file

@ -16,7 +16,6 @@
# define RTL_NUMBER_OF(x) (sizeof(x) / sizeof((x)[0]))
#endif
/* TYPES *********************************************************************/
/* from kdb.c */
@ -75,6 +74,11 @@ typedef enum _KDB_ENTER_CONDITION
KdbEnterFromUmode
} KDB_ENTER_CONDITION;
typedef enum _KDB_OUTPUT_SETTINGS
{
KD_DEBUG_KDSERIAL,
KD_DEBUG_KDNOECHO
} KDB_OUTPUT_SETTINGS;
/* from kdb_symbols.c */
typedef struct _KDB_MODULE_INFO
@ -176,6 +180,40 @@ KdbSymGetAddressInformation(IN PROSSYM_INFO RosSymInfo,
OUT PULONG LineNumber OPTIONAL,
OUT PCH FileName OPTIONAL,
OUT PCH FunctionName OPTIONAL);
VOID
KdbSymLoadUserModuleSymbols(IN PLDR_MODULE LdrModule);
VOID
KdbSymFreeProcessSymbols(IN PEPROCESS Process);
VOID
KdbSymLoadDriverSymbols(IN PUNICODE_STRING Filename,
IN PMODULE_OBJECT Module);
VOID
KdbSymUnloadDriverSymbols(IN PMODULE_OBJECT ModuleObject);
VOID
KdbSymProcessBootSymbols(IN PCHAR FileName);
VOID
KdbSymInit(IN PMODULE_TEXT_SECTION NtoskrnlTextSection,
IN PMODULE_TEXT_SECTION LdrHalTextSection);
BOOLEAN
KdbSymPrintAddress(IN PVOID Address);
KD_CONTINUE_TYPE
KdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
KPROCESSOR_MODE PreviousMode,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame,
BOOLEAN FirstChance);
VOID
KdbDeleteProcessHook(IN PEPROCESS Process);
/* from kdb.c */
@ -185,13 +223,7 @@ extern LONG KdbLastBreakPointNr;
extern ULONG KdbNumSingleSteps;
extern BOOLEAN KdbSingleStepOver;
extern PKDB_KTRAP_FRAME KdbCurrentTrapFrame;
VOID
KdbInit();
VOID
KdbModuleLoaded(
IN PUNICODE_STRING Name);
extern ULONG KdbDebugState;
LONG
KdbpGetNextBreakPointNr(
@ -255,6 +287,10 @@ BOOLEAN
KdbpAttachToProcess(
PVOID ProcessId);
VOID
STDCALL
KdbpGetCommandLineSettings(PCHAR p1);
/* other functions */
#define KdbpSafeReadMemory(dst, src, size) MmSafeCopyFromUser(dst, src, size)
@ -278,7 +314,10 @@ VOID
DbgEnableFile(PCH Filename);
VOID
DbgDisableFile(PCH Filename);
VOID
KbdDisableMouse();
VOID
KbdEnableMouse();
#endif /* NTOSKRNL_KDB_H */

View file

@ -0,0 +1,18 @@
/* $Id: kd.h 13948 2005-03-12 01:11:06Z navaraf $
*
* kernel debugger prototypes
*/
#ifndef __INCLUDE_INTERNAL_KD_BOCHS_H
#define __INCLUDE_INTERNAL_KD_BOCHS_H
#include <internal/ke.h>
#include <internal/ldr.h>
#include <ntdll/ldr.h>
VOID
STDCALL
KdpBochsInit(struct _KD_DISPATCH_TABLE *DispatchTable,
ULONG BootPhase);
#endif /* __INCLUDE_INTERNAL_KD_BOCHS_H */

View file

@ -0,0 +1,20 @@
/* $Id: kd.h 13948 2005-03-12 01:11:06Z navaraf $
*
* kernel debugger prototypes
*/
#ifndef __INCLUDE_INTERNAL_KD_GDB_H
#define __INCLUDE_INTERNAL_KD_GDB_H
#include <internal/ke.h>
#include <internal/ldr.h>
#include <ntdll/ldr.h>
VOID
STDCALL
KdpGdbStubInit(struct _KD_DISPATCH_TABLE *DispatchTable,
ULONG BootPhase);
extern KD_PORT_INFORMATION GdbPortInfo;
#endif /* __INCLUDE_INTERNAL_KD_BOCHS_H */

View file

@ -231,6 +231,9 @@ KeProfileInterruptWithSource(
IN KPROFILE_SOURCE Source
);
BOOLEAN
STDCALL
KiRosPrintAddress(PVOID Address);
VOID STDCALL KeUpdateSystemTime(PKTRAP_FRAME TrapFrame, KIRQL Irql);
VOID STDCALL KeUpdateRunTime(PKTRAP_FRAME TrapFrame, KIRQL Irql);

View file

@ -14,9 +14,7 @@ typedef struct _MODULE_TEXT_SECTION
LIST_ENTRY ListEntry;
PWCH Name;
PIMAGE_OPTIONAL_HEADER OptionalHeader;
#if defined(DBG) || defined(KDBG)
PROSSYM_INFO RosSymInfo;
#endif /* KDBG */
} MODULE_TEXT_SECTION, *PMODULE_TEXT_SECTION;
typedef struct _MODULE_OBJECT

View file

@ -54,6 +54,9 @@
#include <internal/port.h>
#include <internal/nls.h>
#include <internal/dbg.h>
#ifdef KDBG
#include <internal/kdb.h>
#endif
#include <internal/dbgk.h>
#include <internal/trap.h>
#include <internal/safe.h>

View file

@ -11,7 +11,6 @@
/* INCLUDES ****************************************************************/
#include <ntoskrnl.h>
#include <internal/kdb.h>
#define NDEBUG
#include <internal/debug.h>
@ -645,13 +644,11 @@ IoInit3(VOID)
KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
}
/* Start Profiling on a Debug Build */
#if defined(KDBG)
/* Read KDB Data */
KdbInit();
#endif /* KDBG */
/* I/O is now setup for disk access, so start the debugging logger thread. */
if (KdDebugState & KD_DEBUG_FILELOG) DebugLogInit2();
/* I/O is now setup for disk access, so phase 3 */
KdInitSystem(3, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
/* Load services for devices found by PnP manager */
IopInitializePnpServices(IopRootDeviceNode, FALSE);

View file

@ -83,68 +83,14 @@ IoReportResourceForDetection(
*ConflictDetected = FALSE;
DPRINT1("IoReportResourceForDetection partly implemented\n");
/* HACK: check if serial debug output is enabled. If yes,
* prevent serial port driver to detect this serial port
* by indicating a conflict
*/
if ((KdDebugState & KD_DEBUG_SERIAL) && DriverList != NULL)
/* FIXME: Manually indicate conflicts with KD Ports */
if (DriverList)
{
ULONG ComPortBase = 0;
ULONG i;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
switch (LogPortInfo.ComPort)
{
case 1: ComPortBase = 0x3f8; break;
case 2: ComPortBase = 0x2f8; break;
case 3: ComPortBase = 0x3e8; break;
case 4: ComPortBase = 0x2e8; break;
}
/* search for this port address in DriverList */
for (i = 0; i < DriverList->List[0].PartialResourceList.Count; i++)
{
ResourceDescriptor = &DriverList->List[0].PartialResourceList.PartialDescriptors[i];
if (ResourceDescriptor->Type == CmResourceTypePort)
if (KdpDetectConflicts(DriverList))
{
if (ResourceDescriptor->u.Port.Start.u.LowPart <= ComPortBase
&& ResourceDescriptor->u.Port.Start.u.LowPart + ResourceDescriptor->u.Port.Length > ComPortBase)
{
*ConflictDetected = TRUE;
return STATUS_CONFLICTING_ADDRESSES;
}
*ConflictDetected = TRUE;
return STATUS_CONFLICTING_ADDRESSES;
}
}
}
if ((KdDebugState & KD_DEBUG_GDB) && DriverList != NULL)
{
ULONG ComPortBase = 0;
ULONG i;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
switch (GdbPortInfo.ComPort)
{
case 1: ComPortBase = 0x3f8; break;
case 2: ComPortBase = 0x2f8; break;
case 3: ComPortBase = 0x3e8; break;
case 4: ComPortBase = 0x2e8; break;
}
/* search for this port address in DriverList */
for (i = 0; i < DriverList->List[0].PartialResourceList.Count; i++)
{
ResourceDescriptor = &DriverList->List[0].PartialResourceList.PartialDescriptors[i];
if (ResourceDescriptor->Type == CmResourceTypePort)
{
if (ResourceDescriptor->u.Port.Start.u.LowPart <= ComPortBase
&& ResourceDescriptor->u.Port.Start.u.LowPart + ResourceDescriptor->u.Port.Length > ComPortBase)
{
*ConflictDetected = TRUE;
return STATUS_CONFLICTING_ADDRESSES;
}
}
}
}
if (PopSystemPowerDeviceNode != NULL && DriverListSize > 0)

View file

@ -1,230 +0,0 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/kd/kdebug.c
* PURPOSE: Kernel debugger
*
* PROGRAMMERS: Eric Kohl (ekohl@abo.rhein-zeitung.de)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
/* GLOBALS *******************************************************************/
#define DEBUGLOG_SIZE (32*1024)
static CHAR DebugLog[DEBUGLOG_SIZE];
static ULONG DebugLogStart;
static ULONG DebugLogEnd;
static ULONG DebugLogCount;
static KSPIN_LOCK DebugLogLock;
static ULONG DebugLogOverflow;
static HANDLE DebugLogThreadHandle;
static CLIENT_ID DebugLogThreadCid;
static HANDLE DebugLogFile;
static KEVENT DebugLogEvent;
/* FUNCTIONS *****************************************************************/
VOID
DebugLogDumpMessages(VOID)
{
static CHAR Buffer[256];
ULONG Offset;
ULONG Length;
if (!(KdDebugState & KD_DEBUG_FILELOG))
{
return;
}
KdDebugState &= ~KD_DEBUG_FILELOG;
Offset = (DebugLogEnd + 1) % DEBUGLOG_SIZE;
do
{
if (Offset <= DebugLogEnd)
{
Length = min(255, DebugLogEnd - Offset);
}
else
{
Length = min(255, DEBUGLOG_SIZE - Offset);
}
memcpy(Buffer, DebugLog + Offset, Length);
Buffer[Length] = 0;
DbgPrint(Buffer);
Offset = (Offset + Length) % DEBUGLOG_SIZE;
}
while (Length > 0);
}
VOID INIT_FUNCTION
DebugLogInit(VOID)
{
KeInitializeSpinLock(&DebugLogLock);
DebugLogStart = 0;
DebugLogEnd = 0;
DebugLogOverflow = 0;
DebugLogCount = 0;
KeInitializeEvent(&DebugLogEvent, NotificationEvent, FALSE);
}
VOID STDCALL
DebugLogThreadMain(PVOID Context)
{
KIRQL oldIrql;
IO_STATUS_BLOCK Iosb;
static CHAR Buffer[256];
ULONG WLen;
for (;;)
{
LARGE_INTEGER TimeOut;
TimeOut.QuadPart = -5000000; /* Half a second. */
KeWaitForSingleObject(&DebugLogEvent,
0,
KernelMode,
FALSE,
&TimeOut);
KeAcquireSpinLock(&DebugLogLock, &oldIrql);
while (DebugLogCount > 0)
{
if (DebugLogStart > DebugLogEnd)
{
WLen = min(256, DEBUGLOG_SIZE - DebugLogStart);
memcpy(Buffer, &DebugLog[DebugLogStart], WLen);
Buffer[WLen + 1] = '\n';
DebugLogStart =
(DebugLogStart + WLen) % DEBUGLOG_SIZE;
DebugLogCount = DebugLogCount - WLen;
KeReleaseSpinLock(&DebugLogLock, oldIrql);
NtWriteFile(DebugLogFile,
NULL,
NULL,
NULL,
&Iosb,
Buffer,
WLen + 1,
NULL,
NULL);
}
else
{
WLen = min(255, DebugLogEnd - DebugLogStart);
memcpy(Buffer, &DebugLog[DebugLogStart], WLen);
DebugLogStart =
(DebugLogStart + WLen) % DEBUGLOG_SIZE;
DebugLogCount = DebugLogCount - WLen;
KeReleaseSpinLock(&DebugLogLock, oldIrql);
NtWriteFile(DebugLogFile,
NULL,
NULL,
NULL,
&Iosb,
Buffer,
WLen,
NULL,
NULL);
}
KeAcquireSpinLock(&DebugLogLock, &oldIrql);
}
KeResetEvent(&DebugLogEvent);
KeReleaseSpinLock(&DebugLogLock, oldIrql);
}
}
VOID INIT_FUNCTION
DebugLogInit2(VOID)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING FileName;
IO_STATUS_BLOCK Iosb;
RtlInitUnicodeString(&FileName, L"\\SystemRoot\\debug.log");
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
0,
NULL,
NULL);
Status = NtCreateFile(&DebugLogFile,
FILE_ALL_ACCESS,
&ObjectAttributes,
&Iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_SUPERSEDE,
FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (!NT_SUCCESS(Status))
{
DbgPrint("Failed to create debug log file\n");
return;
}
Status = PsCreateSystemThread(&DebugLogThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
&DebugLogThreadCid,
DebugLogThreadMain,
NULL);
}
VOID
DebugLogWrite(PCH String)
{
KIRQL oldIrql;
if (KeGetCurrentIrql() > DISPATCH_LEVEL)
{
DebugLogOverflow++;
return;
}
KeAcquireSpinLock(&DebugLogLock, &oldIrql);
if (DebugLogCount == DEBUGLOG_SIZE)
{
DebugLogOverflow++;
KeReleaseSpinLock(&DebugLogLock, oldIrql);
if (oldIrql < DISPATCH_LEVEL)
{
KeSetEvent(&DebugLogEvent, IO_NO_INCREMENT, FALSE);
}
return;
}
while ((*String) != 0)
{
DebugLog[DebugLogEnd] = *String;
String++;
DebugLogCount++;
if (DebugLogCount == DEBUGLOG_SIZE)
{
DebugLogOverflow++;
KeReleaseSpinLock(&DebugLogLock, oldIrql);
if (oldIrql < DISPATCH_LEVEL)
{
KeSetEvent(&DebugLogEvent, IO_NO_INCREMENT, FALSE);
}
return;
}
DebugLogEnd = (DebugLogEnd + 1) % DEBUGLOG_SIZE;
}
KeReleaseSpinLock(&DebugLogLock, oldIrql);
if (oldIrql < DISPATCH_LEVEL)
{
KeSetEvent(&DebugLogEvent, IO_NO_INCREMENT, FALSE);
}
}

View file

@ -1,511 +0,0 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/kd/kdebug.c
* PURPOSE: Kernel debugger
*
* PROGRAMMERS: Eric Kohl (ekohl@abo.rhein-zeitung.de)
*/
#include <ntoskrnl.h>
#include <internal/kdb.h>
#include <internal/debug.h>
/* serial debug connection */
#define DEFAULT_DEBUG_PORT 2 /* COM2 */
#define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */
#define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */
#define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
/* bochs debug output */
#define BOCHS_LOGGER_PORT (0xe9)
/* VARIABLES ***************************************************************/
BOOLEAN
__declspec(dllexport)
KdDebuggerEnabled = FALSE; /* EXPORTED */
BOOLEAN
__declspec(dllexport)
KdEnteredDebugger = FALSE; /* EXPORTED */
BOOLEAN
__declspec(dllexport)
KdDebuggerNotPresent = TRUE; /* EXPORTED */
ULONG
__declspec(dllexport)
KiBugCheckData; /* EXPORTED */
BOOLEAN
__declspec(dllexport)
KiEnableTimerWatchdog = FALSE; /* EXPORTED */
static BOOLEAN KdpBreakPending = FALSE;
ULONG KdDebugState = KD_DEBUG_DISABLED;
ULONG KdpPortIrq = 0;
KD_PORT_INFORMATION GdbPortInfo;
KD_PORT_INFORMATION LogPortInfo;
/* PRIVATE FUNCTIONS ********************************************************/
static VOID
PrintString(char* fmt,...)
{
char buffer[512];
va_list ap;
va_start(ap, fmt);
_vsnprintf(buffer, sizeof(buffer) - 1, fmt, ap);
buffer[sizeof(buffer) - 1] = 0;
va_end(ap);
HalDisplayString(buffer);
}
VOID INIT_FUNCTION
KdInitSystem(ULONG BootPhase,
PLOADER_PARAMETER_BLOCK LoaderBlock)
{
KD_PORT_INFORMATION PortInfo;
ULONG Value;
PCHAR p1, p2;
if (BootPhase > 0)
{
#ifdef KDBG
/* Initialize the local kernel debugger. */
KdDebuggerEnabled = TRUE;
KdDebugState |= KD_DEBUG_KDB;
#endif
}
if (BootPhase == 0)
{
/* Set debug port default values */
PortInfo.ComPort = DEFAULT_DEBUG_PORT;
PortInfo.BaudRate = DEFAULT_DEBUG_BAUD_RATE;
KdpPortIrq = DEFAULT_DEBUG_COM2_IRQ;
/* Set serial log port default values */
LogPortInfo.ComPort = DEFAULT_DEBUG_PORT;
LogPortInfo.BaudRate = DEFAULT_DEBUG_BAUD_RATE;
}
/* Parse kernel command line */
/* Check for 'DEBUGPORT' */
p1 = (PCHAR)LoaderBlock->CommandLine;
while (p1 && (p2 = strchr(p1, '/')))
{
p2++;
if (!_strnicmp(p2, "DEBUGPORT", 9))
{
p2 += 9;
if (*p2 == '=')
{
p2++;
if (!_strnicmp(p2, "SCREEN", 6) && BootPhase > 0)
{
p2 += 6;
KdDebugState |= KD_DEBUG_SCREEN;
}
else if (!_strnicmp(p2, "BOCHS", 5) && BootPhase == 0)
{
p2 += 5;
KdDebugState |= KD_DEBUG_BOCHS;
}
else if (!_strnicmp(p2, "GDB", 3) && BootPhase == 0)
{
p2 += 3;
KdDebuggerEnabled = TRUE;
KdDebugState |= KD_DEBUG_GDB;
/* Reset port information to defaults */
RtlMoveMemory(&GdbPortInfo, &PortInfo, sizeof(KD_PORT_INFORMATION));
PortInfo.ComPort = DEFAULT_DEBUG_PORT;
PortInfo.BaudRate = DEFAULT_DEBUG_BAUD_RATE;
}
else if (!_strnicmp(p2, "PICE", 4) && BootPhase > 0)
{
p2 += 4;
KdDebuggerEnabled = TRUE;
KdDebugState |= KD_DEBUG_PICE;
}
else if (!_strnicmp(p2, "COM", 3) && BootPhase == 0)
{
p2 += 3;
Value = (ULONG)atol(p2);
if (Value > 0 && Value < 5)
{
KdDebugState |= KD_DEBUG_SERIAL;
LogPortInfo.ComPort = Value;
}
}
else if (!_strnicmp(p2, "FILE", 4) && BootPhase > 0)
{
p2 += 4;
KdDebugState |= KD_DEBUG_FILELOG;
}
}
}
else if (!_strnicmp(p2, "KDSERIAL", 8) && BootPhase > 0)
{
p2 += 8;
KdDebugState |= KD_DEBUG_SERIAL | KD_DEBUG_KDSERIAL;
}
else if (!_strnicmp(p2, "KDNOECHO", 8) && BootPhase > 0)
{
p2 += 8;
KdDebugState |= KD_DEBUG_KDNOECHO;
}
else if (!_strnicmp(p2, "DEBUG", 5) && BootPhase == 0)
{
p2 += 5;
KdDebuggerEnabled = TRUE;
KdDebugState |= KD_DEBUG_SERIAL;
}
else if (!_strnicmp(p2, "NODEBUG", 7) && BootPhase == 0)
{
p2 += 7;
KdDebuggerEnabled = FALSE;
KdDebugState = KD_DEBUG_DISABLED;
}
else if (!_strnicmp(p2, "CRASHDEBUG", 10) && BootPhase == 0)
{
p2 += 10;
KdDebuggerEnabled = FALSE;
KdDebugState = KD_DEBUG_DISABLED;
}
else if (!_strnicmp(p2, "BREAK", 5) && BootPhase > 0)
{
p2 += 5;
KdpBreakPending = TRUE;
}
else if (!_strnicmp(p2, "COM", 3) && BootPhase == 0)
{
p2 += 3;
if ('=' == *p2)
{
p2++;
Value = (ULONG)atol(p2);
if (0 < Value && Value < 5)
{
PortInfo.ComPort = Value;
}
}
}
else if (!_strnicmp(p2, "BAUDRATE", 8) && BootPhase == 0)
{
p2 += 8;
if ('=' == *p2)
{
p2++;
Value = (ULONG)atol(p2);
if (0 < Value)
{
PortInfo.BaudRate = Value;
}
}
}
else if (!_strnicmp(p2, "IRQ", 3) && BootPhase == 0)
{
p2 += 3;
if ('=' == *p2)
{
p2++;
Value = (ULONG)atol(p2);
if (0 < Value)
{
KdpPortIrq = Value;
}
}
}
p1 = p2;
}
/* Perform any initialization nescessary */
if (KdDebugState & KD_DEBUG_GDB && BootPhase == 0)
KdPortInitializeEx(&GdbPortInfo, 0, 0);
if (KdDebugState & KD_DEBUG_SERIAL && BootPhase == 0)
KdPortInitializeEx(&LogPortInfo, 0, 0);
if (KdDebugState & KD_DEBUG_FILELOG && BootPhase > 0)
DebugLogInit();
}
VOID INIT_FUNCTION
KdInit1(VOID)
{
/* Initialize kernel debugger (phase 0) */
if ((KdDebuggerEnabled) &&
(KdDebugState & KD_DEBUG_GDB))
{
KdGdbStubInit(0);
}
}
VOID INIT_FUNCTION
KdInit2(VOID)
{
/* Initialize kernel debugger (phase 1) */
if ((KdDebuggerEnabled) &&
(KdDebugState & KD_DEBUG_GDB))
{
KdGdbStubInit(1);
}
}
VOID INIT_FUNCTION
KdInit3(VOID)
{
/* Print some information */
if (KdDebugState & KD_DEBUG_GDB)
PrintString("\n GDB debugging enabled. COM%ld %ld Baud\n\n",
GdbPortInfo.ComPort, GdbPortInfo.BaudRate);
if (KdDebugState & KD_DEBUG_PICE)
PrintString("\n Private ICE debugger enabled\n\n");
if (KdDebugState & KD_DEBUG_SCREEN)
PrintString("\n Screen debugging enabled\n\n");
if (KdDebugState & KD_DEBUG_BOCHS)
PrintString("\n Bochs debugging enabled\n\n");
if (KdDebugState & KD_DEBUG_SERIAL)
PrintString("\n Serial debugging enabled. COM%ld %ld Baud\n\n",
LogPortInfo.ComPort, LogPortInfo.BaudRate);
if (KdDebugState & KD_DEBUG_FILELOG)
PrintString("\n File log debugging enabled\n\n");
if (KdDebugState & KD_DEBUG_MDA)
PrintString("\n MDA debugging enabled\n\n");
}
VOID
KdSerialDebugPrint (LPSTR Message)
{
PCHAR pch = (PCHAR) Message;
while (*pch != 0)
{
if (*pch == '\n')
{
KdPortPutByteEx (&LogPortInfo, '\r');
}
KdPortPutByteEx (&LogPortInfo, *pch);
pch++;
}
}
VOID
KdBochsDebugPrint(IN LPSTR Message)
{
while (*Message != 0)
{
if (*Message == '\n')
{
WRITE_PORT_UCHAR((PUCHAR)BOCHS_LOGGER_PORT, '\r');
}
WRITE_PORT_UCHAR((PUCHAR)BOCHS_LOGGER_PORT, *Message);
Message++;
}
}
ULONG
KdpPrintString(PANSI_STRING String)
{
PCH pch = String->Buffer;
if (KdDebugState & KD_DEBUG_GDB)
KdGdbDebugPrint(pch);
if (KdDebugState & KD_DEBUG_SCREEN)
HalDisplayString(pch);
if (KdDebugState & KD_DEBUG_SERIAL)
KdSerialDebugPrint(pch);
if (KdDebugState & KD_DEBUG_BOCHS)
KdBochsDebugPrint(pch);
if (KdDebugState & KD_DEBUG_FILELOG)
DebugLogWrite(pch);
return((ULONG)String->Length);
}
/* PUBLIC FUNCTIONS *********************************************************/
/* NTOSKRNL.KdPollBreakIn */
/*
* @unimplemented
*/
VOID
STDCALL
KdDisableDebugger(
VOID
)
{
UNIMPLEMENTED;
}
/*
* @unimplemented
*/
VOID
STDCALL
KdEnableDebugger (
VOID
)
{
UNIMPLEMENTED;
}
/*
* @implemented
*/
BOOLEAN STDCALL
KdPollBreakIn(VOID)
{
if ((!KdDebuggerEnabled) || (!(KdDebugState & KD_DEBUG_SERIAL)))
return FALSE;
return KdpBreakPending;
}
/*
* @implemented
*/
VOID STDCALL
KeEnterKernelDebugger(VOID)
{
HalDisplayString("\n\n *** Entered kernel debugger ***\n");
for (;;)
{
#if defined(__GNUC__)
__asm__("hlt\n\t");
#elif defined(_MSC_VER)
__asm hlt
#else
#error Unknown compiler for inline assembler
#endif
}
}
VOID STDCALL
KdSystemDebugControl(ULONG Code)
{
extern VOID STDCALL PspDumpThreads(BOOLEAN IncludeSystem);
/* A - Dump the entire contents of the non-paged pool. */
if (Code == 0)
{
MiDebugDumpNonPagedPool(FALSE);
}
/* B - Bug check the system. */
else if (Code == 1)
{
KEBUGCHECK(MANUALLY_INITIATED_CRASH);
}
/*
* C - Dump statistics about the distribution of tagged blocks in
* the non-paged pool.
*/
else if (Code == 2)
{
MiDebugDumpNonPagedPoolStats(FALSE);
}
/*
* D - Dump the blocks created in the non-paged pool since the last
* SysRq + D and SysRq + E command.
*/
else if (Code == 3)
{
MiDebugDumpNonPagedPool(TRUE);
}
/* E - Dump statistics about the tags of newly created blocks. */
else if (Code == 4)
{
MiDebugDumpNonPagedPoolStats(TRUE);
}
/* F */
else if (Code == 5)
{
PspDumpThreads(TRUE);
}
/* G */
else if (Code == 6)
{
PspDumpThreads(FALSE);
}
/* H */
else if (Code == 7)
{
}
/* I */
else if (Code == 8)
{
}
/* J */
else if (Code == 9)
{
}
/* K - Enter the system debugger. */
else if (Code == 10)
{
#ifdef KDBG
KdbEnter();
#else /* KDBG */
DbgPrint("No local kernel debugger\n");
#endif /* not KDBG */
}
}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
KdPowerTransition(
ULONG PowerState
)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* Support routines for the GDB stubs */
VOID
KdPutChar(UCHAR Value)
{
KdPortPutByteEx (&GdbPortInfo, Value);
}
UCHAR
KdGetChar(VOID)
{
UCHAR Value;
while (!KdPortGetByteEx (&GdbPortInfo, &Value));
return Value;
}
/* EOF */

View file

@ -0,0 +1,250 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/kd/kdinit.c
* PURPOSE: Kernel Debugger Initializtion
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
/* VARIABLES ***************************************************************/
KD_PORT_INFORMATION PortInfo;
ULONG KdpPortIrq;
KDP_DEBUG_MODE KdpDebugMode;
LIST_ENTRY KdProviders;
PKDP_INIT_ROUTINE WrapperInitRoutine;
KD_DISPATCH_TABLE DispatchTable[KdMax];
KD_DISPATCH_TABLE WrapperTable;
PKDP_INIT_ROUTINE InitRoutines[KdMax] = {KdpScreenInit,
KdpSerialInit,
KdpInitDebugLog};
/* PRIVATE FUNCTIONS *********************************************************/
PCHAR
STDCALL
KdpGetWrapperDebugMode(PCHAR Currentp2,
PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PCHAR p2 = Currentp2;
#ifdef BOCHS
/* Check for BOCHS Debugging */
if (!_strnicmp(p2, "BOCHS", 5))
{
/* Enable It */
p2 += 5;
KdpDebugMode.Bochs = TRUE;
WrapperInitRoutine = KdpBochsInit;
}
#endif
#ifdef GDB
/* Check for GDB Debugging */
if (!_strnicmp(p2, "GDB", 3))
{
/* Enable it */
p2 += 3;
KdpDebugMode.Gdb = TRUE;
/* Enable Debugging */
KdDebuggerEnabled = TRUE;
WrapperInitRoutine = KdpGdbStubInit;
/* Reset port information to defaults */
RtlMoveMemory(&GdbPortInfo, &PortInfo, sizeof(KD_PORT_INFORMATION));
PortInfo.ComPort = DEFAULT_DEBUG_PORT;
PortInfo.BaudRate = DEFAULT_DEBUG_BAUD_RATE;
}
#endif
#ifdef ICE
/* Check for PICE Debugging */
else if (!_strnicmp(p2, "PICE", 4))
{
/* Enable it */
p2 += 4;
KdpDebugMode.Pice = TRUE;
/* Enable Debugging */
KdDebuggerEnabled = TRUE;
}
#endif
#ifdef KDBG
/* Get the KDBG Settings and enable it */
KdDebuggerEnabled = TRUE;
KdpDebugMode.Gdb = TRUE;
KdbpGetCommandLineSettings((PCHAR)LoaderBlock->CommandLine);
#endif
return p2;
}
PCHAR
STDCALL
KdpGetDebugMode(PCHAR Currentp2)
{
PCHAR p2 = Currentp2;
ULONG Value;
/* Check for Screen Debugging */
if (!_strnicmp(p2, "SCREEN", 6))
{
/* Enable It */
p2 += 6;
KdpDebugMode.Screen = TRUE;
}
/* Check for Serial Debugging */
else if (!_strnicmp(p2, "COM", 3))
{
/* Gheck for a valid Serial Port */
p2 += 3;
Value = (ULONG)atol(p2);
if (Value > 0 && Value < 5)
{
/* Valid port found, enable Serial Debugging */
KdpDebugMode.Serial = TRUE;
/* Set the port to use */
SerialPortInfo.ComPort = Value;
KdpPort = Value;
}
}
/* Check for Debug Log Debugging */
else if (!_strnicmp(p2, "FILE", 4))
{
/* Enable It */
p2 += 4;
KdpDebugMode.File = TRUE;
}
return p2;
}
VOID
STDCALL
KdpCallInitRoutine(ULONG BootPhase)
{
PLIST_ENTRY CurrentEntry;
PKD_DISPATCH_TABLE CurrentTable;
/* Call the registered handlers */
CurrentEntry = KdProviders.Flink;
while (CurrentEntry != &KdProviders)
{
/* Get the current table */
CurrentTable = CONTAINING_RECORD(CurrentEntry,
KD_DISPATCH_TABLE,
KdProvidersList);
/* Call it */
CurrentTable->KdpInitRoutine(CurrentTable, BootPhase);
/* Next Table */
CurrentEntry = CurrentEntry->Flink;
}
/* Call the Wrapper Init Routine */
if (WrapperInitRoutine)
WrapperTable.KdpInitRoutine(&WrapperTable, BootPhase);
}
VOID
INIT_FUNCTION
KdInitSystem(ULONG BootPhase,
PLOADER_PARAMETER_BLOCK LoaderBlock)
{
ULONG Value;
ULONG i;
PCHAR p1, p2;
/* Set Default Port Options */
if (BootPhase == 0)
{
/* Initialize the Provider List */
InitializeListHead(&KdProviders);
/* Parse the Command Line */
p1 = (PCHAR)LoaderBlock->CommandLine;
while (p1 && (p2 = strchr(p1, '/')))
{
/* Move past the slash */
p2++;
/* Identify the Debug Type being Used */
if (!_strnicmp(p2, "DEBUGPORT=", 10))
{
p2 += 10;
p2 = KdpGetDebugMode(p2);
p2 = KdpGetWrapperDebugMode(p2, LoaderBlock);
}
/* Check for Kernel Debugging Enable */
else if (!_strnicmp(p2, "DEBUG", 5))
{
/* Enable it on the Serial Port */
p2 += 5;
KdDebuggerEnabled = TRUE;
KdpDebugMode.Serial = TRUE;
}
/* Check for Kernel Debugging Bypass */
else if (!_strnicmp(p2, "NODEBUG", 7))
{
/* Disable Debugging */
p2 += 7;
KdDebuggerEnabled = FALSE;
}
/* Check for Kernel Debugging Bypass unless STOP Error */
else if (!_strnicmp(p2, "CRASHDEBUG", 10))
{
/* Disable Debugging */
p2 += 10;
KdDebuggerEnabled = FALSE;
}
/* Check Serial Port Settings [Baud Rate] */
else if (!_strnicmp(p2, "BAUDRATE=", 9))
{
/* Get the Baud Rate */
p2 += 9;
Value = (ULONG)atol(p2);
/* Check if it's valid and Set it */
if (0 < Value) PortInfo.BaudRate = Value;
}
/* Check Serial Port Settings [IRQ] */
else if (!_strnicmp(p2, "IRQ=", 4))
{
/* Get the IRQ */
p2 += 3;
Value = (ULONG)atol(p2);
/* Check if it's valid and set it */
if (0 < Value) KdpPortIrq = Value;
}
/* Move to next */
p1 = p2;
}
/* Call Providers at Phase 0 */
for (i = 0; i < KdMax; i++)
{
InitRoutines[i](&DispatchTable[i], 0);
}
/* Call Wrapper at Phase 0 */
if (WrapperInitRoutine) WrapperInitRoutine(&WrapperTable, 0);
return;
}
/* Call the Initialization Routines of the Registered Providers */
KdpCallInitRoutine(BootPhase);
}
/* EOF */

272
reactos/ntoskrnl/kd/kdio.c Normal file
View file

@ -0,0 +1,272 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/kd/kdio.c
* PURPOSE: NT Kernel Debugger Input/Output Functions
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#include <internal/debug.h>
/* GLOBALS *******************************************************************/
#define BufferSize 32*1024
HANDLE KdbLogFileHandle;
BOOLEAN KdpLogInitialized;
CHAR DebugBuffer[BufferSize];
ULONG CurrentPosition;
WORK_QUEUE_ITEM KdpDebugLogQueue;
BOOLEAN ItemQueued;
KD_PORT_INFORMATION SerialPortInfo;
/* Current Port in use. FIXME: Do we support more then one? */
ULONG KdpPort;
/* DEBUG LOG FUNCTIONS *******************************************************/
VOID
STDCALL
KdpPrintToLogInternal(PVOID Context)
{
IO_STATUS_BLOCK Iosb;
/* Write to the Debug Log */
NtWriteFile(KdbLogFileHandle,
NULL,
NULL,
NULL,
&Iosb,
DebugBuffer,
CurrentPosition,
NULL,
NULL);
/* Clear the Current Position */
CurrentPosition = 0;
/* A new item can be queued now */
ItemQueued = FALSE;
}
VOID
STDCALL
KdpPrintToLog(PCH String)
{
ULONG StringLength = strlen(String);
/* Don't overflow */
if ((CurrentPosition + StringLength) > BufferSize) return;
/* Add the string to the buffer */
RtlMoveMemory(&DebugBuffer[CurrentPosition], String, StringLength);
/* Update the Current Position */
CurrentPosition += StringLength;
/* Make sure we are initialized and can queue */
if (!KdpLogInitialized || (ItemQueued)) return;
/* Queue the work item */
ExQueueWorkItem(&KdpDebugLogQueue, HyperCriticalWorkQueue);
ItemQueued = TRUE;
}
VOID
STDCALL
KdpInitDebugLog(PKD_DISPATCH_TABLE DispatchTable,
ULONG BootPhase)
{
if (!KdpDebugMode.File) return;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING FileName;
IO_STATUS_BLOCK Iosb;
if (BootPhase == 0)
{
/* Write out the functions that we support for now */
DispatchTable->KdpInitRoutine = KdpInitDebugLog;
DispatchTable->KdpPrintRoutine = KdpPrintToLog;
/* Register as a Provider */
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
}
else if (BootPhase == 2)
{
HalDisplayString("\n File log debugging enabled\n\n");
}
else if (BootPhase == 3)
{
/* Setup the Log Name */
RtlInitUnicodeString(&FileName, L"\\SystemRoot\\debug.log");
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
0,
NULL,
NULL);
/* Create the Log File */
Status = NtCreateFile(&KdbLogFileHandle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&Iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_SUPERSEDE,
FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
/* Allow it to be used */
ExInitializeWorkItem(&KdpDebugLogQueue, &KdpPrintToLogInternal, NULL);
KdpLogInitialized = TRUE;
}
}
/* SERIAL FUNCTIONS **********************************************************/
VOID
STDCALL
KdpSerialDebugPrint(LPSTR Message)
{
PCHAR pch = (PCHAR) Message;
while (*pch != 0)
{
if (*pch == '\n')
{
KdPortPutByteEx(&SerialPortInfo, '\r');
}
KdPortPutByteEx(&SerialPortInfo, *pch);
pch++;
}
}
VOID
STDCALL
KdpSerialInit(PKD_DISPATCH_TABLE DispatchTable,
ULONG BootPhase)
{
if (!KdpDebugMode.Serial) return;
if (BootPhase == 0)
{
/* Write out the functions that we support for now */
DispatchTable->KdpInitRoutine = KdpSerialInit;
DispatchTable->KdpPrintRoutine = KdpSerialDebugPrint;
/* Initialize the Port */
KdPortInitializeEx(&SerialPortInfo, 0, 0);
/* Register as a Provider */
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
}
else if (BootPhase == 2)
{
HalDisplayString("\n Serial debugging enabled\n\n");
}
}
/* SCREEN FUNCTIONS **********************************************************/
VOID
STDCALL
KdpScreenInit(PKD_DISPATCH_TABLE DispatchTable,
ULONG BootPhase)
{
if (!KdpDebugMode.Screen) return;
if (BootPhase == 0)
{
/* Write out the functions that we support for now */
DispatchTable->KdpInitRoutine = KdpScreenInit;
DispatchTable->KdpPrintRoutine = HalDisplayString;
/* Register as a Provider */
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
}
else if (BootPhase == 2)
{
HalDisplayString("\n Screen debugging enabled\n\n");
}
}
/* GENERAL FUNCTIONS *********************************************************/
BOOLEAN
STDCALL
KdpDetectConflicts(PCM_RESOURCE_LIST DriverList)
{
ULONG ComPortBase = 0;
ULONG i;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
/* Select the COM Port Base */
switch (KdpPort)
{
case 1: ComPortBase = 0x3f8; break;
case 2: ComPortBase = 0x2f8; break;
case 3: ComPortBase = 0x3e8; break;
case 4: ComPortBase = 0x2e8; break;
}
/* search for this port address in DriverList */
for (i = 0; i < DriverList->List[0].PartialResourceList.Count; i++)
{
ResourceDescriptor = &DriverList->List[0].PartialResourceList.PartialDescriptors[i];
if (ResourceDescriptor->Type == CmResourceTypePort)
{
if ((ResourceDescriptor->u.Port.Start.u.LowPart <= ComPortBase) &&
(ResourceDescriptor->u.Port.Start.u.LowPart +
ResourceDescriptor->u.Port.Length > ComPortBase))
{
/* Conflict found */
return TRUE;
}
}
}
/* No Conflicts */
return FALSE;
}
ULONG
STDCALL
KdpPrintString(PANSI_STRING String)
{
if (!KdpDebugMode.Value) return 0;
PCH pch = String->Buffer;
PLIST_ENTRY CurrentEntry;
PKD_DISPATCH_TABLE CurrentTable;
/* Call the registered handlers */
CurrentEntry = KdProviders.Flink;
while (CurrentEntry != &KdProviders)
{
/* Get the current table */
CurrentTable = CONTAINING_RECORD(CurrentEntry,
KD_DISPATCH_TABLE,
KdProvidersList);
/* Call it */
CurrentTable->KdpPrintRoutine(pch);
/* Next Table */
CurrentEntry = CurrentEntry->Flink;
}
/* Call the Wrapper Routine */
if (WrapperInitRoutine) WrapperTable.KdpPrintRoutine(pch);
/* Return the Length */
return((ULONG)String->Length);
}
/* EOF */

View file

@ -0,0 +1,205 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/kd/kdinit.c
* PURPOSE: Kernel Debugger Initializtion
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
/* VARIABLES ***************************************************************/
BOOLEAN EXPORTED KdDebuggerEnabled = FALSE;
BOOLEAN EXPORTED KdEnteredDebugger = FALSE;
BOOLEAN EXPORTED KdDebuggerNotPresent = TRUE;
BOOLEAN EXPORTED KiEnableTimerWatchdog = FALSE;
ULONG EXPORTED KiBugCheckData;
BOOLEAN KdpBreakPending;
VOID STDCALL PspDumpThreads(BOOLEAN SystemThreads);
/* PRIVATE FUNCTIONS *********************************************************/
ULONG
STDCALL
KdpServiceDispatcher(ULONG Service,
PVOID Context1,
PVOID Context2)
{
ULONG Result = 0;
switch (Service)
{
case 1: /* DbgPrint */
Result = KdpPrintString ((PANSI_STRING)Context1);
break;
case TAG('R', 'o', 's', ' '): /* ROS-INTERNAL */
{
switch ((ULONG)Context1)
{
case DumpNonPagedPool:
MiDebugDumpNonPagedPool(FALSE);
break;
case ManualBugCheck:
KEBUGCHECK(MANUALLY_INITIATED_CRASH);
break;
case DumpNonPagedPoolStats:
MiDebugDumpNonPagedPoolStats(FALSE);
break;
case DumpNewNonPagedPool:
MiDebugDumpNonPagedPool(TRUE);
break;
case DumpNewNonPagedPoolStats:
MiDebugDumpNonPagedPoolStats(TRUE);
break;
case DumpAllThreads:
PspDumpThreads(TRUE);
break;
case DumpUserThreads:
PspDumpThreads(FALSE);
break;
case EnterDebugger:
DbgBreakPoint();
break;
default:
break;
}
}
default:
HalDisplayString ("Invalid debug service call!\n");
break;
}
return Result;
}
KD_CONTINUE_TYPE
STDCALL
KdpEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
KPROCESSOR_MODE PreviousMode,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame,
BOOLEAN FirstChance,
BOOLEAN Gdb)
{
/* Get out of here if the Debugger isn't enabled */
if (!KdDebuggerEnabled) return kdHandleException;
/* FIXME:
* Right now, the GDB wrapper seems to handle exceptions differntly
* from KDGB and both are called at different times, while the GDB
* one is only called once and that's it. I don't really have the knowledge
* to fix the GDB stub, so until then, we'll be using this hack
*/
if (Gdb)
{
/* Call the registered wrapper */
if (WrapperInitRoutine) return WrapperTable.
KdpExceptionRoutine(ExceptionRecord,
Context,
TrapFrame);
}
/* Call KDBG if available */
return KdbEnterDebuggerException(ExceptionRecord,
PreviousMode,
Context,
TrapFrame,
FirstChance);
}
/* PUBLIC FUNCTIONS *********************************************************/
/*
* @implemented
*/
VOID
STDCALL
KdDisableDebugger(VOID)
{
KIRQL OldIrql;
/* Raise IRQL */
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
/* TODO: Disable any breakpoints */
/* Disable the Debugger */
KdDebuggerEnabled = FALSE;
/* Lower the IRQL */
KeLowerIrql(OldIrql);
}
/*
* @implemented
*/
VOID
STDCALL
KdEnableDebugger(VOID)
{
KIRQL OldIrql;
/* Raise IRQL */
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
/* TODO: Re-enable any breakpoints */
/* Enable the Debugger */
KdDebuggerEnabled = TRUE;
/* Lower the IRQL */
KeLowerIrql(OldIrql);
}
/*
* @implemented
*/
BOOLEAN
STDCALL
KdPollBreakIn(VOID)
{
return KdpBreakPending;
}
/*
* @implemented
*/
VOID
STDCALL
KeEnterKernelDebugger(VOID)
{
HalDisplayString("\n\n *** Entered kernel debugger ***\n");
/* Set the Variable */
KdEnteredDebugger = TRUE;
/* Halt the CPU */
for (;;) Ke386HaltProcessor();
}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
KdPowerTransition(ULONG PowerState)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* EOF */

View file

@ -1,5 +1,4 @@
/* $Id$
*
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/kd/service.c
@ -13,35 +12,6 @@
/* FUNCTIONS ***************************************************************/
/*
* Note: DON'T CHANGE THIS FUNCTION!!!
* DON'T CALL HalDisplayString OR SOMETING ELSE!!!
* You'll only break the serial/bochs debugging feature!!!
*/
ULONG
KdpServiceDispatcher (
ULONG Service,
PVOID Context1,
PVOID Context2)
{
ULONG Result = 0;
switch (Service)
{
case 1: /* DbgPrint */
Result = KdpPrintString ((PANSI_STRING)Context1);
break;
default:
HalDisplayString ("Invalid debug service call!\n");
break;
}
return Result;
}
#define _STR(x) #x
#define STR(x) _STR(x)
@ -95,8 +65,7 @@ void interrupt_handler2d(void);
"pushl %edx\n\t"
"pushl %ecx\n\t"
"pushl %eax\n\t"
"call _KdpServiceDispatcher\n\t"
"addl $12,%esp\n\t" /* restore stack pointer */
"call _KdpServiceDispatcher@12\n\t"
/* Restore the user context */
"addl $4,%esp\n\t" /* UserContext */

View file

@ -0,0 +1,53 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/kd/wrappers/bochs.c
* PURPOSE: BOCHS Wrapper for Kd
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
/* bochs debug output */
#define BOCHS_LOGGER_PORT (0xe9)
/* FUNCTIONS *****************************************************************/
VOID
STDCALL
KdpBochsDebugPrint(IN PCH Message)
{
while (*Message != 0)
{
if (*Message == '\n')
{
WRITE_PORT_UCHAR((PUCHAR)BOCHS_LOGGER_PORT, '\r');
}
WRITE_PORT_UCHAR((PUCHAR)BOCHS_LOGGER_PORT, *Message);
Message++;
}
}
VOID
STDCALL
KdpBochsInit(PKD_DISPATCH_TABLE WrapperTable,
ULONG BootPhase)
{
if (!KdDebuggerEnabled || !KdpDebugMode.Bochs) return;
if (BootPhase == 0)
{
/* Write out the functions that we support for now */
WrapperTable->KdpInitRoutine = KdpBochsInit;
WrapperTable->KdpPrintRoutine = KdpBochsDebugPrint;
}
else if (BootPhase == 2)
{
HalDisplayString("\n Bochs debugging enabled\n\n");
}
}
/* EOF */

View file

@ -107,6 +107,7 @@ static PETHREAD GspDbgThread;
static PETHREAD GspEnumThread;
extern LIST_ENTRY PsActiveProcessHead;
KD_PORT_INFORMATION GdbPortInfo;
/* Number of Registers. */
#define NUMREGS 16
@ -238,6 +239,22 @@ HexValue (CHAR ch)
static CHAR GspInBuffer[BUFMAX];
static CHAR GspOutBuffer[BUFMAX];
VOID
GdbPutChar(UCHAR Value)
{
KdPortPutByteEx (&GdbPortInfo, Value);
}
UCHAR
GdbGetChar(VOID)
{
UCHAR Value;
while (!KdPortGetByteEx (&GdbPortInfo, &Value));
return Value;
}
/* scan for the sequence $<data>#<Checksum> */
PCHAR
@ -252,7 +269,7 @@ GspGetPacket()
while (TRUE)
{
/* wait around for the start character, ignore all other characters */
while ((ch = KdGetChar ()) != '$');
while ((ch = GdbGetChar ()) != '$');
retry:
Checksum = 0;
@ -262,7 +279,7 @@ GspGetPacket()
/* now, read until a # or end of Buffer is found */
while (Count < BUFMAX)
{
ch = KdGetChar ();
ch = GdbGetChar ();
if (ch == '$')
goto retry;
if (ch == '#')
@ -275,24 +292,24 @@ GspGetPacket()
if (ch == '#')
{
ch = KdGetChar ();
ch = GdbGetChar ();
XmitChecksum = (CHAR)(HexValue (ch) << 4);
ch = KdGetChar ();
ch = GdbGetChar ();
XmitChecksum += (CHAR)(HexValue (ch));
if (Checksum != XmitChecksum)
{
KdPutChar ('-'); /* failed checksum */
GdbPutChar ('-'); /* failed checksum */
}
else
{
KdPutChar ('+'); /* successful transfer */
GdbPutChar ('+'); /* successful transfer */
/* if a sequence char is present, reply the sequence ID */
if (Buffer[2] == ':')
{
KdPutChar (Buffer[0]);
KdPutChar (Buffer[1]);
GdbPutChar (Buffer[0]);
GdbPutChar (Buffer[1]);
return &Buffer[3];
}
@ -315,22 +332,22 @@ GspPutPacket (PCHAR Buffer)
/* $<packet info>#<Checksum>. */
do
{
KdPutChar ('$');
GdbPutChar ('$');
Checksum = 0;
Count = 0;
while ((ch = Buffer[Count]))
{
KdPutChar (ch);
GdbPutChar (ch);
Checksum += ch;
Count += 1;
}
KdPutChar ('#');
KdPutChar (HexChars[(Checksum >> 4) & 0xf]);
KdPutChar (HexChars[Checksum & 0xf]);
GdbPutChar ('#');
GdbPutChar (HexChars[(Checksum >> 4) & 0xf]);
GdbPutChar (HexChars[Checksum & 0xf]);
}
while (KdGetChar () != '+');
while (GdbGetChar () != '+');
}
@ -342,20 +359,20 @@ GspPutPacketNoWait (PCHAR Buffer)
CHAR ch;
/* $<packet info>#<Checksum>. */
KdPutChar ('$');
GdbPutChar ('$');
Checksum = 0;
Count = 0;
while ((ch = Buffer[Count]))
{
KdPutChar (ch);
GdbPutChar (ch);
Checksum += ch;
Count += 1;
}
KdPutChar ('#');
KdPutChar (HexChars[(Checksum >> 4) & 0xf]);
KdPutChar (HexChars[Checksum & 0xf]);
GdbPutChar ('#');
GdbPutChar (HexChars[(Checksum >> 4) & 0xf]);
GdbPutChar (HexChars[Checksum & 0xf]);
}
/* Indicate to caller of GspMem2Hex or GspHex2Mem that there has been an
@ -1109,9 +1126,10 @@ GspSetHwBreakpoint(ULONG BreakpointNumber,
* This function does all command procesing for interfacing to gdb.
*/
KD_CONTINUE_TYPE
KdEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame)
STDCALL
KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame)
{
BOOLEAN Stepping;
LONG Address;
@ -1457,7 +1475,7 @@ GspBreakIn(PKINTERRUPT Interrupt,
KeTrapFrameToContext (TrapFrame, &Context);
KdEnterDebuggerException (NULL, &Context, TrapFrame);
KdpGdbEnterDebuggerException (NULL, &Context, TrapFrame);
KeContextToTrapFrame (&Context, TrapFrame);
@ -1469,72 +1487,10 @@ GspBreakIn(PKINTERRUPT Interrupt,
extern ULONG KdpPortIrq;
/* Initialize the GDB stub */
VOID INIT_FUNCTION
KdGdbStubInit(ULONG Phase)
{
#if 0
KAFFINITY Affinity;
NTSTATUS Status;
ULONG MappedIrq;
KIRQL Dirql;
#endif
if (Phase == 0)
{
GspInitialized = TRUE;
GspRunThread = PsGetCurrentThread();
ObReferenceObject(GspRunThread);
/* GspDbgThread = PsGetCurrentThread(); */
GspDbgThread = NULL;
GspEnumThread = NULL;
HalDisplayString("Waiting for GDB to attach\n");
DbgPrint("Module 'hal.dll' loaded at 0x%.08x.\n", LdrHalBase);
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
}
else if (Phase == 1)
{
#if 0
/* Hook an interrupt handler to allow the debugger to break into
the system */
MappedIrq = HalGetInterruptVector (Internal,
0,
0,
KdpPortIrq,
&Dirql,
&Affinity);
Status = IoConnectInterrupt(&GspInterrupt,
GspBreakIn,
NULL,
NULL,
MappedIrq,
Dirql,
Dirql,
0,
FALSE,
Affinity,
FALSE);
if (!NT_SUCCESS (Status))
{
DPRINT1("Could not connect to IRQ line %d (0x%x)\n",
KdpPortIrq, Status);
return;
}
KdPortEnableInterrupts();
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
#endif
}
}
VOID
KdGdbDebugPrint(LPSTR Message)
STDCALL
KdpGdbDebugPrint(PCH Message)
{
#if 0
/* This can be quite annoying! */
@ -1581,3 +1537,44 @@ KdGdbListModules()
DbgPrint ("%d modules listed\n", ModuleCount);
}
/* Initialize the GDB stub */
VOID
STDCALL
KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable,
ULONG BootPhase)
{
if (!KdDebuggerEnabled || !KdpDebugMode.Gdb) return;
if (BootPhase == 0)
{
/* Initialize the Port */
KdPortInitializeEx(&GdbPortInfo, 0, 0);
}
else if (BootPhase == 1)
{
GspInitialized = TRUE;
GspRunThread = PsGetCurrentThread();
ObReferenceObject(GspRunThread);
GspDbgThread = NULL;
GspEnumThread = NULL;
/* Write out the functions that we support for now */
WrapperTable->KdpInitRoutine = KdpGdbStubInit;
WrapperTable->KdpPrintRoutine = KdpGdbDebugPrint;
WrapperTable->KdpExceptionRoutine = KdpGdbEnterDebuggerException;
HalDisplayString("Waiting for GDB to attach\n");
DbgPrint("Module 'hal.dll' loaded at 0x%.08x.\n", LdrHalBase);
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
}
else if (BootPhase == 2)
{
HalDisplayString("\n GDB debugging enabled\n\n");
}
}
/* EOF */

View file

@ -1,17 +1,15 @@
/* $Id$
*
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/kdb.c
* PURPOSE: Kernel debugger
* FILE: ntoskrnl/kdbg/kdb.c
* PURPOSE: Kernel Debugger
*
* PROGRAMMERS: David Welch (welch@mcmail.com)
* PROGRAMMERS: Gregor Anich
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#include <internal/kdb.h>
#define NDEBUG
#include <internal/debug.h>
@ -43,7 +41,7 @@ STATIC PKDB_BREAKPOINT KdbBreakPointToReenable = NULL; /* Set to a breakpoint st
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. */
ULONG KdbDebugState = 0; /* KDBG Settings (NOECHO, KDSERIAL) */
STATIC BOOLEAN KdbEnteredOnSingleStep = FALSE; /* Set to true when KDB was entered because of single step */
PEPROCESS KdbCurrentProcess = NULL; /* The current process context in which KDB runs */
PEPROCESS KdbOriginalProcess = NULL; /* The process in whichs context KDB was intered */
@ -1084,7 +1082,7 @@ KdbpInternalEnter()
ULONG SavedStackLimit;
KbdDisableMouse();
if (KdDebugState & KD_DEBUG_SCREEN)
if (KdpDebugMode.Screen)
{
HalReleaseDisplayOwnership();
}
@ -1483,12 +1481,6 @@ continue_execution:
return ContinueType;
}
VOID
KdbInit()
{
KdbpCliInit();
}
VOID
KdbDeleteProcessHook(IN PEPROCESS Process)
{
@ -1498,9 +1490,27 @@ KdbDeleteProcessHook(IN PEPROCESS Process)
}
VOID
KdbModuleLoaded(IN PUNICODE_STRING Name)
STDCALL
KdbpGetCommandLineSettings(PCHAR p1)
{
KdbpCliModuleLoaded(Name);
PCHAR p2;
while (p1 && (p2 = strchr(p1, '/')))
{
p2++;
if (!_strnicmp(p2, "KDSERIAL", 8))
{
p2 += 8;
KdbDebugState |= KD_DEBUG_KDSERIAL;
KdpDebugMode.Serial = TRUE;
}
else if (!_strnicmp(p2, "KDNOECHO", 8))
{
p2 += 8;
KdbDebugState |= KD_DEBUG_KDNOECHO;
}
p1 = p2;
}
}

View file

@ -1734,7 +1734,7 @@ KdbpPrint(
if ((KdbNumberOfRowsTerminal < 0) || (KdbNumberOfColsTerminal < 0) ||
(KdbNumberOfRowsPrinted) == 0) /* Refresh terminal size each time when number of rows printed is 0 */
{
if ((KdDebugState & KD_DEBUG_KDSERIAL) && TerminalReportsSize)
if ((KdbDebugState & KD_DEBUG_KDSERIAL) && TerminalReportsSize)
{
/* Try to query number of rows from terminal. A reply looks like "\x1b[8;24;80t" */
TerminalReportsSize = FALSE;
@ -1813,7 +1813,7 @@ KdbpPrint(
if (KdbNumberOfColsPrinted > 0)
DbgPrint("\n");
DbgPrint("--- Press q to abort, any other key to continue ---");
if (KdDebugState & KD_DEBUG_KDSERIAL)
if (KdbDebugState & KD_DEBUG_KDSERIAL)
c = KdbpGetCharSerial();
else
c = KdbpGetCharKeyboard(&ScanCode);
@ -1822,7 +1822,7 @@ KdbpPrint(
/* Try to read '\n' which might follow '\r' - if \n is not received here
* it will be interpreted as "return" when the next command should be read.
*/
if (KdDebugState & KD_DEBUG_KDSERIAL)
if (KdbDebugState & KD_DEBUG_KDSERIAL)
c = KdbpTryGetCharSerial(5);
else
c = KdbpTryGetCharKeyboard(&ScanCode, 5);
@ -1975,11 +1975,11 @@ KdbpReadCommand(
INT CmdHistIndex = -1;
INT i;
EchoOn = !((KdDebugState & KD_DEBUG_KDNOECHO) != 0);
EchoOn = !((KdbDebugState & KD_DEBUG_KDNOECHO) != 0);
for (;;)
{
if (KdDebugState & KD_DEBUG_KDSERIAL)
if (KdbDebugState & KD_DEBUG_KDSERIAL)
{
Key = (NextKey == '\0') ? KdbpGetCharSerial() : NextKey;
NextKey = '\0';
@ -2025,7 +2025,7 @@ KdbpReadCommand(
/* Read the next char - this is to throw away a \n which most clients should
* send after \r.
*/
if (KdDebugState & KD_DEBUG_KDSERIAL)
if (KdbDebugState & KD_DEBUG_KDSERIAL)
NextKey = KdbpTryGetCharSerial(5);
else
NextKey = KdbpTryGetCharKeyboard(&ScanCode, 5);
@ -2213,7 +2213,7 @@ KdbpCliMainLoop(
}
/* Flush the input buffer */
if (KdDebugState & KD_DEBUG_KDSERIAL)
if (KdbDebugState & KD_DEBUG_KDSERIAL)
{
while (KdbpTryGetCharSerial(1) != -1);
}

View file

@ -16,18 +16,15 @@
#define NDEBUG
#include <debug.h>
extern KD_PORT_INFORMATION LogPortInfo;
CHAR
KdbpTryGetCharSerial(UINT Retry)
{
CHAR Result = -1;
if (Retry == 0)
while (!KdPortGetByteEx(&LogPortInfo, (PUCHAR)&Result));
while (!KdPortGetByteEx(&SerialPortInfo, (PUCHAR)&Result));
else
while (!KdPortGetByteEx(&LogPortInfo, (PUCHAR)&Result) && Retry-- > 0);
while (!KdPortGetByteEx(&SerialPortInfo, (PUCHAR)&Result) && Retry-- > 0);
return Result;
}

View file

@ -427,10 +427,8 @@ KdbpSymLoadModuleSymbols(IN PUNICODE_STRING FileName,
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
#ifdef KDBG
/* Allow KDB to break on module load */
KdbModuleLoaded(FileName);
#endif
/* Try to find cached (already loaded) symbol file */
*RosSymInfo = KdbpSymFindCachedFile(FileName);

View file

@ -300,7 +300,7 @@ KeBugCheckWithTf(ULONG BugCheckCode,
/* Make sure we're switching back to the blue screen and print messages on it */
HalReleaseDisplayOwnership();
if (0 == (KdDebugState & KD_DEBUG_GDB)) KdDebugState |= KD_DEBUG_SCREEN;
if (KdpDebugMode.Gdb) KdpDebugMode.Screen = TRUE;
/* Try to find out who did this. For this, we need a Trap Frame.
* Note: Some special BSODs pass the Frame/EIP as a Param. MSDN has the
@ -338,9 +338,6 @@ KeBugCheckWithTf(ULONG BugCheckCode,
Ke386DisableInterrupts();
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
/* Disable Interrupts, Dump Debug Messages */
DebugLogDumpMessages();
/* Unload the Kernel Adress Space if we own it */
if (MmGetKernelAddressSpace()->Lock.Owner == KeGetCurrentThread())
MmUnlockAddressSpace(MmGetKernelAddressSpace());

View file

@ -59,14 +59,12 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
if (!Context)
{
/* Assume Full context */
TContext.ContextFlags = CONTEXT_FULL;
/* Check the mode */
if (PreviousMode == UserMode)
{
/* Add Debugger Registers if this is User Mode */
TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER;
}
@ -78,53 +76,42 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
Context = &TContext;
}
#if 0 /* FIXME: Isn't this right? With a break after? */
if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
{
Context->Eip--;
}
#endif
/* Break into Debugger */
Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
Context,
Tf,
TRUE,
TRUE);
/* Check if a Debugger is enabled */
if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB)
{
/* Break into it */
Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
}
/* If the debugger said continue, then continue */
if (Action == kdContinue) return;
/* If the Debugger couldn't handle it... */
if (Action != kdDoNotHandleException)
{
{
/* See what kind of Exception this is */
if (PreviousMode == UserMode)
{
{
/* User mode exception, search the frames if we have to */
if (SearchFrames)
{
PULONG Stack;
ULONG CDest;
char temp_space[12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)]; /* FIXME: HACKHACK */
PULONG pNewUserStack = (PULONG)(Tf->Esp - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
NTSTATUS StatusOfCopy;
#ifdef KDBG
/* Enter KDB if available */
Action = KdbEnterDebuggerException(ExceptionRecord,
/* Enter Debugger if available */
Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
Context,
Tf,
TRUE);
TRUE,
FALSE);
/* Exit if we're continuing */
if (Action == kdContinue) return;
#endif
/* FIXME: Forward exception to user mode debugger */
@ -150,14 +137,11 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
/* Check for success */
if (NT_SUCCESS(StatusOfCopy))
{
/* Set new Stack Pointer */
Tf->Esp = (ULONG)pNewUserStack;
}
else
{
{
/*
* Now it really hit the ventilation device. Sorry,
* can do nothing but kill the sucker.
@ -165,7 +149,6 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
DPRINT1("User-mode stack was invalid. Terminating target thread\n");
}
/* Set EIP to the User-mode Dispathcer */
Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
return;
@ -175,38 +158,35 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
/* FIXME: Forward the exception to the process exception port */
#ifdef KDBG
/* Enter KDB if available */
Action = KdbEnterDebuggerException(ExceptionRecord,
Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
Context,
Tf,
FALSE,
FALSE);
/* Exit if we're continuing */
if (Action == kdContinue) return;
#endif
/* Terminate the offending thread */
DPRINT1("Unhandled UserMode exception, terminating thread\n");
ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
}
else
{
/* This is Kernel Mode */
#ifdef KDBG
/* Enter KDB if available */
Action = KdbEnterDebuggerException(ExceptionRecord,
Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
Context,
Tf,
TRUE);
TRUE,
FALSE);
/* Exit if we're continuing */
if (Action == kdContinue) return;
#endif
/* Dispatch the Exception */
Value = RtlpDispatchException (ExceptionRecord, Context);
@ -216,19 +196,19 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
if (Value != ExceptionContinueExecution ||
0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))
{
DPRINT("ExceptionRecord->ExceptionAddress = 0x%x\n", ExceptionRecord->ExceptionAddress);
#ifdef KDBG
/* Enter KDB if available */
Action = KdbEnterDebuggerException(ExceptionRecord,
Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
Context,
Tf,
FALSE,
FALSE);
/* Exit if we're continuing */
if (Action == kdContinue) return;
#endif
KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED,
ExceptionRecord->ExceptionCode,
(ULONG)ExceptionRecord->ExceptionAddress,

View file

@ -106,15 +106,8 @@ NTSTATUS ExceptionToNtStatus[] =
/* FUNCTIONS ****************************************************************/
#if defined(DBG) || defined(KDBG)
BOOLEAN STDCALL
KeRosPrintAddress(PVOID address)
{
return KdbSymPrintAddress(address);
}
#else /* KDBG */
BOOLEAN STDCALL
KeRosPrintAddress(PVOID address)
KiRosPrintAddress(PVOID address)
{
PLIST_ENTRY current_entry;
MODULE_TEXT_SECTION* current;
@ -147,7 +140,6 @@ KeRosPrintAddress(PVOID address)
return(FALSE);
}
#endif /* KDBG */
ULONG
KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)

View file

@ -19,10 +19,6 @@
/* INCLUDES ****************************************************************/
#include <ntoskrnl.h>
#if defined(KDBG) || defined(DBG)
#include <internal/kdb.h>
#endif /* KDBG */
#include <../hal/halx86/include/halirq.h>
#define NDEBUG

View file

@ -96,7 +96,7 @@ _KiSystemService:
pushl %gs // + 0x48
sub $0x28, %esp // + 0x70
#ifdef DBG
#ifdef GDB
/* Trick gdb 6 into backtracing over the system call */
mov 0x6c(%esp), %ebx
pushl 4(%ebx) /* DebugEIP */ // + 0x74
@ -123,7 +123,7 @@ _KiSystemService:
CheckValidCall:
#ifdef DBG
#ifdef GDB
/*
* GDB thinks the function starts here and
* wants a standard prolog, so let's give it

View file

@ -979,11 +979,8 @@ LdrPEProcessModule(
DPRINT("Loading Module %wZ...\n", FileName);
if (KdDebuggerEnabled && (KdDebugState & KD_DEBUG_GDB))
{
DPRINT("Module %wZ loaded at 0x%.08x.\n",
DPRINT("Module %wZ loaded at 0x%.08x.\n",
FileName, CreatedModuleObject->Base);
}
return STATUS_SUCCESS;
}

View file

@ -244,9 +244,9 @@ RPoolRemoveFree ( PR_POOL pool, PR_FREE Item )
ASSERT ( pool->FirstFree == Item );
pool->FirstFree = Item->NextFree;
}
#if defined(DBG) || defined(KDBG)
#ifdef DBG
Item->NextFree = Item->PrevFree = (PR_FREE)(ULONG_PTR)0xDEADBEEF;
#endif//DBG || KDBG
#endif//DBG
}
static void
@ -280,9 +280,9 @@ RFreeInit ( void* memory )
#endif//R_FREEMAGIC
block->Status = 0;
RFreeFillStack ( block );
#if defined(DBG) || defined(KDBG)
#ifdef DBG
block->PrevFree = block->NextFree = (PR_FREE)(ULONG_PTR)0xDEADBEEF;
#endif//DBG || KDBG
#endif//DBG
return block;
}
@ -643,7 +643,7 @@ RiUsedInit ( PR_USED Block, rulong Tag )
//ASSERT_SIZE ( Block->Size );
// now add the block to the used block list
#if defined(DBG) || defined(KDBG)
#ifdef DBG
Block->NextUsed = (PR_USED)(ULONG_PTR)0xDEADBEEF;
#endif//R_USED_LIST
@ -661,9 +661,9 @@ RiUsedInitRedZone ( PR_USED Block, rulong UserSize )
Block->UserSize = UserSize;
memset ( Addr - R_RZ, R_RZ_LOVALUE, R_RZ );
memset ( Addr + Block->UserSize, R_RZ_HIVALUE, R_RZ );
#if defined(DBG) || defined(KDBG)
#ifdef DBG
memset ( Addr, 0xCD, UserSize );
#endif//DBG || KDBG
#endif//DBG
}
#endif//R_RZ

View file

@ -189,8 +189,7 @@ MmLocateMemoryAreaByAddress(
DPRINT("MmLocateMemoryAreaByAddress(AddressSpace %p, Address %p)\n",
AddressSpace, Address);
if (!(KdDebugState & KD_DEBUG_SCREEN))
MmVerifyMemoryAreas(AddressSpace);
MmVerifyMemoryAreas(AddressSpace);
while (Node != NULL)
{

View file

@ -503,7 +503,7 @@ KdEnableDebugger@0
KdEnteredDebugger
KdPollBreakIn@0
KdPowerTransition@4
KdSystemDebugControl@4
KdpServiceDispatcher@12
Ke386CallBios@8
Ke386IoSetAccessProcess@8
Ke386QueryIoAccessMap@8
@ -944,7 +944,7 @@ READ_REGISTER_USHORT@4
READ_REGISTER_BUFFER_UCHAR@12
READ_REGISTER_BUFFER_ULONG@12
READ_REGISTER_BUFFER_USHORT@12
KeRosPrintAddress@4
KiRosPrintAddress@4
KeRosDumpStackFrames@8
KeRosGetStackFrames@8
RtlAbsoluteToSelfRelativeSD@12