Improve (hardware) exception handling and reporting

svn path=/trunk/; revision=4514
This commit is contained in:
Gé van Geldorp 2003-04-07 23:10:08 +00:00
parent e81de9962d
commit 2602dec603
7 changed files with 118 additions and 112 deletions

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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);
}