3 * Copyright (C) 2000 ReactOS Team
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.
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.
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.
19 /* $Id: catch.c,v 1.29 2003/03/06 23:57:02 gvg Exp $
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)
28 /* INCLUDES *****************************************************************/
30 #include <ddk/ntddk.h>
31 #include <reactos/bugcodes.h>
33 #include <internal/ke.h>
34 #include <internal/ldr.h>
35 #include <internal/ps.h>
36 #include <internal/kd.h>
39 #include <internal/debug.h>
41 /* FUNCTIONS ****************************************************************/
44 RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord
,
48 KiDispatchException(PEXCEPTION_RECORD ExceptionRecord
,
51 KPROCESSOR_MODE PreviousMode
,
54 EXCEPTION_DISPOSITION Value
;
57 DPRINT("KiDispatchException() called\n");
59 /* PCR->KeExceptionDispatchCount++; */
63 TContext
.ContextFlags
= CONTEXT_FULL
;
64 if (PreviousMode
== UserMode
)
66 TContext
.ContextFlags
= TContext
.ContextFlags
| CONTEXT_DEBUGGER
;
69 KeTrapFrameToContext(Tf
, &TContext
);
75 if (ExceptionRecord
->ExceptionCode
== STATUS_BREAKPOINT
)
80 if (PreviousMode
== UserMode
)
87 /* FIXME: Give the kernel debugger a chance */
89 /* FIXME: Forward exception to user mode debugger */
91 /* FIXME: Check user mode stack for enough space */
95 * Let usermode try and handle the exception
98 (12 + sizeof(EXCEPTION_RECORD
) + sizeof(CONTEXT
));
99 Stack
= (PULONG
)Tf
->Esp
;
100 CDest
= 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD
), 4) / 4);
103 /* Pointer to EXCEPTION_RECORD structure */
104 Stack
[1] = (ULONG
)&Stack
[3];
105 /* Pointer to CONTEXT structure */
106 Stack
[2] = (ULONG
)&Stack
[CDest
];
107 memcpy(&Stack
[3], ExceptionRecord
, sizeof(EXCEPTION_RECORD
));
108 memcpy(&Stack
[CDest
], Context
, sizeof(CONTEXT
));
110 Tf
->Eip
= (ULONG
)LdrpGetSystemDllExceptionDispatcher();
114 /* FIXME: Forward the exception to the debugger */
116 /* FIXME: Forward the exception to the process exception port */
118 /* Terminate the offending thread */
119 ZwTerminateThread(NtCurrentThread(), ExceptionRecord
->ExceptionCode
);
121 /* If that fails then bugcheck */
122 DbgPrint("Could not terminate thread\n");
123 KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED
);
127 KD_CONTINUE_TYPE Action
= kdContinue
;
129 /* PreviousMode == KernelMode */
131 if (KdDebuggerEnabled
&& KdDebugState
& KD_DEBUG_GDB
)
133 Action
= KdEnterDebuggerException (ExceptionRecord
, Context
, Tf
);
136 else if (KdDebuggerEnabled
&& KdDebugState
& KD_DEBUG_KDB
)
138 Action
= KdbEnterDebuggerException (ExceptionRecord
, Context
, Tf
);
141 if (Action
!= kdHandleException
)
143 Value
= RtlpDispatchException (ExceptionRecord
, Context
);
145 DPRINT("RtlpDispatchException() returned with 0x%X\n", Value
);
147 * If RtlpDispatchException() does not handle the exception then
151 if (Value
!= ExceptionContinueExecution
)
154 KeBugCheck (KMODE_EXCEPTION_NOT_HANDLED
);
159 KeContextToTrapFrame (Context
, KeGetCurrentThread()->TrapFrame
);
165 ExRaiseAccessViolation (VOID
)
167 ExRaiseStatus (STATUS_ACCESS_VIOLATION
);
171 ExRaiseDatatypeMisalignment (VOID
)
173 ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT
);
177 ExRaiseStatus (IN NTSTATUS Status
)
179 EXCEPTION_RECORD ExceptionRecord
;
181 DPRINT("ExRaiseStatus(%x)\n", Status
);
183 ExceptionRecord
.ExceptionRecord
= NULL
;
184 ExceptionRecord
.NumberParameters
= 0;
185 ExceptionRecord
.ExceptionCode
= Status
;
186 ExceptionRecord
.ExceptionFlags
= 0;
188 RtlRaiseException(&ExceptionRecord
);
193 NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord
,
195 IN BOOLEAN SearchFrames
)
197 KiDispatchException(ExceptionRecord
,
199 PsGetCurrentThread()->Tcb
.TrapFrame
,
202 return(STATUS_SUCCESS
);
207 RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord
)
209 ZwRaiseException(ExceptionRecord
, NULL
, TRUE
);