Search code examples
memory-managementrustruntimepanic

What happens to stack/heap allocated types when a runtime panic occurs?


What happens to the types that are allocated on the heap or stack before a panic occurs? Is a destructor called so that the types are deallocated? Do they linger around in the memory waiting to be overwritten by some other process? Or is it something else entirely?

I've no idea since I'm new to Rust and systems programming in general.


Solution

  • By default, the stack will be unwound and destructors are run. You can prove this for yourself:

    struct Noisy;
    
    impl Drop for Noisy {
        fn drop(&mut self) {
            println!("Dropping!");
        }
    }
    
    fn main() {
        let _on_stack = Noisy;
        let _on_heap = Box::new(Noisy);
    
        panic!("Oh no!");
    }
    

    This will print:

    Dropping!
    Dropping!
    

    Note that there's no real difference in stack or heap here. Any heap-allocated item is going to have something on the stack pointing to it. When the handle on the stack goes out of scope, it cleans up the heap resources.


    The stack is unwound until it exits from the current thread (if it's the main thread, the program exits). It's also possible to use catch_unwind. Beware using this though:

    It is not recommended to use this function for a general try/catch mechanism. [...] Note that this function may not catch all panics in Rust.

    Note that I said by default. You can also compile with an option whereby panics translate directly into aborting the process. At that point, the process is over and no more destructors will be run.

    If you panic in a destructor, then it's also game over: the process will be aborted.