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
;
21 BOOLEAN KdpBreakPending
;
22 BOOLEAN KdPitchDebugger
= TRUE
;
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
;
110 ULONG ExceptionCommand
= ExceptionRecord
->ExceptionInformation
[0];
112 /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */
113 if ((ExceptionRecord
->ExceptionCode
== STATUS_BREAKPOINT
) &&
114 (ExceptionRecord
->NumberParameters
> 0) &&
115 ((ExceptionCommand
== BREAKPOINT_LOAD_SYMBOLS
) ||
116 (ExceptionCommand
== BREAKPOINT_UNLOAD_SYMBOLS
) ||
117 (ExceptionCommand
== BREAKPOINT_COMMAND_STRING
) ||
118 (ExceptionCommand
== BREAKPOINT_PRINT
)))
120 /* Check if this is a debug print */
121 if (ExceptionCommand
== BREAKPOINT_PRINT
)
123 /* Print the string */
124 KdpServiceDispatcher(BREAKPOINT_PRINT
,
125 (PVOID
)ExceptionRecord
->ExceptionInformation
[1],
126 ExceptionRecord
->ExceptionInformation
[2]);
129 /* This we can handle: simply bump EIP */
134 /* Get out of here if the Debugger isn't connected */
135 if (KdDebuggerNotPresent
) return FALSE
;
137 /* Call KDBG if available */
138 Return
= KdbEnterDebuggerException(ExceptionRecord
,
144 /* Convert return to BOOLEAN */
145 if (Return
== kdContinue
) return TRUE
;
151 KdpCallGdb(IN PKTRAP_FRAME TrapFrame
,
152 IN PEXCEPTION_RECORD ExceptionRecord
,
155 KD_CONTINUE_TYPE Return
= kdDoNotHandleException
;
157 /* Get out of here if the Debugger isn't connected */
158 if (KdDebuggerNotPresent
) return FALSE
;
161 * Right now, the GDB wrapper seems to handle exceptions differntly
162 * from KDGB and both are called at different times, while the GDB
163 * one is only called once and that's it. I don't really have the knowledge
164 * to fix the GDB stub, so until then, we'll be using this hack
166 if (WrapperInitRoutine
)
168 Return
= WrapperTable
.KdpExceptionRoutine(ExceptionRecord
,
173 /* Convert return to BOOLEAN */
174 if (Return
== kdContinue
) return TRUE
;
178 /* PUBLIC FUNCTIONS *********************************************************/
185 KdDisableDebugger(VOID
)
190 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
192 /* TODO: Disable any breakpoints */
194 /* Disable the Debugger */
195 KdDebuggerEnabled
= FALSE
;
198 KeLowerIrql(OldIrql
);
201 return STATUS_SUCCESS
;
209 KdEnableDebugger(VOID
)
214 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
216 /* TODO: Re-enable any breakpoints */
218 /* Enable the Debugger */
219 KdDebuggerEnabled
= TRUE
;
222 KeLowerIrql(OldIrql
);
225 return STATUS_SUCCESS
;
235 return KdpBreakPending
;
243 KdPowerTransition(ULONG PowerState
)
246 return STATUS_NOT_IMPLEMENTED
;
254 KdChangeOption(IN KD_OPTION Option
,
255 IN ULONG InBufferLength OPTIONAL
,
257 IN ULONG OutBufferLength OPTIONAL
,
259 OUT PULONG OutBufferRequiredLength OPTIONAL
)
262 return STATUS_NOT_IMPLEMENTED
;
268 NtQueryDebugFilterState(IN ULONG ComponentId
,
273 /* convert Level to mask if it isn't already one */
277 for ( i
= 0; i
< KdComponentTableEntries
; i
++ )
279 if ( ComponentId
== KdComponentTable
[i
].ComponentId
)
281 if ( Level
& KdComponentTable
[i
].Level
)
291 NtSetDebugFilterState(IN ULONG ComponentId
,
296 for ( i
= 0; i
< KdComponentTableEntries
; i
++ )
298 if ( ComponentId
== KdComponentTable
[i
].ComponentId
)
301 if ( i
== KdComponentTableEntries
)
303 if ( i
== MAX_KD_COMPONENT_TABLE_ENTRIES
)
304 return STATUS_INVALID_PARAMETER_1
;
305 ++KdComponentTableEntries
;
306 KdComponentTable
[i
].ComponentId
= ComponentId
;
307 KdComponentTable
[i
].Level
= 0;
310 KdComponentTable
[i
].Level
|= Level
;
312 KdComponentTable
[i
].Level
&= ~Level
;
313 return STATUS_SUCCESS
;
321 KdSystemDebugControl(IN SYSDBG_COMMAND Command
,
322 IN PVOID InputBuffer
,
323 IN ULONG InputBufferLength
,
324 OUT PVOID OutputBuffer
,
325 IN ULONG OutputBufferLength
,
326 IN OUT PULONG ReturnLength
,
327 IN KPROCESSOR_MODE PreviousMode
)
330 return KdpServiceDispatcher(Command
, InputBuffer
, InputBufferLength
);
333 PKDEBUG_ROUTINE KiDebugRoutine
= KdpEnterDebuggerException
;