mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
Improve (hardware) exception handling and reporting
svn path=/trunk/; revision=4514
This commit is contained in:
parent
e81de9962d
commit
2602dec603
7 changed files with 118 additions and 112 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: create.c,v 1.64 2003/03/26 22:11:27 hbirr Exp $
|
||||
/* $Id: create.c,v 1.65 2003/04/07 23:10:07 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -171,29 +171,32 @@ _except_handler(
|
|||
struct _CONTEXT *ContextRecord,
|
||||
void * DispatcherContext )
|
||||
{
|
||||
DPRINT("Process terminated abnormally...\n");
|
||||
DPRINT1("Process terminated abnormally due to unhandled exception\n");
|
||||
|
||||
if (++_except_recursion_trap > 3) {
|
||||
DPRINT("_except_handler(...) appears to be recursing.\n");
|
||||
DPRINT("Process HALTED.\n");
|
||||
for (;;) {}
|
||||
}
|
||||
|
||||
if (/* FIXME: */ TRUE) /* Not a service */
|
||||
if (3 < ++_except_recursion_trap)
|
||||
{
|
||||
DPRINT1("_except_handler(...) appears to be recursing.\n");
|
||||
DPRINT1("Process HALTED.\n");
|
||||
for (;;)
|
||||
{
|
||||
DPRINT(" calling ExitProcess(0) no, lets try ExitThread . . .\n");
|
||||
//ExitProcess(0);
|
||||
ExitThread(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT(" calling ExitThread(0) . . .\n");
|
||||
ExitThread(0);
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT(" We should not get to here !!!\n");
|
||||
/* We should not get to here */
|
||||
return ExceptionContinueSearch;
|
||||
if (/* FIXME: */ TRUE) /* Not a service */
|
||||
{
|
||||
DPRINT(" calling ExitProcess(0) no, lets try ExitThread . . .\n");
|
||||
/* ExitProcess(0); */
|
||||
ExitThread(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT(" calling ExitThread(0) . . .\n");
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
DPRINT1(" We should not get to here !!!\n");
|
||||
/* We should not get to here */
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: exception.c,v 1.12 2003/03/16 14:16:54 chorns Exp $
|
||||
/* $Id: exception.c,v 1.13 2003/04/07 23:10:08 gvg Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -58,7 +58,7 @@ KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord,
|
|||
VOID STDCALL
|
||||
RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
|
||||
{
|
||||
DbgPrint("RtlRaiseException()");
|
||||
DPRINT("RtlRaiseException()\n");
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
#include <internal/module.h>
|
||||
#include <internal/ldr.h>
|
||||
|
||||
#undef NDEBUG
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
extern LIST_ENTRY PiThreadListHead;
|
||||
|
@ -354,7 +354,7 @@ GspPutPacketNoWait (PCHAR Buffer)
|
|||
/* Indicate to caller of GspMem2Hex or GspHex2Mem that there has been an
|
||||
error. */
|
||||
static volatile BOOLEAN GspMemoryError = FALSE;
|
||||
static void *GspAccessLocation = NULL;
|
||||
static volatile void *GspAccessLocation = NULL;
|
||||
|
||||
|
||||
/* Convert the memory pointed to by Address into hex, placing result in Buffer */
|
||||
|
@ -370,6 +370,12 @@ GspMem2Hex (PCHAR Address,
|
|||
ULONG i;
|
||||
CHAR ch;
|
||||
|
||||
if (NULL == Address && MayFault)
|
||||
{
|
||||
GspMemoryError = TRUE;
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
for (i = 0; i < (ULONG) Count; i++)
|
||||
{
|
||||
if (MayFault)
|
||||
|
@ -457,14 +463,12 @@ GspComputeSignal (NTSTATUS ExceptionCode)
|
|||
SigVal = 8;
|
||||
break; /* divide by zero */
|
||||
case STATUS_SINGLE_STEP:
|
||||
SigVal = 5;
|
||||
break; /* debug exception */
|
||||
/* debug exception */
|
||||
case STATUS_BREAKPOINT:
|
||||
SigVal = 5;
|
||||
break; /* breakpoint */
|
||||
case STATUS_INTEGER_OVERFLOW:
|
||||
SigVal = 16;
|
||||
break; /* into instruction (overflow) */
|
||||
/* into instruction (overflow) */
|
||||
case STATUS_ARRAY_BOUNDS_EXCEEDED:
|
||||
SigVal = 16;
|
||||
break; /* bound instruction */
|
||||
|
@ -477,11 +481,12 @@ GspComputeSignal (NTSTATUS ExceptionCode)
|
|||
break; /* coprocessor not available */
|
||||
#endif
|
||||
case STATUS_STACK_OVERFLOW:
|
||||
SigVal = 11;
|
||||
break; /* stack exception */
|
||||
/* stack exception */
|
||||
case STATUS_DATATYPE_MISALIGNMENT:
|
||||
SigVal = 11;
|
||||
break; /* page fault */
|
||||
/* page fault */
|
||||
case STATUS_ACCESS_VIOLATION:
|
||||
SigVal = 11; /* access violation */
|
||||
break;
|
||||
default:
|
||||
SigVal = 7; /* "software generated" */
|
||||
}
|
||||
|
@ -746,7 +751,6 @@ GspQuery(PCHAR Request)
|
|||
ETHREAD, Tcb.ThreadListEntry);
|
||||
Value = (ULONG) GspEnumThread->Cid.UniqueThread;
|
||||
GspLong2Hex (&ptr, Value);
|
||||
DPRINT("fThreadInfo 0x%08x\n", (ULONG) GspEnumThread->Cid.UniqueThread);
|
||||
}
|
||||
else if (strncmp (Command, "sThreadInfo", 11) == 0)
|
||||
{
|
||||
|
@ -760,12 +764,10 @@ DPRINT("fThreadInfo 0x%08x\n", (ULONG) GspEnumThread->Cid.UniqueThread);
|
|||
GspOutBuffer[0] = 'm';
|
||||
Value = (ULONG) GspEnumThread->Cid.UniqueThread;
|
||||
GspLong2Hex (&ptr, Value);
|
||||
DPRINT("sThreadInfo 0x%08x\n", (ULONG) GspEnumThread->Cid.UniqueThread);
|
||||
}
|
||||
else
|
||||
{
|
||||
GspOutBuffer[0] = 'l';
|
||||
DPRINT("End of threads\n");
|
||||
}
|
||||
}
|
||||
else if (strncmp (Command, "ThreadExtraInfo", 15) == 0)
|
||||
|
@ -983,13 +985,15 @@ KdEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
/* Disable hardware debugging while we are inside the stub */
|
||||
__asm__("movl %0,%%db7" : /* no output */ : "r" (0));
|
||||
|
||||
if (NULL != GspAccessLocation &&
|
||||
if (STATUS_ACCESS_VIOLATION == ExceptionRecord->ExceptionCode &&
|
||||
NULL != GspAccessLocation &&
|
||||
(ULONG_PTR) GspAccessLocation ==
|
||||
(ULONG_PTR) ExceptionRecord->ExceptionInformation[1])
|
||||
{
|
||||
GspAccessLocation = NULL;
|
||||
GspMemoryError = TRUE;
|
||||
TrapFrame->Eip += 2;
|
||||
ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NONCONTINUABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1044,16 +1048,9 @@ KdEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
break;
|
||||
case 'g': /* return the value of the CPU Registers */
|
||||
if (GspDbgThread)
|
||||
{
|
||||
DPRINT("GspDbgThread active\n");
|
||||
GspGetRegistersFromTrapFrame (&GspOutBuffer[0], Context, GspDbgThread->Tcb.TrapFrame);
|
||||
/*GspGetRegistersFromTrapFrame (&GspOutBuffer[0], Context, TrapFrame);*/
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("GspDbgThread not active\n");
|
||||
GspGetRegistersFromTrapFrame (&GspOutBuffer[0], Context, TrapFrame);
|
||||
}
|
||||
break;
|
||||
case 'G': /* set the value of the CPU Registers - return OK */
|
||||
if (GspDbgThread)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: bug.c,v 1.27 2002/09/08 10:23:28 chorns Exp $
|
||||
/* $Id: bug.c,v 1.28 2003/04/07 23:10:08 gvg Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/bug.c
|
||||
|
@ -158,14 +158,18 @@ KeBugCheckEx(ULONG BugCheckCode,
|
|||
MmDumpToPagingFile(BugCheckCode, BugCheckParameter1,
|
||||
BugCheckParameter2, BugCheckParameter3,
|
||||
BugCheckParameter4, NULL);
|
||||
|
||||
|
||||
if (KdDebuggerEnabled)
|
||||
{
|
||||
__asm__("sti\n\t");
|
||||
DbgBreakPoint();
|
||||
__asm__("cli\n\t");
|
||||
}
|
||||
|
||||
for(;;);
|
||||
for (;;)
|
||||
{
|
||||
__asm__("hlt\n\t");
|
||||
}
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: catch.c,v 1.29 2003/03/06 23:57:02 gvg Exp $
|
||||
/* $Id: catch.c,v 1.30 2003/04/07 23:10:08 gvg Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/catch.c
|
||||
|
@ -53,6 +53,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
{
|
||||
EXCEPTION_DISPOSITION Value;
|
||||
CONTEXT TContext;
|
||||
KD_CONTINUE_TYPE Action = kdContinue;
|
||||
|
||||
DPRINT("KiDispatchException() called\n");
|
||||
|
||||
|
@ -77,69 +78,65 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
Context->Eip--;
|
||||
}
|
||||
#endif
|
||||
if (PreviousMode == UserMode)
|
||||
{
|
||||
if (SearchFrames)
|
||||
{
|
||||
PULONG Stack;
|
||||
ULONG CDest;
|
||||
|
||||
/* FIXME: Give the kernel debugger a chance */
|
||||
|
||||
/* FIXME: Forward exception to user mode debugger */
|
||||
|
||||
/* FIXME: Check user mode stack for enough space */
|
||||
|
||||
|
||||
/*
|
||||
* Let usermode try and handle the exception
|
||||
*/
|
||||
Tf->Esp = Tf->Esp -
|
||||
(12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT));
|
||||
Stack = (PULONG)Tf->Esp;
|
||||
CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4);
|
||||
/* Return address */
|
||||
Stack[0] = 0;
|
||||
/* Pointer to EXCEPTION_RECORD structure */
|
||||
Stack[1] = (ULONG)&Stack[3];
|
||||
/* Pointer to CONTEXT structure */
|
||||
Stack[2] = (ULONG)&Stack[CDest];
|
||||
memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
|
||||
memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
|
||||
|
||||
Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: Forward the exception to the debugger */
|
||||
|
||||
/* FIXME: Forward the exception to the process exception port */
|
||||
|
||||
/* Terminate the offending thread */
|
||||
ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
|
||||
|
||||
/* If that fails then bugcheck */
|
||||
DbgPrint("Could not terminate thread\n");
|
||||
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
|
||||
if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB)
|
||||
{
|
||||
Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
|
||||
}
|
||||
else
|
||||
{
|
||||
KD_CONTINUE_TYPE Action = kdContinue;
|
||||
|
||||
/* PreviousMode == KernelMode */
|
||||
|
||||
if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB)
|
||||
{
|
||||
Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
|
||||
}
|
||||
#ifdef KDBG
|
||||
else if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_KDB)
|
||||
{
|
||||
Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf);
|
||||
}
|
||||
else if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_KDB)
|
||||
{
|
||||
Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf);
|
||||
}
|
||||
#endif /* KDBG */
|
||||
if (Action != kdHandleException)
|
||||
if (Action != kdHandleException)
|
||||
{
|
||||
if (PreviousMode == UserMode)
|
||||
{
|
||||
if (SearchFrames)
|
||||
{
|
||||
PULONG Stack;
|
||||
ULONG CDest;
|
||||
|
||||
/* FIXME: Forward exception to user mode debugger */
|
||||
|
||||
/* FIXME: Check user mode stack for enough space */
|
||||
|
||||
/*
|
||||
* Let usermode try and handle the exception
|
||||
*/
|
||||
Tf->Esp = Tf->Esp -
|
||||
(12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT));
|
||||
Stack = (PULONG)Tf->Esp;
|
||||
CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4);
|
||||
/* Return address */
|
||||
Stack[0] = 0;
|
||||
/* Pointer to EXCEPTION_RECORD structure */
|
||||
Stack[1] = (ULONG)&Stack[3];
|
||||
/* Pointer to CONTEXT structure */
|
||||
Stack[2] = (ULONG)&Stack[CDest];
|
||||
memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
|
||||
memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
|
||||
|
||||
Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: Forward the exception to the debugger */
|
||||
|
||||
/* FIXME: Forward the exception to the process exception port */
|
||||
|
||||
/* Terminate the offending thread */
|
||||
DPRINT1("Unhandled UserMode exception, terminating thread\n");
|
||||
ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
|
||||
|
||||
/* If that fails then bugcheck */
|
||||
DPRINT1("Could not terminate thread\n");
|
||||
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* PreviousMode == KernelMode */
|
||||
Value = RtlpDispatchException (ExceptionRecord, Context);
|
||||
|
||||
DPRINT("RtlpDispatchException() returned with 0x%X\n", Value);
|
||||
|
@ -147,17 +144,16 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
* If RtlpDispatchException() does not handle the exception then
|
||||
* bugcheck
|
||||
*/
|
||||
#ifdef TODO
|
||||
if (Value != ExceptionContinueExecution)
|
||||
#endif
|
||||
if (Value != ExceptionContinueExecution ||
|
||||
0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))
|
||||
{
|
||||
KeBugCheck (KMODE_EXCEPTION_NOT_HANDLED);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
KeContextToTrapFrame (Context, KeGetCurrentThread()->TrapFrame);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
KeContextToTrapFrame (Context, KeGetCurrentThread()->TrapFrame);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -181,6 +181,9 @@ KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
|
|||
Er.NumberParameters = 0;
|
||||
}
|
||||
|
||||
Er.ExceptionFlags = (STATUS_SINGLE_STEP == Er.ExceptionCode || STATUS_BREAKPOINT == Er.ExceptionCode ?
|
||||
0 : EXCEPTION_NONCONTINUABLE);
|
||||
|
||||
KiDispatchException(&Er, 0, Tf, KernelMode, TRUE);
|
||||
|
||||
return(0);
|
||||
|
|
|
@ -144,6 +144,9 @@ KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
|
|||
}
|
||||
|
||||
|
||||
Er.ExceptionFlags = (STATUS_SINGLE_STEP == Er.ExceptionCode || STATUS_BREAKPOINT == Er.ExceptionCode ?
|
||||
0 : EXCEPTION_NONCONTINUABLE);
|
||||
|
||||
KiDispatchException(&Er, 0, Tf, UserMode, TRUE);
|
||||
return(0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue