- Fix ExInitPoolLookasidePointers and ExpInitailizeLookasideLists.
[reactos.git] / reactos / ntoskrnl / kd / kdmain.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/kd/kdinit.c
5 * PURPOSE: Kernel Debugger Initializtion
6 *
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
8 */
9
10 #include <ntoskrnl.h>
11 #define NDEBUG
12 #include <internal/debug.h>
13
14 /* VARIABLES ***************************************************************/
15
16 BOOLEAN KdDebuggerEnabled = FALSE;
17 BOOLEAN KdEnteredDebugger = FALSE;
18 BOOLEAN KdDebuggerNotPresent = TRUE;
19 BOOLEAN KiEnableTimerWatchdog = FALSE;
20 BOOLEAN KdBreakAfterSymbolLoad = FALSE;
21 ULONG KiBugCheckData;
22 BOOLEAN KdpBreakPending;
23 VOID STDCALL PspDumpThreads(BOOLEAN SystemThreads);
24
25 typedef struct
26 {
27 ULONG ComponentId;
28 ULONG Level;
29 } KD_COMPONENT_DATA;
30 #define MAX_KD_COMPONENT_TABLE_ENTRIES 128
31 KD_COMPONENT_DATA KdComponentTable[MAX_KD_COMPONENT_TABLE_ENTRIES];
32 ULONG KdComponentTableEntries = 0;
33
34 /* PRIVATE FUNCTIONS *********************************************************/
35
36 ULONG
37 STDCALL
38 KdpServiceDispatcher(ULONG Service,
39 PVOID Buffer1,
40 ULONG Buffer1Length)
41 {
42 ULONG Result = 0;
43
44 switch (Service)
45 {
46 case BREAKPOINT_PRINT: /* DbgPrint */
47 Result = KdpPrintString(Buffer1, Buffer1Length);
48 break;
49
50 #ifdef DBG
51 case TAG('R', 'o', 's', ' '): /* ROS-INTERNAL */
52 {
53 switch ((ULONG)Buffer1)
54 {
55 case DumpNonPagedPool:
56 MiDebugDumpNonPagedPool(FALSE);
57 break;
58
59 case ManualBugCheck:
60 KEBUGCHECK(MANUALLY_INITIATED_CRASH);
61 break;
62
63 case DumpNonPagedPoolStats:
64 MiDebugDumpNonPagedPoolStats(FALSE);
65 break;
66
67 case DumpNewNonPagedPool:
68 MiDebugDumpNonPagedPool(TRUE);
69 break;
70
71 case DumpNewNonPagedPoolStats:
72 MiDebugDumpNonPagedPoolStats(TRUE);
73 break;
74
75 case DumpAllThreads:
76 PspDumpThreads(TRUE);
77 break;
78
79 case DumpUserThreads:
80 PspDumpThreads(FALSE);
81 break;
82
83 case EnterDebugger:
84 DbgBreakPoint();
85 break;
86
87 default:
88 break;
89 }
90 }
91 #endif
92 default:
93 HalDisplayString ("Invalid debug service call!\n");
94 break;
95 }
96
97 return Result;
98 }
99
100 BOOLEAN
101 NTAPI
102 KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
103 IN PKEXCEPTION_FRAME ExceptionFrame,
104 IN PEXCEPTION_RECORD ExceptionRecord,
105 IN PCONTEXT Context,
106 IN KPROCESSOR_MODE PreviousMode,
107 IN BOOLEAN SecondChance)
108 {
109 KD_CONTINUE_TYPE Return;
110
111 /* HACK (just like all this routine */
112 if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) Context->Eip++;
113
114 /* Get out of here if the Debugger isn't connected */
115 if (KdDebuggerNotPresent) return FALSE;
116
117 /* Call KDBG if available */
118 Return = KdbEnterDebuggerException(ExceptionRecord,
119 PreviousMode,
120 Context,
121 TrapFrame,
122 !SecondChance);
123
124 /* Convert return to BOOLEAN */
125 if (Return == kdContinue) return TRUE;
126 return FALSE;
127 }
128
129 BOOLEAN
130 NTAPI
131 KdpCallGdb(IN PKTRAP_FRAME TrapFrame,
132 IN PEXCEPTION_RECORD ExceptionRecord,
133 IN PCONTEXT Context)
134 {
135 KD_CONTINUE_TYPE Return = kdDoNotHandleException;
136
137 /* Get out of here if the Debugger isn't connected */
138 if (KdDebuggerNotPresent) return FALSE;
139
140 /* FIXME:
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
145 */
146 if (WrapperInitRoutine)
147 {
148 Return = WrapperTable.KdpExceptionRoutine(ExceptionRecord,
149 Context,
150 TrapFrame);
151 }
152
153 /* Convert return to BOOLEAN */
154 if (Return == kdContinue) return TRUE;
155 return FALSE;
156 }
157
158 /* PUBLIC FUNCTIONS *********************************************************/
159
160 /*
161 * @implemented
162 */
163 NTSTATUS
164 STDCALL
165 KdDisableDebugger(VOID)
166 {
167 KIRQL OldIrql;
168
169 /* Raise IRQL */
170 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
171
172 /* TODO: Disable any breakpoints */
173
174 /* Disable the Debugger */
175 KdDebuggerEnabled = FALSE;
176
177 /* Lower the IRQL */
178 KeLowerIrql(OldIrql);
179
180 /* Return success */
181 return STATUS_SUCCESS;
182 }
183
184 /*
185 * @implemented
186 */
187 NTSTATUS
188 STDCALL
189 KdEnableDebugger(VOID)
190 {
191 KIRQL OldIrql;
192
193 /* Raise IRQL */
194 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
195
196 /* TODO: Re-enable any breakpoints */
197
198 /* Enable the Debugger */
199 KdDebuggerEnabled = TRUE;
200
201 /* Lower the IRQL */
202 KeLowerIrql(OldIrql);
203
204 /* Return success */
205 return STATUS_SUCCESS;
206 }
207
208 /*
209 * @implemented
210 */
211 BOOLEAN
212 STDCALL
213 KdPollBreakIn(VOID)
214 {
215 return KdpBreakPending;
216 }
217
218 /*
219 * @implemented
220 */
221 VOID
222 STDCALL
223 KeEnterKernelDebugger(VOID)
224 {
225 HalDisplayString("\n\n *** Entered kernel debugger ***\n");
226
227 /* Set the Variable */
228 KdEnteredDebugger = TRUE;
229
230 /* Halt the CPU */
231 for (;;) Ke386HaltProcessor();
232 }
233
234 /*
235 * @unimplemented
236 */
237 NTSTATUS
238 STDCALL
239 KdPowerTransition(ULONG PowerState)
240 {
241 UNIMPLEMENTED;
242 return STATUS_NOT_IMPLEMENTED;
243 }
244
245 /*
246 * @unimplemented
247 */
248 VOID
249 STDCALL
250 KdChangeOption(IN KD_OPTION Option,
251 IN ULONG InBufferLength OPTIONAL,
252 IN PVOID InBuffer,
253 IN ULONG OutBufferLength OPTIONAL,
254 OUT PVOID OutBuffer,
255 OUT PULONG OutBufferRequiredLength OPTIONAL)
256 {
257 UNIMPLEMENTED;
258 }
259
260
261 NTSTATUS
262 STDCALL
263 NtQueryDebugFilterState(IN ULONG ComponentId,
264 IN ULONG Level)
265 {
266 unsigned int i;
267
268 /* convert Level to mask if it isn't already one */
269 if ( Level < 32 )
270 Level = 1 << Level;
271
272 for ( i = 0; i < KdComponentTableEntries; i++ )
273 {
274 if ( ComponentId == KdComponentTable[i].ComponentId )
275 {
276 if ( Level & KdComponentTable[i].Level )
277 return TRUE;
278 break;
279 }
280 }
281 return FALSE;
282 }
283
284 NTSTATUS
285 STDCALL
286 NtSetDebugFilterState(IN ULONG ComponentId,
287 IN ULONG Level,
288 IN BOOLEAN State)
289 {
290 unsigned int i;
291 for ( i = 0; i < KdComponentTableEntries; i++ )
292 {
293 if ( ComponentId == KdComponentTable[i].ComponentId )
294 break;
295 }
296 if ( i == KdComponentTableEntries )
297 {
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;
303 }
304 if ( State )
305 KdComponentTable[i].Level |= Level;
306 else
307 KdComponentTable[i].Level &= ~Level;
308 return STATUS_SUCCESS;
309 }
310
311 PKDEBUG_ROUTINE KiDebugRoutine = KdpEnterDebuggerException;
312
313 /* EOF */