2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/kd/kdinit.c
5 * PURPOSE: Kernel Debugger Initializtion
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
12 #include <internal/debug.h>
14 /* VARIABLES ***************************************************************/
16 BOOLEAN KdDebuggerEnabled
= FALSE
;
17 BOOLEAN KdEnteredDebugger
= FALSE
;
18 BOOLEAN KdDebuggerNotPresent
= TRUE
;
19 BOOLEAN KiEnableTimerWatchdog
= FALSE
;
20 BOOLEAN KdBreakAfterSymbolLoad
= FALSE
;
22 BOOLEAN KdpBreakPending
;
23 VOID STDCALL
PspDumpThreads(BOOLEAN SystemThreads
);
30 #define MAX_KD_COMPONENT_TABLE_ENTRIES 128
31 KD_COMPONENT_DATA KdComponentTable
[MAX_KD_COMPONENT_TABLE_ENTRIES
];
32 ULONG KdComponentTableEntries
= 0;
34 /* PRIVATE FUNCTIONS *********************************************************/
38 KdpServiceDispatcher(ULONG Service
,
46 case BREAKPOINT_PRINT
: /* DbgPrint */
47 Result
= KdpPrintString(Buffer1
, Buffer1Length
);
51 case TAG('R', 'o', 's', ' '): /* ROS-INTERNAL */
53 switch ((ULONG
)Buffer1
)
55 case DumpNonPagedPool
:
56 MiDebugDumpNonPagedPool(FALSE
);
60 KEBUGCHECK(MANUALLY_INITIATED_CRASH
);
63 case DumpNonPagedPoolStats
:
64 MiDebugDumpNonPagedPoolStats(FALSE
);
67 case DumpNewNonPagedPool
:
68 MiDebugDumpNonPagedPool(TRUE
);
71 case DumpNewNonPagedPoolStats
:
72 MiDebugDumpNonPagedPoolStats(TRUE
);
80 PspDumpThreads(FALSE
);
93 HalDisplayString ("Invalid debug service call!\n");
102 KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame
,
103 IN PKEXCEPTION_FRAME ExceptionFrame
,
104 IN PEXCEPTION_RECORD ExceptionRecord
,
106 IN KPROCESSOR_MODE PreviousMode
,
107 IN BOOLEAN SecondChance
)
109 KD_CONTINUE_TYPE Return
;
111 /* HACK (just like all this routine */
112 if (ExceptionRecord
->ExceptionCode
== STATUS_BREAKPOINT
) Context
->Eip
++;
114 /* Get out of here if the Debugger isn't connected */
115 if (KdDebuggerNotPresent
) return FALSE
;
117 /* Call KDBG if available */
118 Return
= KdbEnterDebuggerException(ExceptionRecord
,
124 /* Convert return to BOOLEAN */
125 if (Return
== kdContinue
) return TRUE
;
131 KdpCallGdb(IN PKTRAP_FRAME TrapFrame
,
132 IN PEXCEPTION_RECORD ExceptionRecord
,
135 KD_CONTINUE_TYPE Return
= kdDoNotHandleException
;
137 /* Get out of here if the Debugger isn't connected */
138 if (KdDebuggerNotPresent
) return FALSE
;
141 * Right now, the GDB wrapper seems to handle exceptions differntly
142 * from KDGB and both are called at different times, while the GDB
143 * one is only called once and that's it. I don't really have the knowledge
144 * to fix the GDB stub, so until then, we'll be using this hack
146 if (WrapperInitRoutine
)
148 Return
= WrapperTable
.KdpExceptionRoutine(ExceptionRecord
,
153 /* Convert return to BOOLEAN */
154 if (Return
== kdContinue
) return TRUE
;
158 /* PUBLIC FUNCTIONS *********************************************************/
165 KdDisableDebugger(VOID
)
170 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
172 /* TODO: Disable any breakpoints */
174 /* Disable the Debugger */
175 KdDebuggerEnabled
= FALSE
;
178 KeLowerIrql(OldIrql
);
181 return STATUS_SUCCESS
;
189 KdEnableDebugger(VOID
)
194 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
196 /* TODO: Re-enable any breakpoints */
198 /* Enable the Debugger */
199 KdDebuggerEnabled
= TRUE
;
202 KeLowerIrql(OldIrql
);
205 return STATUS_SUCCESS
;
215 return KdpBreakPending
;
223 KeEnterKernelDebugger(VOID
)
225 HalDisplayString("\n\n *** Entered kernel debugger ***\n");
227 /* Set the Variable */
228 KdEnteredDebugger
= TRUE
;
231 for (;;) Ke386HaltProcessor();
239 KdPowerTransition(ULONG PowerState
)
242 return STATUS_NOT_IMPLEMENTED
;
250 KdChangeOption(IN KD_OPTION Option
,
251 IN ULONG InBufferLength OPTIONAL
,
253 IN ULONG OutBufferLength OPTIONAL
,
255 OUT PULONG OutBufferRequiredLength OPTIONAL
)
263 NtQueryDebugFilterState(IN ULONG ComponentId
,
268 /* convert Level to mask if it isn't already one */
272 for ( i
= 0; i
< KdComponentTableEntries
; i
++ )
274 if ( ComponentId
== KdComponentTable
[i
].ComponentId
)
276 if ( Level
& KdComponentTable
[i
].Level
)
286 NtSetDebugFilterState(IN ULONG ComponentId
,
291 for ( i
= 0; i
< KdComponentTableEntries
; i
++ )
293 if ( ComponentId
== KdComponentTable
[i
].ComponentId
)
296 if ( i
== KdComponentTableEntries
)
298 if ( i
== MAX_KD_COMPONENT_TABLE_ENTRIES
)
299 return STATUS_INVALID_PARAMETER_1
;
300 ++KdComponentTableEntries
;
301 KdComponentTable
[i
].ComponentId
= ComponentId
;
302 KdComponentTable
[i
].Level
= 0;
305 KdComponentTable
[i
].Level
|= Level
;
307 KdComponentTable
[i
].Level
&= ~Level
;
308 return STATUS_SUCCESS
;
311 PKDEBUG_ROUTINE KiDebugRoutine
= KdpEnterDebuggerException
;