{\r
BOOLEAN Entered, Status;\r
PKPRCB Prcb;\r
- while (TRUE);\r
+ NTSTATUS ExceptionCode = ExceptionRecord->ExceptionCode;\r
\r
- /*\r
- * Only go ahead with this if this is an INT3 or an INT1, or if the global\r
- * flag forces us to call up the debugger on exception, or if this is a\r
- * second chance exception which means it hasn't been handled by now.\r
- */\r
- if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) ||\r
- (ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) ||\r
- (NtGlobalFlag & FLG_STOP_ON_EXCEPTION) ||\r
- (SecondChanceException))\r
+ /* Check if this is INT1 or 3, or if we're forced to handle it */\r
+ if ((ExceptionCode == STATUS_BREAKPOINT) ||\r
+ (ExceptionCode == STATUS_SINGLE_STEP) ||\r
+ //(ExceptionCode == STATUS_ASSERTION_FAILURE) ||\r
+ (NtGlobalFlag & FLG_STOP_ON_EXCEPTION))\r
{\r
- /*\r
- * Also, unless this is a second chance exception, then do not call up\r
- * the debugger if the debug port is disconnected or the exception code\r
- * indicates success.\r
- */\r
- if (!(SecondChanceException) &&\r
- ((ExceptionRecord->ExceptionCode == STATUS_PORT_DISCONNECTED) ||\r
- (NT_SUCCESS(ExceptionRecord->ExceptionCode))))\r
+ /* Check if we can't really handle this */\r
+ if ((SecondChanceException) ||\r
+ (ExceptionCode == STATUS_PORT_DISCONNECTED) ||\r
+ (NT_SUCCESS(ExceptionCode)))\r
{\r
- /* Return false to hide the exception */\r
+ /* Return false to have someone else take care of the exception */\r
return FALSE;\r
}\r
-\r
- /* Enter the debugger */\r
- Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);\r
-\r
- /*\r
- * Get the KPRCB and save the CPU Control State manually instead of\r
- * using KiSaveProcessorState, since we already have a valid CONTEXT.\r
- */\r
- Prcb = KeGetCurrentPrcb();\r
- KiSaveProcessorControlState(&Prcb->ProcessorState);\r
- RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,\r
- ContextRecord,\r
- sizeof(CONTEXT));\r
-\r
- /* Report the new state */\r
-#if 0\r
- Status = KdpReportExceptionStateChange(ExceptionRecord,\r
- &Prcb->ProcessorState.\r
- ContextFrame,\r
- SecondChanceException);\r
-#else\r
- Status = FALSE;\r
-#endif\r
-\r
- /* Now restore the processor state, manually again. */\r
- RtlCopyMemory(ContextRecord,\r
- &Prcb->ProcessorState.ContextFrame,\r
- sizeof(CONTEXT));\r
- KiRestoreProcessorControlState(&Prcb->ProcessorState);\r
-\r
- /* Exit the debugger and clear the CTRL-C state */\r
- KdExitDebugger(Entered);\r
- KdpControlCPressed = FALSE;\r
- return Status;\r
+ }\r
+ else if (SecondChanceException)\r
+ {\r
+ /* We won't bother unless this is second chance */\r
+ return FALSE;\r
}\r
\r
- /* Fail if we got here */\r
- return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-NTAPI\r
-KdpTrap(IN PKTRAP_FRAME TrapFrame,\r
- IN PKEXCEPTION_FRAME ExceptionFrame,\r
- IN PEXCEPTION_RECORD ExceptionRecord,\r
- IN PCONTEXT ContextRecord,\r
- IN KPROCESSOR_MODE PreviousMode,\r
- IN BOOLEAN SecondChanceException)\r
-{\r
- BOOLEAN Unload = FALSE;\r
- ULONG Eip, Eax;\r
- BOOLEAN Status = FALSE;\r
+ /* Enter the debugger */\r
+ Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);\r
\r
/*\r
- * Check if we got a STATUS_BREAKPOINT with a SubID for Print, Prompt or\r
- * Load/Unload symbols.\r
+ * Get the KPRCB and save the CPU Control State manually instead of\r
+ * using KiSaveProcessorState, since we already have a valid CONTEXT.\r
*/\r
- if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&\r
- (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK))\r
- {\r
- /* Save EIP */\r
- Eip = ContextRecord->Eip;\r
-\r
- /* Check what kind of operation was requested from us */\r
- switch (ExceptionRecord->ExceptionInformation[0])\r
- {\r
- /* DbgPrint */\r
- case BREAKPOINT_PRINT:\r
-\r
- /* Call the worker routine */\r
- Eax = KdpPrint(ContextRecord->Ebx,\r
- ContextRecord->Edi,\r
- (LPSTR)ExceptionRecord->ExceptionInformation[1],\r
- (ULONG)ExceptionRecord->ExceptionInformation[2],\r
- PreviousMode,\r
- TrapFrame,\r
- ExceptionFrame,\r
- &Status);\r
-\r
- /* Update the return value for the caller */\r
- ContextRecord->Eax = Eax;\r
- break;\r
-\r
- /* DbgPrompt */\r
- case BREAKPOINT_PROMPT:\r
-\r
- /* Call the worker routine */\r
- while (TRUE);\r
- Eax = 0;\r
- Status = TRUE;\r
-\r
- /* Update the return value for the caller */\r
- ContextRecord->Eax = Eax;\r
- break;\r
-\r
- /* DbgUnloadSymbols */\r
- case BREAKPOINT_UNLOAD_SYMBOLS:\r
-\r
- /* Drop into the load case below, with the unload parameter */\r
- Unload = TRUE;\r
-\r
- /* DbgLoadSymbols */\r
- case BREAKPOINT_LOAD_SYMBOLS:\r
-\r
- /* Call the worker routine */\r
- KdpSymbol(UlongToPtr(ExceptionRecord->ExceptionInformation[1]),\r
- (ULONG)ExceptionRecord->ExceptionInformation[2],\r
- Unload,\r
- PreviousMode,\r
- ContextRecord,\r
- TrapFrame,\r
- ExceptionFrame);\r
- Status = TRUE;\r
- break;\r
-\r
- /* DbgCommandString*/\r
- case BREAKPOINT_COMMAND_STRING:\r
-\r
- /* Call the worker routine */\r
- while (TRUE);\r
- Status = TRUE;\r
-\r
- /* Anything else, do nothing */\r
- default:\r
-\r
- /* Get out */\r
- break;\r
- }\r
-\r
- /*\r
- * If EIP was not updated, we'll increment it ourselves so execution\r
- * continues past the breakpoint.\r
- */\r
- if (ContextRecord->Eip == Eip) ContextRecord->Eip++;\r
- }\r
- else\r
- {\r
- /* Call the worker routine */\r
- Status = KdpReport(TrapFrame,\r
- ExceptionFrame,\r
- ExceptionRecord,\r
- ContextRecord,\r
- PreviousMode,\r
- SecondChanceException);\r
- }\r
-\r
- /* Return TRUE or FALSE to caller */\r
+ Prcb = KeGetCurrentPrcb();\r
+ KiSaveProcessorControlState(&Prcb->ProcessorState);\r
+ RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,\r
+ ContextRecord,\r
+ sizeof(CONTEXT));\r
+\r
+ /* Report the new state */\r
+ Status = KdpReportExceptionStateChange(ExceptionRecord,\r
+ &Prcb->ProcessorState.\r
+ ContextFrame,\r
+ SecondChanceException);\r
+\r
+ /* Now restore the processor state, manually again. */\r
+ RtlCopyMemory(ContextRecord,\r
+ &Prcb->ProcessorState.ContextFrame,\r
+ sizeof(CONTEXT));\r
+ //KiRestoreProcessorControlState(&Prcb->ProcessorState);\r
+\r
+ /* Exit the debugger and clear the CTRL-C state */\r
+ KdExitDebugger(Entered);\r
+ KdpControlCPressed = FALSE;\r
return Status;\r
}\r
\r
(ExceptionCommand == BREAKPOINT_PRINT)))\r
{\r
/* This we can handle: simply bump EIP */\r
+#if defined (_M_X86)\r
ContextRecord->Eip++;\r
+#elif defined (_M_AMD64)\r
+ ContextRecord->Rip++;\r
+#else\r
+#error Unknown platform\r
+#endif\r
return TRUE;\r
}\r
else if (KdPitchDebugger)\r