Page 1 of 1

Problem with Backtraces and Rust

Posted: Sat Nov 16, 2024 5:00 pm
by quackitsquinn
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:

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;
    }
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

Re: Problem with Backtraces and Rust

Posted: Sun Nov 17, 2024 1:14 pm
by Octocontrabass
Have you checked the stack contents using a debugger?

Re: Problem with Backtraces and Rust

Posted: Mon Nov 18, 2024 12:57 pm
by quackitsquinn
Ok, so I loaded everything into GDB and noticed something really weird. rbp is null going into the function. Turns out,.cargo/config.toml was not properly giving rustc the correct arguments, and using the RUSTFLAGS env it fixed it. I don't know what I saw that made me think it was creating frame pointers, but it turns out I thought incorrectly.

Time to figure out why my config wasn't working.. woo