KdDebuggerEnable -> KdDebuggerEnabled
[reactos.git] / reactos / ntoskrnl / ke / catch.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2000 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: catch.c,v 1.27 2002/12/11 04:39:20 robd Exp $
20 *
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/catch.c
23 * PURPOSE: Exception handling
24 * PROGRAMMER: David Welch (welch@mcmail.com)
25 * Casper S. Hornstrup (chorns@users.sourceforge.net)
26 */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <ddk/ntddk.h>
31 #include <roscfg.h>
32 #include <internal/ke.h>
33 #include <internal/ldr.h>
34 #include <internal/ps.h>
35 #include <internal/kd.h>
36
37 #define NDEBUG
38 #include <internal/debug.h>
39
40 /* FUNCTIONS ****************************************************************/
41
42 ULONG
43 RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
44 IN PCONTEXT Context);
45
46 VOID
47 KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
48 PCONTEXT Context,
49 PKTRAP_FRAME Tf,
50 KPROCESSOR_MODE PreviousMode,
51 BOOLEAN SearchFrames)
52 {
53 EXCEPTION_DISPOSITION Value;
54 CONTEXT TContext;
55
56 DPRINT("KiDispatchException() called\n");
57
58 /* PCR->KeExceptionDispatchCount++; */
59
60 if (Context == NULL)
61 {
62 TContext.ContextFlags = CONTEXT_FULL;
63 if (PreviousMode == UserMode)
64 {
65 TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER;
66 }
67
68 KeTrapFrameToContext(Tf, &TContext);
69
70 Context = &TContext;
71 }
72
73 #if 0
74 if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
75 {
76 Context->Eip--;
77 }
78 #endif
79 if (PreviousMode == UserMode)
80 {
81 if (SearchFrames)
82 {
83 PULONG Stack;
84 ULONG CDest;
85
86 /* FIXME: Give the kernel debugger a chance */
87
88 /* FIXME: Forward exception to user mode debugger */
89
90 /* FIXME: Check user mode stack for enough space */
91
92
93 /*
94 * Let usermode try and handle the exception
95 */
96 Tf->Esp = Tf->Esp -
97 (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT));
98 Stack = (PULONG)Tf->Esp;
99 CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4);
100 /* Return address */
101 Stack[0] = 0;
102 /* Pointer to EXCEPTION_RECORD structure */
103 Stack[1] = (ULONG)&Stack[3];
104 /* Pointer to CONTEXT structure */
105 Stack[2] = (ULONG)&Stack[CDest];
106 memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
107 memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
108
109 Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
110 return;
111 }
112
113 /* FIXME: Forward the exception to the debugger */
114
115 /* FIXME: Forward the exception to the process exception port */
116
117 /* Terminate the offending thread */
118 ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
119
120 /* If that fails then bugcheck */
121 DbgPrint("Could not terminate thread\n");
122 KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
123 }
124 else
125 {
126 KD_CONTINUE_TYPE Action = kdContinue;
127
128 /* PreviousMode == KernelMode */
129
130 if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB)
131 {
132 Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
133 }
134 #ifdef KDBG
135 else if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_KDB)
136 {
137 Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf);
138 }
139 #endif /* KDBG */
140 if (Action != kdHandleException)
141 {
142 Value = RtlpDispatchException (ExceptionRecord, Context);
143
144 DPRINT("RtlpDispatchException() returned with 0x%X\n", Value);
145 /*
146 * If RtlpDispatchException() does not handle the exception then
147 * bugcheck
148 */
149 if (Value != ExceptionContinueExecution)
150 {
151 KeBugCheck (KMODE_EXCEPTION_NOT_HANDLED);
152 }
153 }
154 else
155 {
156 KeContextToTrapFrame (Context, KeGetCurrentThread()->TrapFrame);
157 }
158 }
159 }
160
161 VOID STDCALL
162 ExRaiseAccessViolation (VOID)
163 {
164 ExRaiseStatus (STATUS_ACCESS_VIOLATION);
165 }
166
167 VOID STDCALL
168 ExRaiseDatatypeMisalignment (VOID)
169 {
170 ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT);
171 }
172
173 VOID STDCALL
174 ExRaiseStatus (IN NTSTATUS Status)
175 {
176 EXCEPTION_RECORD ExceptionRecord;
177
178 DPRINT("ExRaiseStatus(%x)\n", Status);
179
180 ExceptionRecord.ExceptionRecord = NULL;
181 ExceptionRecord.NumberParameters = 0;
182 ExceptionRecord.ExceptionCode = Status;
183 ExceptionRecord.ExceptionFlags = 0;
184
185 RtlRaiseException(&ExceptionRecord);
186 }
187
188
189 NTSTATUS STDCALL
190 NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord,
191 IN PCONTEXT Context,
192 IN BOOLEAN SearchFrames)
193 {
194 KiDispatchException(ExceptionRecord,
195 Context,
196 PsGetCurrentThread()->Tcb.TrapFrame,
197 ExGetPreviousMode(),
198 SearchFrames);
199 return(STATUS_SUCCESS);
200 }
201
202
203 VOID STDCALL
204 RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
205 {
206 ZwRaiseException(ExceptionRecord, NULL, TRUE);
207 }
208
209 /* EOF */