3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ke/catch.c
6 * PURPOSE: Exception handling
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 * Casper S. Hornstrup (chorns@users.sourceforge.net)
12 /* INCLUDES *****************************************************************/
16 #include <internal/debug.h>
18 /* FUNCTIONS ****************************************************************/
21 RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord
,
25 KiDispatchException(PEXCEPTION_RECORD ExceptionRecord
,
28 KPROCESSOR_MODE PreviousMode
,
31 EXCEPTION_DISPOSITION Value
;
33 KD_CONTINUE_TYPE Action
= kdHandleException
;
35 DPRINT("KiDispatchException() called\n");
38 /* PCR->KeExceptionDispatchCount++; */
42 TContext
.ContextFlags
= CONTEXT_FULL
;
43 if (PreviousMode
== UserMode
)
45 TContext
.ContextFlags
= TContext
.ContextFlags
| CONTEXT_DEBUGGER
;
48 KeTrapFrameToContext(Tf
, &TContext
);
54 if (ExceptionRecord
->ExceptionCode
== STATUS_BREAKPOINT
)
60 if (KdDebuggerEnabled
&& KdDebugState
& KD_DEBUG_GDB
)
62 Action
= KdEnterDebuggerException (ExceptionRecord
, Context
, Tf
);
65 if (Action
== kdContinue
)
70 if (Action
!= kdDoNotHandleException
)
72 if (PreviousMode
== UserMode
)
78 char temp_space
[12 + sizeof(EXCEPTION_RECORD
) + sizeof(CONTEXT
)]; /* FIXME: HACKHACK */
79 PULONG pNewUserStack
= (PULONG
)(Tf
->Esp
- (12 + sizeof(EXCEPTION_RECORD
) + sizeof(CONTEXT
)));
80 NTSTATUS StatusOfCopy
;
83 Action
= KdbEnterDebuggerException (ExceptionRecord
, PreviousMode
,
85 if (Action
== kdContinue
)
91 /* FIXME: Forward exception to user mode debugger */
93 /* FIXME: Check user mode stack for enough space */
96 * Let usermode try and handle the exception
98 Stack
= (PULONG
)temp_space
;
99 CDest
= 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD
), 4) / 4);
102 /* Pointer to EXCEPTION_RECORD structure */
103 Stack
[1] = (ULONG
)&pNewUserStack
[3];
104 /* Pointer to CONTEXT structure */
105 Stack
[2] = (ULONG
)&pNewUserStack
[CDest
];
106 memcpy(&Stack
[3], ExceptionRecord
, sizeof(EXCEPTION_RECORD
));
107 memcpy(&Stack
[CDest
], Context
, sizeof(CONTEXT
));
109 StatusOfCopy
= MmCopyToCaller(pNewUserStack
,
111 (12 + sizeof(EXCEPTION_RECORD
) + sizeof(CONTEXT
)));
112 if (NT_SUCCESS(StatusOfCopy
))
114 Tf
->Esp
= (ULONG
)pNewUserStack
;
118 /* Now it really hit the ventilation device. Sorry,
119 * can do nothing but kill the sucker.
121 ZwTerminateThread(NtCurrentThread(), ExceptionRecord
->ExceptionCode
);
122 DPRINT1("User-mode stack was invalid. Terminating target thread\n");
124 Tf
->Eip
= (ULONG
)LdrpGetSystemDllExceptionDispatcher();
128 /* FIXME: Forward the exception to the debugger */
130 /* FIXME: Forward the exception to the process exception port */
133 Action
= KdbEnterDebuggerException (ExceptionRecord
, PreviousMode
,
135 if (Action
== kdContinue
)
141 /* Terminate the offending thread */
142 DPRINT1("Unhandled UserMode exception, terminating thread\n");
143 ZwTerminateThread(NtCurrentThread(), ExceptionRecord
->ExceptionCode
);
147 /* PreviousMode == KernelMode */
149 Action
= KdbEnterDebuggerException (ExceptionRecord
, PreviousMode
,
151 if (Action
== kdContinue
)
157 Value
= RtlpDispatchException (ExceptionRecord
, Context
);
159 DPRINT("RtlpDispatchException() returned with 0x%X\n", Value
);
161 * If RtlpDispatchException() does not handle the exception then
164 if (Value
!= ExceptionContinueExecution
||
165 0 != (ExceptionRecord
->ExceptionFlags
& EXCEPTION_NONCONTINUABLE
))
167 DPRINT("ExceptionRecord->ExceptionAddress = 0x%x\n",
168 ExceptionRecord
->ExceptionAddress
);
170 Action
= KdbEnterDebuggerException (ExceptionRecord
, PreviousMode
,
172 if (Action
== kdContinue
)
177 KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED
, 0, 0, 0, 0, Tf
);
187 ExRaiseAccessViolation (VOID
)
189 ExRaiseStatus (STATUS_ACCESS_VIOLATION
);
196 ExRaiseDatatypeMisalignment (VOID
)
198 ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT
);
205 ExRaiseStatus (IN NTSTATUS Status
)
207 EXCEPTION_RECORD ExceptionRecord
;
209 DPRINT("ExRaiseStatus(%x)\n", Status
);
211 ExceptionRecord
.ExceptionRecord
= NULL
;
212 ExceptionRecord
.NumberParameters
= 0;
213 ExceptionRecord
.ExceptionCode
= Status
;
214 ExceptionRecord
.ExceptionFlags
= 0;
216 RtlRaiseException(&ExceptionRecord
);
227 PEXCEPTION_RECORD ExceptionRecord
230 RtlRaiseException(ExceptionRecord
);
238 ExSystemExceptionFilter(VOID
)
240 return KeGetPreviousMode() != KernelMode
? EXCEPTION_EXECUTE_HANDLER
: EXCEPTION_CONTINUE_SEARCH
;
249 IN NTSTATUS ErrorStatus
,
250 IN ULONG NumberOfParameters
,
251 IN PUNICODE_STRING UnicodeStringParameterMask OPTIONAL
,
252 IN PVOID
*Parameters
,
253 IN HARDERROR_RESPONSE_OPTION ResponseOption
,
254 OUT PHARDERROR_RESPONSE Response
265 KeDeregisterBugCheckReasonCallback(
266 IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord
278 KeGetRecommendedSharedDataAlignment(
291 KeRegisterBugCheckReasonCallback(
292 IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord
,
293 IN PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine
,
294 IN KBUGCHECK_CALLBACK_REASON Reason
,