2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/kd64/kdtrap.c
5 * PURPOSE: KD64 Trap Handlers
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
15 /* FUNCTIONS *****************************************************************/
19 KdpReport(IN PKTRAP_FRAME TrapFrame
,
20 IN PKEXCEPTION_FRAME ExceptionFrame
,
21 IN PEXCEPTION_RECORD ExceptionRecord
,
22 IN PCONTEXT ContextRecord
,
23 IN KPROCESSOR_MODE PreviousMode
,
24 IN BOOLEAN SecondChanceException
)
26 BOOLEAN Entered
, Status
;
28 NTSTATUS ExceptionCode
= ExceptionRecord
->ExceptionCode
;
30 /* Check if this is INT1 or 3, or if we're forced to handle it */
31 if ((ExceptionCode
== STATUS_BREAKPOINT
) ||
32 (ExceptionCode
== STATUS_SINGLE_STEP
) ||
33 //(ExceptionCode == STATUS_ASSERTION_FAILURE) ||
34 (NtGlobalFlag
& FLG_STOP_ON_EXCEPTION
))
36 /* Check if we can't really handle this */
37 if ((SecondChanceException
) ||
38 (ExceptionCode
== STATUS_PORT_DISCONNECTED
) ||
39 (NT_SUCCESS(ExceptionCode
)))
41 /* Return false to have someone else take care of the exception */
45 else if (SecondChanceException
)
47 /* We won't bother unless this is second chance */
51 /* Enter the debugger */
52 Entered
= KdEnterDebugger(TrapFrame
, ExceptionFrame
);
55 * Get the KPRCB and save the CPU Control State manually instead of
56 * using KiSaveProcessorState, since we already have a valid CONTEXT.
58 Prcb
= KeGetCurrentPrcb();
59 KiSaveProcessorControlState(&Prcb
->ProcessorState
);
60 RtlCopyMemory(&Prcb
->ProcessorState
.ContextFrame
,
64 /* Report the new state */
65 Status
= KdpReportExceptionStateChange(ExceptionRecord
,
66 &Prcb
->ProcessorState
.
68 SecondChanceException
);
70 /* Now restore the processor state, manually again. */
71 RtlCopyMemory(ContextRecord
,
72 &Prcb
->ProcessorState
.ContextFrame
,
74 //KiRestoreProcessorControlState(&Prcb->ProcessorState);
76 /* Exit the debugger and clear the CTRL-C state */
77 KdExitDebugger(Entered
);
78 KdpControlCPressed
= FALSE
;
84 KdpTrap(IN PKTRAP_FRAME TrapFrame
,
85 IN PKEXCEPTION_FRAME ExceptionFrame
,
86 IN PEXCEPTION_RECORD ExceptionRecord
,
87 IN PCONTEXT ContextRecord
,
88 IN KPROCESSOR_MODE PreviousMode
,
89 IN BOOLEAN SecondChanceException
)
91 BOOLEAN Unload
= FALSE
;
93 BOOLEAN Status
= FALSE
;
96 * Check if we got a STATUS_BREAKPOINT with a SubID for Print, Prompt or
97 * Load/Unload symbols.
99 if ((ExceptionRecord
->ExceptionCode
== STATUS_BREAKPOINT
) &&
100 (ExceptionRecord
->ExceptionInformation
[0] != BREAKPOINT_BREAK
))
103 Eip
= ContextRecord
->Eip
;
105 /* Check what kind of operation was requested from us */
106 switch (ExceptionRecord
->ExceptionInformation
[0])
109 case BREAKPOINT_PRINT
:
111 /* Call the worker routine */
112 Eax
= KdpPrint(ContextRecord
->Ebx
,
114 (LPSTR
)ExceptionRecord
->ExceptionInformation
[1],
115 (ULONG
)ExceptionRecord
->ExceptionInformation
[2],
121 /* Update the return value for the caller */
122 ContextRecord
->Eax
= Eax
;
126 case BREAKPOINT_PROMPT
:
128 /* Call the worker routine */
133 /* Update the return value for the caller */
134 ContextRecord
->Eax
= Eax
;
137 /* DbgUnloadSymbols */
138 case BREAKPOINT_UNLOAD_SYMBOLS
:
140 /* Drop into the load case below, with the unload parameter */
144 case BREAKPOINT_LOAD_SYMBOLS
:
146 /* Call the worker routine */
147 KdpSymbol((PVOID
)ExceptionRecord
->ExceptionInformation
[1],
148 (PVOID
)ExceptionRecord
->ExceptionInformation
[2],
157 /* DbgCommandString*/
158 case BREAKPOINT_COMMAND_STRING
:
160 /* Call the worker routine */
164 /* Anything else, do nothing */
172 * If EIP was not updated, we'll increment it ourselves so execution
173 * continues past the breakpoint.
175 if (ContextRecord
->Eip
== Eip
) ContextRecord
->Eip
++;
179 /* Call the worker routine */
180 Status
= KdpReport(TrapFrame
,
185 SecondChanceException
);
188 /* Return TRUE or FALSE to caller */
194 KdpStub(IN PKTRAP_FRAME TrapFrame
,
195 IN PKEXCEPTION_FRAME ExceptionFrame
,
196 IN PEXCEPTION_RECORD ExceptionRecord
,
197 IN PCONTEXT ContextRecord
,
198 IN KPROCESSOR_MODE PreviousMode
,
199 IN BOOLEAN SecondChanceException
)
201 ULONG ExceptionCommand
= ExceptionRecord
->ExceptionInformation
[0];
203 /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */
204 if ((ExceptionRecord
->ExceptionCode
== STATUS_BREAKPOINT
) &&
205 (ExceptionRecord
->NumberParameters
> 0) &&
206 ((ExceptionCommand
== BREAKPOINT_LOAD_SYMBOLS
) ||
207 (ExceptionCommand
== BREAKPOINT_UNLOAD_SYMBOLS
) ||
208 (ExceptionCommand
== BREAKPOINT_COMMAND_STRING
) ||
209 (ExceptionCommand
== BREAKPOINT_PRINT
)))
211 /* This we can handle: simply bump EIP */
212 ContextRecord
->Eip
++;
215 else if (KdPitchDebugger
)
217 /* There's no debugger, fail. */
220 else if ((KdAutoEnableOnEvent
) &&
221 (KdPreviouslyEnabled
) &&
222 !(KdDebuggerEnabled
) &&
223 (KdEnableDebugger()) &&
226 /* Debugging was Auto-Enabled. We can now send this to KD. */
227 return KdpTrap(TrapFrame
,
232 SecondChanceException
);
236 /* FIXME: All we can do in this case is trace this exception */