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