Что происходит с типами, выделенными стеком / кучей, при возникновении паники во время выполнения?

Что происходит с типами, выделенными в куче или стеке, до возникновения паники? Вызывается ли деструктор для освобождения типов? Они задерживаются в памяти в ожидании перезаписи каким-либо другим процессом? Или это что-то совсем другое?

Понятия не имею, так как я новичок в Rust и системном программировании в целом.


person Chakravarthy Raghunandan    schedule 31.10.2016    source источник


Ответы (1)


По умолчанию стек разматывается и запускаются деструкторы. Вы можете убедиться в этом сами:

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!");
}

Это напечатает:

Dropping!
Dropping!

Обратите внимание, что здесь нет реальной разницы в стеке или куче. Любой элемент, размещенный в куче, будет иметь что-то в стеке, указывающее на него. Когда дескриптор стека выходит за пределы области видимости, он очищает ресурсы кучи.


Стек раскручивается до тех пор, пока не выйдет из текущего потока (если это основной поток, программа завершится). Также можно использовать catch_unwind. Остерегайтесь использовать это:

Не рекомендуется использовать эту функцию для общего механизма try / catch. [...] Обратите внимание, что эта функция может не улавливать все паники в Rust.

Обратите внимание, что я сказал по умолчанию. Вы также можете выполнить компиляцию с опцией, при которой паника напрямую преобразуется в прерывание процесса. На этом процесс завершен, и деструкторы больше не будут запускаться.

Если вы запаникуете в деструкторе, значит, игра окончена: процесс будет прерван.

person Shepmaster    schedule 31.10.2016