diff --git a/arch/x86_64/panic.c b/arch/x86_64/panic.c index 21afab1..7840459 100644 --- a/arch/x86_64/panic.c +++ b/arch/x86_64/panic.c @@ -1,8 +1,11 @@ #include +#include #include #include #include #include +#include +#include #include #define R_CF 0 @@ -166,36 +169,64 @@ static void print_stack_item(uintptr_t addr) printk("%s", buf); } -static void print_stack_trace(uintptr_t ip, uintptr_t *bp) +static bool read_stack_frame( + struct address_space *space, + uintptr_t bp, + struct stack_frame *out) { - struct stack_frame *stk = (struct stack_frame *)bp; + if (bp >= VM_PAGEMAP_BASE) { + *out = *(struct stack_frame *)out; + return true; + } + + if (!space) { + return false; + } + + size_t tmp; + kern_status_t status + = address_space_read(space, bp, sizeof *out, out, &tmp); + return status == KERN_OK; +} + +static void print_stack_trace( + struct address_space *space, + uintptr_t ip, + uintptr_t bp) +{ + struct stack_frame stk; + if (!read_stack_frame(space, bp, &stk)) { + return; + } 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; + while (current_frame < max_frames) { + uintptr_t addr = stk.rip; print_stack_item(addr); - stk = (struct stack_frame *)stk->rbp; + bp = stk.rbp; + if (!read_stack_frame(space, bp, &stk)) { + break; + } current_frame++; } } void ml_print_stack_trace(uintptr_t ip) { - uintptr_t *bp; + struct task *task = current_task(); + struct address_space *space = task ? task->t_address_space : NULL; + uintptr_t bp; asm volatile("mov %%rbp, %0" : "=r"(bp)); - print_stack_trace(ip, bp); + print_stack_trace(space, ip, bp); } void ml_print_stack_trace_irq(struct ml_cpu_context *ctx) { - print_stack_trace(ctx->rip, (uintptr_t *)ctx->rbp); + struct task *task = current_task(); + struct address_space *space = task ? task->t_address_space : NULL; + print_stack_trace(space, ctx->rip, ctx->rbp); }