From 6cf8f4234acda1acbff3c948efed5f14046f35c5 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sat, 6 May 2023 22:18:34 +0100 Subject: [PATCH] x86_64: print stack trace during panic --- arch/x86_64/acpi/smp.cpp | 1 + arch/x86_64/include/socks/machine/panic.h | 5 +- arch/x86_64/panic.c | 65 ++++++++++++++++++++++- kernel/panic.c | 7 +++ 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/arch/x86_64/acpi/smp.cpp b/arch/x86_64/acpi/smp.cpp index da1e634..b753238 100644 --- a/arch/x86_64/acpi/smp.cpp +++ b/arch/x86_64/acpi/smp.cpp @@ -21,6 +21,7 @@ extern "C" void ap_trampoline_exit(void) __this_ap_ok = 1; ml_cpu_block *this_cpu = (ml_cpu_block *)kmalloc(sizeof *this_cpu, VM_NORMAL); + memset(this_cpu, 0x00, sizeof *this_cpu); ml_cpu_block_init(this_cpu); ml_cpu_block_use(this_cpu); diff --git a/arch/x86_64/include/socks/machine/panic.h b/arch/x86_64/include/socks/machine/panic.h index 6441f3e..4bf1366 100644 --- a/arch/x86_64/include/socks/machine/panic.h +++ b/arch/x86_64/include/socks/machine/panic.h @@ -1,9 +1,12 @@ #ifndef SOCKS_X86_64_PANIC_H_ #define SOCKS_X86_64_PANIC_H_ +#include + struct cpu_context; extern void ml_print_cpu_state(struct cpu_context *ctx); -extern void ml_print_stack_trace(struct cpu_context *ctx); +extern void ml_print_stack_trace(uintptr_t ip); +extern void ml_print_stack_trace_irq(struct cpu_context *ctx); #endif diff --git a/arch/x86_64/panic.c b/arch/x86_64/panic.c index d0c7397..e6c4a1c 100644 --- a/arch/x86_64/panic.c +++ b/arch/x86_64/panic.c @@ -1,3 +1,5 @@ +#include "socks/machine/panic.h" +#include "socks/vm.h" #include #include #include @@ -19,6 +21,11 @@ #define R_ID 21 #define R_MAX 21 +struct stack_frame { + uintptr_t rbp; + uintptr_t rip; +} __attribute__((packed)); + const char *pf_rfl_name(int bit) { switch (bit) { @@ -112,7 +119,61 @@ void ml_print_cpu_state(struct cpu_context *ctx) printk(" cr3 %016llx cr4 %016llx", cr3, cr4); } -void ml_print_stack_trace(struct cpu_context *ctx) +static void print_stack_item(uintptr_t addr) { - + if (!addr) { + return; + } + + char buf[64]; + size_t i = 0; + + i += snprintf(buf, sizeof(buf), " [<%p>] ", addr); + + size_t offset = 0; + char name[128]; + int found = -1; + + if (found == 0 && name[0] != '\0') { + i += snprintf(buf + i, sizeof(buf) - i, "%s+0x%lx", name, offset); + } else { + i += snprintf(buf + i, sizeof(buf) - i, "?"); + } + + printk("%s", buf); +} + +static void print_stack_trace(uintptr_t ip, uintptr_t *bp) +{ + struct stack_frame *stk = (struct stack_frame *)bp; + printk("call trace:"); + + print_stack_item(ip); + + int max_frames = 10, current_frame = 0; + while (1) { + if (!vm_virt_to_phys(stk) || + bp == NULL || + current_frame > max_frames) { + break; + } + + uintptr_t addr = stk->rip; + print_stack_item(addr); + + stk = (struct stack_frame *)stk->rbp; + current_frame++; + } +} + +void ml_print_stack_trace(uintptr_t ip) +{ + uintptr_t *bp; + asm volatile("mov %%rbp, %0" : "=r" (bp)); + print_stack_trace(ip, bp); +} + +void ml_print_stack_trace_irq(struct cpu_context *ctx) +{ + print_stack_trace(ctx->rip, (uintptr_t *)ctx->rbp); } diff --git a/kernel/panic.c b/kernel/panic.c index 587bca9..566827b 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -37,6 +37,13 @@ void panic_irq(struct cpu_context *ctx, const char *fmt, ...) WRITE_ONCE(has_panicked, 1); + if (ctx) { + ml_print_stack_trace_irq(ctx); + } else { + uintptr_t ip = (uintptr_t)__builtin_return_address(0); + ml_print_stack_trace(ip); + } + printk("---[ end kernel panic: %s", buf); ml_halt_cpu(); }