diff --git a/src/kernel/assert.cpp b/src/kernel/assert.cpp index e805eb7..8b49865 100644 --- a/src/kernel/assert.cpp +++ b/src/kernel/assert.cpp @@ -9,5 +9,5 @@ void const *symbol_table = nullptr; extern "C" void _PDCLIB_assert(const char *message, const char *function, const char *file, unsigned line) { - panic::panic(message, function, file, line); + panic::panic(message, nullptr, function, file, line); } diff --git a/src/kernel/assert.h b/src/kernel/assert.h index 436166f..2b70bbd 100644 --- a/src/kernel/assert.h +++ b/src/kernel/assert.h @@ -16,6 +16,7 @@ extern void const *symbol_table; __attribute__ ((always_inline)) inline void panic( const char *message = nullptr, + const cpu_state *user = nullptr, const char *function = __builtin_FUNCTION(), const char *file = __builtin_FILE(), uint64_t line = __builtin_LINE()) @@ -28,10 +29,13 @@ inline void panic( // If we aren't the first CPU to panic, cpu.panic will be null if (cpu.panic) { cpu.panic->symbol_data = symbol_table; + cpu.panic->user_state = user; + cpu.panic->message = message; cpu.panic->function = function; cpu.panic->file = file; cpu.panic->line = line; + cpu.panic->cpus = g_num_cpus; *apic_icr = send_nmi_command; @@ -48,12 +52,13 @@ __attribute__ ((always_inline)) inline void kassert( bool check, const char *message = nullptr, + const cpu_state *user = nullptr, const char *function = __builtin_FUNCTION(), const char *file = __builtin_FILE(), uint64_t line = __builtin_LINE()) { if (!check) - panic::panic(message, function, file, line); + panic::panic(message, user, function, file, line); } #define assert(x) kassert((x)) diff --git a/src/kernel/cpu.h b/src/kernel/cpu.h index 6c9571b..065af11 100644 --- a/src/kernel/cpu.h +++ b/src/kernel/cpu.h @@ -21,11 +21,14 @@ struct cpu_state /// Kernel-wide panic information struct panic_data { - void const * symbol_data; - char const * message; - char const * function; - char const * file; + void const *symbol_data; + cpu_state const *user_state; + + char const *message; + char const *function; + char const *file; uint32_t line; + uint16_t cpus; }; diff --git a/src/kernel/interrupts.cpp b/src/kernel/interrupts.cpp index 5e52cf1..4d92220 100644 --- a/src/kernel/interrupts.cpp +++ b/src/kernel/interrupts.cpp @@ -91,11 +91,11 @@ isr_handler(cpu_state *regs) asm volatile ("mov %%dr5, %%r13" ::: "r13"); asm volatile ("mov %%dr6, %%r14" ::: "r14"); asm volatile ("mov %%dr7, %%r15" ::: "r15"); - kassert(false, "Debug exception"); + kassert(false, "Debug exception", regs); break; case isr::isrDoubleFault: - kassert(false, "Double fault"); + kassert(false, "Double fault", regs); break; case isr::isrGPFault: @@ -113,7 +113,7 @@ isr_handler(cpu_state *regs) snprintf(message, sizeof(message), "General Protection Fault, error:%lx%s", regs->errorcode, regs->errorcode & 1 ? " external" : ""); } - kassert(false, message); + kassert(false, message, regs); break; case isr::isrPageFault: { @@ -138,7 +138,7 @@ isr_handler(cpu_state *regs) (regs->errorcode & 0x04) ? " user" : "", (regs->errorcode & 0x08) ? " reserved" : "", (regs->errorcode & 0x10) ? " ip" : ""); - kassert(false, message); + kassert(false, message, regs); } break; @@ -156,7 +156,7 @@ isr_handler(cpu_state *regs) default: snprintf(message, sizeof(message), "Unknown interrupt 0x%lx", regs->interrupt); - kassert(false, message); + kassert(false, message, regs); } // Return the IST for this vector to what it was diff --git a/src/kernel/panic.serial/display.cpp b/src/kernel/panic.serial/display.cpp index f6094c5..8bcc87c 100644 --- a/src/kernel/panic.serial/display.cpp +++ b/src/kernel/panic.serial/display.cpp @@ -113,6 +113,13 @@ print_cpu_state(serial_port &out, const cpu_state ®s) out.write(clear); } +void +print_user_state(serial_port &out, const cpu_state ®s) +{ + out.write("\n\e[1;35m USER:\e[0 "); + print_cpu_state(out, regs); +} + } // namespace panicking // For printf.c diff --git a/src/kernel/panic.serial/display.h b/src/kernel/panic.serial/display.h index 93c8604..37b01bb 100644 --- a/src/kernel/panic.serial/display.h +++ b/src/kernel/panic.serial/display.h @@ -28,5 +28,6 @@ void print_header( void print_cpu(serial_port &out, cpu_data &cpu); void print_callstack(serial_port &out, symbol_table &syms, frame const *fp); void print_cpu_state(serial_port &out, const cpu_state ®s); +void print_user_state(serial_port &out, const cpu_state ®s); } // namespace panicking diff --git a/src/kernel/panic.serial/entry.s b/src/kernel/panic.serial/entry.s index b05caef..9cf48f4 100644 --- a/src/kernel/panic.serial/entry.s +++ b/src/kernel/panic.serial/entry.s @@ -12,7 +12,7 @@ _panic_entry: push_all check_swap_gs - mov r9, rsp + mov rdi, rsp mov rax, [rsp + REGS.rip] push rax diff --git a/src/kernel/panic.serial/main.cpp b/src/kernel/panic.serial/main.cpp index 1ae26f4..ef5efc3 100644 --- a/src/kernel/panic.serial/main.cpp +++ b/src/kernel/panic.serial/main.cpp @@ -22,13 +22,7 @@ panicking::symbol_table &syms = __syms_storage.value; constexpr int order = __ATOMIC_ACQ_REL; extern "C" -void panic_handler( - const void *symbol_data, - const char *message, - const char *function, - const char *file, - uint64_t line, - const cpu_state *regs) +void panic_handler(const cpu_state *regs) { cpu_data &cpu = current_cpu(); panic_data *panic = cpu.panic; @@ -57,6 +51,9 @@ void panic_handler( print_callstack(com1, syms, fp); print_cpu_state(com1, *regs); + if (panic && panic->user_state) + print_user_state(com1, *panic->user_state); + __atomic_clear(&asserting_locked, order); // If we're running on the CPU that panicked, tell the