https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0d00a5d6eb977461e61bc…
commit 0d00a5d6eb977461e61bc552647358b9f1d71e3f
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat Jan 1 04:49:06 2022 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sat Jan 1 05:04:23 2022 +0100
[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.
---
boot/freeldr/freeldr/arch/i386/i386bug.c | 117 +++++++++++++++---------------
boot/freeldr/freeldr/arch/i386/i386trap.S | 2 +-
2 files changed, 61 insertions(+), 58 deletions(-)
diff --git a/boot/freeldr/freeldr/arch/i386/i386bug.c
b/boot/freeldr/freeldr/arch/i386/i386bug.c
index 908ad46950c..7e03deacdcb 100644
--- a/boot/freeldr/freeldr/arch/i386/i386bug.c
+++ b/boot/freeldr/freeldr/arch/i386/i386bug.c
@@ -5,31 +5,31 @@
typedef struct _FRAME
{
- struct _FRAME *Next;
- void *Address;
+ struct _FRAME* Next;
+ PVOID Address;
} FRAME;
static const CHAR *i386ExceptionDescriptionText[] =
{
- "Exception 00: DIVIDE BY ZERO\n\n",
- "Exception 01: DEBUG EXCEPTION\n\n",
- "Exception 02: NON-MASKABLE INTERRUPT EXCEPTION\n\n",
- "Exception 03: BREAKPOINT (INT 3)\n\n",
- "Exception 04: OVERFLOW\n\n",
- "Exception 05: BOUND EXCEPTION\n\n",
- "Exception 06: INVALID OPCODE\n\n",
- "Exception 07: FPU NOT AVAILABLE\n\n",
- "Exception 08: DOUBLE FAULT\n\n",
- "Exception 09: COPROCESSOR SEGMENT OVERRUN\n\n",
- "Exception 0A: INVALID TSS\n\n",
- "Exception 0B: SEGMENT NOT PRESENT\n\n",
- "Exception 0C: STACK EXCEPTION\n\n",
- "Exception 0D: GENERAL PROTECTION FAULT\n\n",
- "Exception 0E: PAGE FAULT\n\n",
- "Exception 0F: Reserved\n\n",
- "Exception 10: COPROCESSOR ERROR\n\n",
- "Exception 11: ALIGNMENT CHECK\n\n",
- "Exception 12: MACHINE CHECK\n\n"
+ "Exception 00: DIVIDE BY ZERO",
+ "Exception 01: DEBUG EXCEPTION",
+ "Exception 02: NON-MASKABLE INTERRUPT EXCEPTION",
+ "Exception 03: BREAKPOINT (INT 3)",
+ "Exception 04: OVERFLOW",
+ "Exception 05: BOUND EXCEPTION",
+ "Exception 06: INVALID OPCODE",
+ "Exception 07: FPU NOT AVAILABLE",
+ "Exception 08: DOUBLE FAULT",
+ "Exception 09: COPROCESSOR SEGMENT OVERRUN",
+ "Exception 0A: INVALID TSS",
+ "Exception 0B: SEGMENT NOT PRESENT",
+ "Exception 0C: STACK EXCEPTION",
+ "Exception 0D: GENERAL PROTECTION FAULT",
+ "Exception 0E: PAGE FAULT",
+ "Exception 0F: Reserved",
+ "Exception 10: COPROCESSOR ERROR",
+ "Exception 11: ALIGNMENT CHECK",
+ "Exception 12: MACHINE CHECK"
};
#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_ScreenPosY = 0;
-#if 0
-static void
-i386PrintChar(CHAR chr, ULONG x, ULONG y)
-{
- MachVideoPutChar(chr, SCREEN_ATTR, x, y);
-}
-#endif
-
static void
i386PrintText(CHAR *pszText)
{
@@ -96,18 +88,17 @@ PrintText(const CHAR *Format, ...)
static void
i386PrintFrames(PKTRAP_FRAME TrapFrame)
{
- FRAME *Frame;
+ FRAME* Frame;
PrintText("Frames:\n");
+ for (Frame =
#ifdef _M_IX86
- for (Frame = (FRAME*)TrapFrame->Ebp;
- Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
- Frame = Frame->Next)
+ (FRAME*)TrapFrame->Ebp;
#else
- for (Frame = (FRAME*)TrapFrame->TrapFrame;
- Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
- Frame = Frame->Next)
+ (FRAME*)TrapFrame->TrapFrame;
#endif
+ Frame != NULL && (ULONG_PTR)Frame < STACKADDR;
+ Frame = Frame->Next)
{
PrintText("%p ", Frame->Address);
}
@@ -126,7 +117,8 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame,
PKSPECIAL_REGIST
PrintText("An error occured in " VERSION "\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
PrintText("EAX: %.8lx ESP: %.8lx CR0: %.8lx DR0:
%.8lx\n",
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);
PrintText("EDX: %.8lx EDI: %.8lx CR3: %.8lx DR3:
%.8lx\n",
TrapFrame->Edx, TrapFrame->Edi, Special->Cr3, TrapFrame->Dr3);
- PrintText(" DR6:
%.8lx\n",
- TrapFrame->Dr6);
- PrintText(" DR7:
%.8lx\n\n",
- TrapFrame->Dr7);
+ PrintText("%*s CR4: %.8lx DR6: %.8lx\n",
+ 41, "", Special->Cr4, TrapFrame->Dr6);
+ PrintText("%*s DR7: %.8lx\n",
+ 62, "", TrapFrame->Dr7);
/* NOTE: Segment registers are intrinsically 16 bits. Even if the x86
* KTRAP_FRAME structure stores them as ULONG, only their lower 16 bits
* 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);
- PrintText("DS: %.4lx ERROR CODE: %.8lx\n",
+ PrintText(" DS: %.4lx ERROR CODE: %.8lx\n",
(USHORT)TrapFrame->SegDs, TrapFrame->ErrCode);
- PrintText("ES: %.4lx EFLAGS: %.8lx\n",
+ PrintText(" ES: %.4lx EFLAGS: %.8lx\n",
(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);
- 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);
- 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);
-
- i386PrintFrames(TrapFrame); // Display frames
- InstructionPointer = (PUCHAR)TrapFrame->Eip;
#else
PrintText("RAX: %.8lx R8: %.8lx R12: %.8lx RSI:
%.8lx\n",
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",
TrapFrame->Rdx, TrapFrame->R11, 0, TrapFrame->Rsp);
- PrintText("CS: %.4lx RIP: %.8lx\n",
+ PrintText(" CS: %.4lx RIP: %.8lx\n",
TrapFrame->SegCs, TrapFrame->Rip);
- PrintText("DS: %.4lx ERROR CODE: %.8lx\n",
+ PrintText(" DS: %.4lx ERROR CODE: %.8lx\n",
TrapFrame->SegDs, TrapFrame->ErrorCode);
- PrintText("ES: %.4lx EFLAGS: %.8lx\n",
+ PrintText(" ES: %.4lx EFLAGS: %.8lx\n",
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);
- 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);
- PrintText("SS: %.4lx LDTR: %.4lx TR: %.4lx\n\n",
+ PrintText(" SS: %.4lx LDTR: %.4lx TR: %.4lx\n\n",
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;
#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[2], InstructionPointer[3],
InstructionPointer[4], InstructionPointer[5],
diff --git a/boot/freeldr/freeldr/arch/i386/i386trap.S
b/boot/freeldr/freeldr/arch/i386/i386trap.S
index 0be6ec7e5a2..bbc5367d70d 100644
--- a/boot/freeldr/freeldr/arch/i386/i386trap.S
+++ b/boot/freeldr/freeldr/arch/i386/i386trap.S
@@ -82,7 +82,7 @@ MACRO(SAVE_CPU_REGS)
push eax
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:
.long 0