Problem with Backtraces and Rust
Posted: Sat Nov 16, 2024 5:00 pm
Hello!! I've been working on my rust kernel for a few months, and decided to try to implement stack traces as a little side quest because it seemed easy enough. I started off with this implementation:
It was mostly based off of the Stack Trace article on the wiki, besides the recursion limit because the Limine bootloader specification says that a null frame is pushed to the stack.
Unfortunately, when I run this function, rbp is instantly null. I looked in the assembly, and rust is making frame pointers (I enabled the force_frame_pointers codegen flag to make sure), and I made sure the function wasn't being inlined. I also tried using a different approach using Redox's stack trace code, but that just ends up with a page fault.
I am reaching my limit of knowledge with assembly, and for the life of me can't find why this refuses to work. Would greatly appreciate any help because I am completely stumped.
Here's a version of my kernel with 90% of the unnecessary-for-this code stripped out: https://github.com/quackitsquinn/novos/ ... st-example
Code: Select all
/// Recurses `n` times, then prints the stack trace. This is used to test the stack trace printing.
#[inline(never)]
extern "C" fn recurse(n: u32) {
if n == 0 {
sprintln!("Printing stack trace");
print_trace();
sprintln!(".. Finished printing stack trace");
return;
}
recurse(n - 1);
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct StackFrame {
pub rbp: *const StackFrame,
pub rip: *const (),
}
pub fn print_trace() {
let mut rbp: *const StackFrame;
unsafe {
asm!("mov {}, rbp", out(reg) rbp);
}
while !rbp.is_null() {
let frame = unsafe { ptr::read_unaligned(rbp) };
sprintln!("{:#?}", frame);
rbp = frame.rbp;
}
Unfortunately, when I run this function, rbp is instantly null. I looked in the assembly, and rust is making frame pointers (I enabled the force_frame_pointers codegen flag to make sure), and I made sure the function wasn't being inlined. I also tried using a different approach using Redox's stack trace code, but that just ends up with a page fault.
I am reaching my limit of knowledge with assembly, and for the life of me can't find why this refuses to work. Would greatly appreciate any help because I am completely stumped.
Here's a version of my kernel with 90% of the unnecessary-for-this code stripped out: https://github.com/quackitsquinn/novos/ ... st-example