Rust std, implement sys/pal for my custom OS

Hello everyone,

I am trying to port rust and rust std to my custom OS. (I'm sorry I can't provide the source code of my OS :frowning_face: )
I want to implement stdio related behavior first for debugging purposes (print macros and panic).
But even after implementing both Stdout and Stderr inside sys/pal/customos/ my test program panics when I use the print macro leading into a segfault which is itself triggered by an infinite loop of panic.
Using gdb I found that it is triggered by this portion of code in library/std/src/sync/ :

    #[unstable(feature = "once_cell_try", issue = "109737")]
    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
        F: FnOnce() -> Result<T, E>,
        // Fast path check
        // NOTE: We need to perform an acquire on the state in this method
        // in order to correctly synchronize `LazyLock::force`. This is
        // currently done by calling `self.get()`, which in turn calls
        // `self.is_initialized()`, which in turn performs the acquire.
        if let Some(value) = self.get() {
            return Ok(value);


        // SAFETY: The inner value has been initialized
        Ok(unsafe { self.get_unchecked() })

My question would be, is there some documention, guide or any resource that lists the mandatory work to be done before print macro works on my custom OS ? I already explored most of Rust internal docs, Compiler dev / Std dev but I didn't find any info that could help me.
Thanks in advance for your help, I wish you a good day !

I don't know that such a list exists, but in order to make your problem more debuggable, I suggest you set a panic hook or (if that fails) a panic handler which uses your operating system's own system calls directly to print the panic information. That way, you will be able to see what the panic actually is, even before the somewhat more complex print mechanisms have been made to work.

1 Like

I will try your suggestion, thank you.

Rather than going straight to println!, could you break it down a bit more and go via stdout()? That might make it more tractable.

E.g. add one line at a time and make sure it works.

let stdout = std::io::stdout();
let mut handle = stdout.lock();
handle.write_all(b"hello world")?;

And do the same for stderr.

1 Like

Thanks, with your idea I managed to narrow down the source of the crash.