mirror of
https://github.com/reactos/reactos.git
synced 2024-11-18 21:13:52 +00:00
[FREELDR] Slightly revamp the Exception BSOD screen.
- Don't store trailing newlines in the exception description text strings. - Remove unused i386PrintChar(). - Display CR4 in x86. - Use the "indentation" printf generation trick in order to get aligned strings for (CF4 and) DR6 and DR7, without having to hardcode the tons of alignment whitespaces (--> make the strings stored in freeldr shorter). - Show the IP/ErrorCode/EFlags/GDTR/IDTR/LDTR values vertically aligned. - Display the stack frames in both x86 and x64 modes. - Adjust the instruction pointer when a BREAKPOINT or OVERFLOW exception arises, so that the offending instruction can show up in the instruction stream.
This commit is contained in:
parent
2c9dbacebb
commit
0d00a5d6eb
2 changed files with 61 additions and 58 deletions
|
@ -5,31 +5,31 @@
|
||||||
|
|
||||||
typedef struct _FRAME
|
typedef struct _FRAME
|
||||||
{
|
{
|
||||||
struct _FRAME *Next;
|
struct _FRAME* Next;
|
||||||
void *Address;
|
PVOID Address;
|
||||||
} FRAME;
|
} FRAME;
|
||||||
|
|
||||||
static const CHAR *i386ExceptionDescriptionText[] =
|
static const CHAR *i386ExceptionDescriptionText[] =
|
||||||
{
|
{
|
||||||
"Exception 00: DIVIDE BY ZERO\n\n",
|
"Exception 00: DIVIDE BY ZERO",
|
||||||
"Exception 01: DEBUG EXCEPTION\n\n",
|
"Exception 01: DEBUG EXCEPTION",
|
||||||
"Exception 02: NON-MASKABLE INTERRUPT EXCEPTION\n\n",
|
"Exception 02: NON-MASKABLE INTERRUPT EXCEPTION",
|
||||||
"Exception 03: BREAKPOINT (INT 3)\n\n",
|
"Exception 03: BREAKPOINT (INT 3)",
|
||||||
"Exception 04: OVERFLOW\n\n",
|
"Exception 04: OVERFLOW",
|
||||||
"Exception 05: BOUND EXCEPTION\n\n",
|
"Exception 05: BOUND EXCEPTION",
|
||||||
"Exception 06: INVALID OPCODE\n\n",
|
"Exception 06: INVALID OPCODE",
|
||||||
"Exception 07: FPU NOT AVAILABLE\n\n",
|
"Exception 07: FPU NOT AVAILABLE",
|
||||||
"Exception 08: DOUBLE FAULT\n\n",
|
"Exception 08: DOUBLE FAULT",
|
||||||
"Exception 09: COPROCESSOR SEGMENT OVERRUN\n\n",
|
"Exception 09: COPROCESSOR SEGMENT OVERRUN",
|
||||||
"Exception 0A: INVALID TSS\n\n",
|
"Exception 0A: INVALID TSS",
|
||||||
"Exception 0B: SEGMENT NOT PRESENT\n\n",
|
"Exception 0B: SEGMENT NOT PRESENT",
|
||||||
"Exception 0C: STACK EXCEPTION\n\n",
|
"Exception 0C: STACK EXCEPTION",
|
||||||
"Exception 0D: GENERAL PROTECTION FAULT\n\n",
|
"Exception 0D: GENERAL PROTECTION FAULT",
|
||||||
"Exception 0E: PAGE FAULT\n\n",
|
"Exception 0E: PAGE FAULT",
|
||||||
"Exception 0F: Reserved\n\n",
|
"Exception 0F: Reserved",
|
||||||
"Exception 10: COPROCESSOR ERROR\n\n",
|
"Exception 10: COPROCESSOR ERROR",
|
||||||
"Exception 11: ALIGNMENT CHECK\n\n",
|
"Exception 11: ALIGNMENT CHECK",
|
||||||
"Exception 12: MACHINE CHECK\n\n"
|
"Exception 12: MACHINE CHECK"
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCREEN_ATTR 0x1F // Bright white on blue background
|
#define SCREEN_ATTR 0x1F // Bright white on blue background
|
||||||
|
@ -38,14 +38,6 @@ static const CHAR *i386ExceptionDescriptionText[] =
|
||||||
static ULONG i386_ScreenPosX = 0;
|
static ULONG i386_ScreenPosX = 0;
|
||||||
static ULONG i386_ScreenPosY = 0;
|
static ULONG i386_ScreenPosY = 0;
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void
|
|
||||||
i386PrintChar(CHAR chr, ULONG x, ULONG y)
|
|
||||||
{
|
|
||||||
MachVideoPutChar(chr, SCREEN_ATTR, x, y);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
i386PrintText(CHAR *pszText)
|
i386PrintText(CHAR *pszText)
|
||||||
{
|
{
|
||||||
|
@ -96,18 +88,17 @@ PrintText(const CHAR *Format, ...)
|
||||||
static void
|
static void
|
||||||
i386PrintFrames(PKTRAP_FRAME TrapFrame)
|
i386PrintFrames(PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
FRAME *Frame;
|
FRAME* Frame;
|
||||||
|
|
||||||
PrintText("Frames:\n");
|
PrintText("Frames:\n");
|
||||||
|
for (Frame =
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
for (Frame = (FRAME*)TrapFrame->Ebp;
|
(FRAME*)TrapFrame->Ebp;
|
||||||
Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
|
|
||||||
Frame = Frame->Next)
|
|
||||||
#else
|
#else
|
||||||
for (Frame = (FRAME*)TrapFrame->TrapFrame;
|
(FRAME*)TrapFrame->TrapFrame;
|
||||||
Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
|
|
||||||
Frame = Frame->Next)
|
|
||||||
#endif
|
#endif
|
||||||
|
Frame != NULL && (ULONG_PTR)Frame < STACKADDR;
|
||||||
|
Frame = Frame->Next)
|
||||||
{
|
{
|
||||||
PrintText("%p ", Frame->Address);
|
PrintText("%p ", Frame->Address);
|
||||||
}
|
}
|
||||||
|
@ -126,7 +117,8 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST
|
||||||
|
|
||||||
PrintText("An error occured in " VERSION "\n"
|
PrintText("An error occured in " VERSION "\n"
|
||||||
"Report this error on the ReactOS Bug Tracker: https://jira.reactos.org\n\n"
|
"Report this error on the ReactOS Bug Tracker: https://jira.reactos.org\n\n"
|
||||||
"0x%02lx: %s\n", TrapIndex, i386ExceptionDescriptionText[TrapIndex]);
|
"0x%02lx: %s\n\n", TrapIndex, i386ExceptionDescriptionText[TrapIndex]);
|
||||||
|
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
PrintText("EAX: %.8lx ESP: %.8lx CR0: %.8lx DR0: %.8lx\n",
|
PrintText("EAX: %.8lx ESP: %.8lx CR0: %.8lx DR0: %.8lx\n",
|
||||||
TrapFrame->Eax, TrapFrame->HardwareEsp, Special->Cr0, TrapFrame->Dr0);
|
TrapFrame->Eax, TrapFrame->HardwareEsp, Special->Cr0, TrapFrame->Dr0);
|
||||||
|
@ -136,29 +128,28 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST
|
||||||
TrapFrame->Ecx, TrapFrame->Esi, Special->Cr2, TrapFrame->Dr2);
|
TrapFrame->Ecx, TrapFrame->Esi, Special->Cr2, TrapFrame->Dr2);
|
||||||
PrintText("EDX: %.8lx EDI: %.8lx CR3: %.8lx DR3: %.8lx\n",
|
PrintText("EDX: %.8lx EDI: %.8lx CR3: %.8lx DR3: %.8lx\n",
|
||||||
TrapFrame->Edx, TrapFrame->Edi, Special->Cr3, TrapFrame->Dr3);
|
TrapFrame->Edx, TrapFrame->Edi, Special->Cr3, TrapFrame->Dr3);
|
||||||
PrintText(" DR6: %.8lx\n",
|
PrintText("%*s CR4: %.8lx DR6: %.8lx\n",
|
||||||
TrapFrame->Dr6);
|
41, "", Special->Cr4, TrapFrame->Dr6);
|
||||||
PrintText(" DR7: %.8lx\n\n",
|
PrintText("%*s DR7: %.8lx\n",
|
||||||
TrapFrame->Dr7);
|
62, "", TrapFrame->Dr7);
|
||||||
|
|
||||||
/* NOTE: Segment registers are intrinsically 16 bits. Even if the x86
|
/* NOTE: Segment registers are intrinsically 16 bits. Even if the x86
|
||||||
* KTRAP_FRAME structure stores them as ULONG, only their lower 16 bits
|
* KTRAP_FRAME structure stores them as ULONG, only their lower 16 bits
|
||||||
* are initialized. We thus cast them to USHORT before display. */
|
* are initialized. We thus cast them to USHORT before display. */
|
||||||
PrintText("CS: %.4lx EIP: %.8lx\n",
|
PrintText(" CS: %.4lx EIP: %.8lx\n",
|
||||||
(USHORT)TrapFrame->SegCs, TrapFrame->Eip);
|
(USHORT)TrapFrame->SegCs, TrapFrame->Eip);
|
||||||
PrintText("DS: %.4lx ERROR CODE: %.8lx\n",
|
PrintText(" DS: %.4lx ERROR CODE: %.8lx\n",
|
||||||
(USHORT)TrapFrame->SegDs, TrapFrame->ErrCode);
|
(USHORT)TrapFrame->SegDs, TrapFrame->ErrCode);
|
||||||
PrintText("ES: %.4lx EFLAGS: %.8lx\n",
|
PrintText(" ES: %.4lx EFLAGS: %.8lx\n",
|
||||||
(USHORT)TrapFrame->SegEs, TrapFrame->EFlags);
|
(USHORT)TrapFrame->SegEs, TrapFrame->EFlags);
|
||||||
PrintText("FS: %.4lx GDTR Base: %.8lx Limit: %.4x\n",
|
PrintText(" FS: %.4lx GDTR Base: %.8lx Limit: %.4x\n",
|
||||||
|
// " FS: %.4lx GDTR: Base %.8lx Limit %.4x\n"
|
||||||
(USHORT)TrapFrame->SegFs, Special->Gdtr.Base, Special->Gdtr.Limit);
|
(USHORT)TrapFrame->SegFs, Special->Gdtr.Base, Special->Gdtr.Limit);
|
||||||
PrintText("GS: %.4lx IDTR Base: %.8lx Limit: %.4x\n",
|
PrintText(" GS: %.4lx IDTR Base: %.8lx Limit: %.4x\n",
|
||||||
|
// " GS: %.4lx IDTR: Base %.8lx Limit %.4x\n",
|
||||||
(USHORT)TrapFrame->SegGs, Special->Idtr.Base, Special->Idtr.Limit);
|
(USHORT)TrapFrame->SegGs, Special->Idtr.Base, Special->Idtr.Limit);
|
||||||
PrintText("SS: %.4lx LDTR: %.4lx TR: %.4lx\n\n",
|
PrintText(" SS: %.4lx LDTR: %.4lx TR: %.4lx\n\n",
|
||||||
(USHORT)TrapFrame->HardwareSegSs, Special->Ldtr, Special->Tr);
|
(USHORT)TrapFrame->HardwareSegSs, Special->Ldtr, Special->Tr);
|
||||||
|
|
||||||
i386PrintFrames(TrapFrame); // Display frames
|
|
||||||
InstructionPointer = (PUCHAR)TrapFrame->Eip;
|
|
||||||
#else
|
#else
|
||||||
PrintText("RAX: %.8lx R8: %.8lx R12: %.8lx RSI: %.8lx\n",
|
PrintText("RAX: %.8lx R8: %.8lx R12: %.8lx RSI: %.8lx\n",
|
||||||
TrapFrame->Rax, TrapFrame->R8, 0, TrapFrame->Rsi);
|
TrapFrame->Rax, TrapFrame->R8, 0, TrapFrame->Rsi);
|
||||||
|
@ -169,21 +160,33 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST
|
||||||
PrintText("RDX: %.8lx R11: %.8lx R15: %.8lx RSP: %.8lx\n",
|
PrintText("RDX: %.8lx R11: %.8lx R15: %.8lx RSP: %.8lx\n",
|
||||||
TrapFrame->Rdx, TrapFrame->R11, 0, TrapFrame->Rsp);
|
TrapFrame->Rdx, TrapFrame->R11, 0, TrapFrame->Rsp);
|
||||||
|
|
||||||
PrintText("CS: %.4lx RIP: %.8lx\n",
|
PrintText(" CS: %.4lx RIP: %.8lx\n",
|
||||||
TrapFrame->SegCs, TrapFrame->Rip);
|
TrapFrame->SegCs, TrapFrame->Rip);
|
||||||
PrintText("DS: %.4lx ERROR CODE: %.8lx\n",
|
PrintText(" DS: %.4lx ERROR CODE: %.8lx\n",
|
||||||
TrapFrame->SegDs, TrapFrame->ErrorCode);
|
TrapFrame->SegDs, TrapFrame->ErrorCode);
|
||||||
PrintText("ES: %.4lx EFLAGS: %.8lx\n",
|
PrintText(" ES: %.4lx EFLAGS: %.8lx\n",
|
||||||
TrapFrame->SegEs, TrapFrame->EFlags);
|
TrapFrame->SegEs, TrapFrame->EFlags);
|
||||||
PrintText("FS: %.4lx GDTR Base: %.8lx Limit: %.4x\n",
|
PrintText(" FS: %.4lx GDTR Base: %.8lx Limit: %.4x\n",
|
||||||
TrapFrame->SegFs, Special->Gdtr.Base, Special->Gdtr.Limit);
|
TrapFrame->SegFs, Special->Gdtr.Base, Special->Gdtr.Limit);
|
||||||
PrintText("GS: %.4lx IDTR Base: %.8lx Limit: %.4x\n",
|
PrintText(" GS: %.4lx IDTR Base: %.8lx Limit: %.4x\n",
|
||||||
TrapFrame->SegGs, Special->Idtr.Base, Special->Idtr.Limit);
|
TrapFrame->SegGs, Special->Idtr.Base, Special->Idtr.Limit);
|
||||||
PrintText("SS: %.4lx LDTR: %.4lx TR: %.4lx\n\n",
|
PrintText(" SS: %.4lx LDTR: %.4lx TR: %.4lx\n\n",
|
||||||
TrapFrame->SegSs, Special->Ldtr, Special->Tr);
|
TrapFrame->SegSs, Special->Ldtr, Special->Tr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Display the stack frames */
|
||||||
|
i386PrintFrames(TrapFrame);
|
||||||
|
|
||||||
|
#ifdef _M_IX86
|
||||||
|
InstructionPointer = (PUCHAR)TrapFrame->Eip;
|
||||||
|
#else
|
||||||
InstructionPointer = (PUCHAR)TrapFrame->Rip;
|
InstructionPointer = (PUCHAR)TrapFrame->Rip;
|
||||||
#endif
|
#endif
|
||||||
PrintText("\nInstruction stream: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x \n",
|
/* Adjust IP for #BP (INT 03) or #OF to point to the offending instruction */
|
||||||
|
if ((TrapIndex == 3) || (TrapIndex == 4))
|
||||||
|
InstructionPointer--;
|
||||||
|
|
||||||
|
PrintText("\nInstruction stream: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n",
|
||||||
InstructionPointer[0], InstructionPointer[1],
|
InstructionPointer[0], InstructionPointer[1],
|
||||||
InstructionPointer[2], InstructionPointer[3],
|
InstructionPointer[2], InstructionPointer[3],
|
||||||
InstructionPointer[4], InstructionPointer[5],
|
InstructionPointer[4], InstructionPointer[5],
|
||||||
|
|
|
@ -82,7 +82,7 @@ MACRO(SAVE_CPU_REGS)
|
||||||
push eax
|
push eax
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
/* Set by each exception handler to the address of the description text */
|
/* Set by each exception handler to the index of the description text */
|
||||||
i386ExceptionIndex:
|
i386ExceptionIndex:
|
||||||
.long 0
|
.long 0
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue