diff --git a/src/system/kernel/arch/x86/64/stubs.cpp b/src/system/kernel/arch/x86/64/stubs.cpp index fc77e25637..6e904b0f56 100644 --- a/src/system/kernel/arch/x86/64/stubs.cpp +++ b/src/system/kernel/arch/x86/64/stubs.cpp @@ -91,6 +91,41 @@ struct stack_frame { }; +static bool +is_iframe(addr_t frame) +{ + addr_t previousFrame = *(addr_t*)frame; + return ((previousFrame & ~IFRAME_TYPE_MASK) == 0 && previousFrame != 0); +} + + +static void +print_iframe(struct iframe* frame) +{ + bool isUser = IFRAME_IS_USER(frame); + + kprintf("%s iframe at %p (end = %p)\n", isUser ? "user" : "kernel", frame, + isUser ? (uint64*)(frame + 1) : &frame->user_rsp); + + kprintf(" rax 0x%-16lx rbx 0x%-16lx rcx 0x%-16lx rdx 0x%lx\n", + frame->rax, frame->rbx, frame->rcx, frame->rdx); + kprintf(" rsi 0x%-16lx rdi 0x%-16lx rbp 0x%-16lx r8 0x%lx\n", + frame->rsi, frame->rdi, frame->rbp, frame->r8); + kprintf(" r9 0x%-16lx r10 0x%-16lx r11 0x%-16lx r12 0x%lx\n", + frame->r9, frame->r10, frame->r11, frame->r12); + kprintf(" r13 0x%-16lx r14 0x%-16lx r15 0x%-16lx\n", + frame->r13, frame->r14, frame->r15); + kprintf(" rip 0x%-16lx rflags 0x%-16lx", frame->rip, frame->flags); + if (isUser) { + // from user space + kprintf("user rsp 0x%lx", frame->user_rsp); + } + kprintf("\n"); + kprintf(" vector: 0x%lx, error code: 0x%lx\n", frame->vector, + frame->error_code); +} + + void arch_debug_stack_trace(void) { @@ -102,14 +137,25 @@ arch_debug_stack_trace(void) if (rbp == 0) break; - stack_frame* frame = (stack_frame*)rbp; - if (frame->return_address == 0) - break; + if (is_iframe(rbp)) { + struct iframe* frame = (struct iframe*)rbp; + print_iframe(frame); + kprintf("%2d %016lx (+%4ld) %016lx\n", callIndex, rbp, + frame->rbp - rbp, frame->rip); - kprintf("%2d %016lx (+%4ld) %016lx\n", callIndex, rbp, - (addr_t)frame->previous - rbp, frame->return_address); + rbp = frame->rbp; + } else { + stack_frame* frame = (stack_frame*)rbp; + if (frame->return_address == 0) + break; - rbp = (addr_t)frame->previous; + kprintf("%2d %016lx (+%4ld) %016lx\n", callIndex, rbp, + (frame->previous != NULL) + ? (addr_t)frame->previous - rbp : 0, + frame->return_address); + + rbp = (addr_t)frame->previous; + } } }