From f77ac794c4dfc4a4f5840ae4b06bad1698095f67 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 6 Sep 2023 01:57:13 +0200 Subject: [PATCH] show useful info on kernel crash screen --- + | 15 ++++++ src/kernel/include/internal/io.h | 5 ++ src/kernel/lib/havarie.c | 93 ++++++++++++++++++++++++++++++-- src/kernel/lib/text_screen.c | 2 - 4 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 + diff --git a/+ b/+ new file mode 100644 index 0000000..ca0ccec --- /dev/null +++ b/+ @@ -0,0 +1,15 @@ +#ifndef _CLIPPER_IO_H_ +#define _CLIPPER_IO_H_ + +#include + +inline void outb(uint16_t port, uint8_t val) { + asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port) : "memory"); +} + +inline uint8_t peek(void* addr) { + uint8_t val; + asm volatile ("mov [%addr], %%eax" : : "m"(addr) : "eax"); +} + +#endif // _CLIPPER_IO_H_ diff --git a/src/kernel/include/internal/io.h b/src/kernel/include/internal/io.h index 77c3917..0f788df 100644 --- a/src/kernel/include/internal/io.h +++ b/src/kernel/include/internal/io.h @@ -7,4 +7,9 @@ inline void outb(uint16_t port, uint8_t val) { asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port) : "memory"); } +inline uint8_t peek(void* addr) { + uint32_t ret = 3; + return ret; +} + #endif // _CLIPPER_IO_H_ diff --git a/src/kernel/lib/havarie.c b/src/kernel/lib/havarie.c index bba30c7..7ed816f 100644 --- a/src/kernel/lib/havarie.c +++ b/src/kernel/lib/havarie.c @@ -1,6 +1,8 @@ #include "internal/havarie.h" #include "internal/text_screen.h" +#include "stdlib.h" +#include "string.h" void capsize() { print_havarie_msg(); @@ -11,6 +13,73 @@ void capsize() { for(;;); } +static inline +uint8_t peek(void* addr) { + uint32_t ret; + asm ( "push %%fs\n\t" + "mov $0, %%eax\n\t" + "mov %%ax, %%fs\n\t" + "mov %%fs:(%1), %0\n\t" + "pop %%fs" + : "=r"(ret) : "r"(addr) ); + return ret; +} + +static +void dump_stack(uint8_t col, uint8_t row) { + tscursor_set(col, row); + tsputs("Stack dump", TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_LIGHT_BLUE); + row++; + + tscursor_set(col, row); + tsputs(" 0 1 2 3 4 5 6 7 8 9 A B C D E F", TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_GRAY); + row++; + + int esp, ebp; + asm("mov %%esp, %[esp]\n" + "mov %%ebp, %[ebp]\n" + : [esp]"=m" (esp), [ebp]"=m" (ebp) + ); + + int start_address = esp & ~0xF; + char tmp[16]; + for (int table_row = 0; table_row < 16; table_row++) { + tscursor_set(col, row); + + itoa(start_address, tmp, 16); + size_t len = strlen(tmp); + + char* src = tmp + len - 1; + char* dst = tmp + 7; + + if (len < 9) { + do { + *dst-- = *src--; + } while(src >= tmp); + + do { + *dst-- = '0'; + } while (src != dst); + } + + tsputs(tmp, TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_GRAY); + tsprintf(" "); + + for (int table_col = 0; table_col < 4; table_col++) { + uint8_t x = peek((void*)(long)(start_address + 4 * table_col + 0)); + uint8_t y = peek((void*)(long)(start_address + 4 * table_col + 1)); + uint8_t z = peek((void*)(long)(start_address + 4 * table_col + 2)); + uint8_t w = peek((void*)(long)(start_address + 4 * table_col + 3)); + + tsprintf("%02x %02x %02x %02x ", x, y, z, w); + } + + row++; + + start_address -= 0x10; + } +} + void print_havarie_msg() { tsclear_screen(); tscursor_set(0, 0); @@ -30,8 +99,24 @@ void print_havarie_msg() { [esi]"=m" (esi), [edi]"=m" (edi), [esp]"=m" (esp), [ebp]"=m" (ebp) ); - tsprintf("eax=0x%08x\t\tesi=0x%08x\n", eax, esi); - tsprintf("ebx=0x%08x\t\tedi=0x%08x\n", ebx, edi); - tsprintf("ecx=0x%08x\t\tesp=0x%08x\n", ecx, esp); - tsprintf("edx=0x%08x\t\tebp=0x%08x\n", edx, ebp); + tsputs("Registers\n", TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_LIGHT_BLUE); + tsprintf("eax=0x%08x\nebx=0x%08x\necx=0x%08x\nedx=0x%08x\n\n", eax, ebx, ecx, edx); + tsprintf("esi=0x%08x\nedi=0x%08x\nesp=0x%08x\nebp=0x%08x\n\n", esi, edi, esp, ebp); + + short cs, ds, es, ss, fs, gs; + asm("mov %%cs, %[cs]\n" + "mov %%ds, %[ds]\n" + "mov %%es, %[es]\n" + "mov %%ss, %[ss]\n" + "mov %%fs, %[fs]\n" + "mov %%gs, %[gs]\n" + : [cs]"=m" (cs), [ds]"=m" (ds), [es]"=m" (es), + [ss]"=m" (ss), [fs]"=m" (fs), [gs]"=m" (gs) + ); + + tsputs("\nSegments\n", TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_LIGHT_BLUE); + tsprintf("cs=%08x\nds=%08x\nes=%08x\n\n", cs, ds, es); + tsprintf("ss=%08x\nfs=%08x\ngs=%08x\n\n", ss, fs, gs); + + dump_stack(18, 3); } diff --git a/src/kernel/lib/text_screen.c b/src/kernel/lib/text_screen.c index 4cc0df9..e48ac5c 100644 --- a/src/kernel/lib/text_screen.c +++ b/src/kernel/lib/text_screen.c @@ -121,8 +121,6 @@ const char* decode_format_specifier_field_width(const char* str, struct printf_f tmp[i] = *str++; } - tmp[0] = '8'; - tmp[1] = 0; tmp[i] = '\0'; data->field_size = atoi(tmp);