diff --git a/kernel/src/arch/x86_64/CPU.cpp b/kernel/src/arch/x86_64/CPU.cpp index 56606059..5a725e88 100644 --- a/kernel/src/arch/x86_64/CPU.cpp +++ b/kernel/src/arch/x86_64/CPU.cpp @@ -184,11 +184,9 @@ namespace CPU u64 instruction; }; - void get_stack_trace(void (*callback)(u64, void*), void* arg) + static void backtrace_impl(u64 base_pointer, void (*callback)(u64, void*), void* arg) { - u64 rbp; - asm volatile("mov %%rbp, %0" : "=r"(rbp)); - StackFrame* current_frame = (StackFrame*)rbp; + StackFrame* current_frame = (StackFrame*)base_pointer; // FIXME: Validate that the frame itself is readable, might span across multiple pages while (current_frame && MemoryManager::validate_readable_page((u64)current_frame)) { @@ -197,30 +195,32 @@ namespace CPU } } + void get_stack_trace(void (*callback)(u64, void*), void* arg) + { + u64 rbp; + asm volatile("mov %%rbp, %0" : "=r"(rbp)); + return backtrace_impl(rbp, callback, arg); + } + void print_stack_trace() { u64 rbp; int frame_index = 0; asm volatile("mov %%rbp, %0" : "=r"(rbp)); - StackFrame* current_frame = (StackFrame*)rbp; - // FIXME: Validate that the frame itself is readable, might span across multiple pages - while (current_frame && MemoryManager::validate_readable_page((u64)current_frame)) - { - kinfoln("#%d at %p", frame_index++, (void*)current_frame->instruction); - current_frame = current_frame->next; - } + return backtrace_impl( + rbp, + [](u64 instruction, void* arg) { + int* ptr = (int*)arg; + kinfoln("#%d at %p", *ptr, (void*)instruction); + (*ptr)++; + }, + &frame_index); } void get_stack_trace_at(Registers* regs, void (*callback)(u64, void*), void* arg) { callback(regs->rip, arg); - StackFrame* current_frame = (StackFrame*)regs->rbp; - // FIXME: Validate that the frame itself is readable, might span across multiple pages - while (current_frame && MemoryManager::validate_readable_page((u64)current_frame)) - { - callback(current_frame->instruction, arg); - current_frame = current_frame->next; - } + return backtrace_impl(regs->rbp, callback, arg); } void print_stack_trace_at(Registers* regs)