Skip to content

Nested panics and std::thread::panicking #143612

Description

@purplesyringa
struct Dropper;
impl Drop for Dropper {
    fn drop(&mut self) {
        catch_unwind(|| panic!()); // two panics alive at the same time
    }
}
let _dropper = Dropper;
panic!();

Should this abort? We often say that "double panics lead to abort", and I think we might even document that, but I've just found out this behavior is surprising to a lot of folks. So I want to ask for T-lang consensus: are double panics explicitly allowed if caught, and only unwinding across a landing pad leads to abort?

If double panics are allowed in this case, then everyone relying on std::thread::panicking is subtly broken. We encounter the same problem as std::uncaught_exception in C++. N4152 had to deprecate std::uncaught_exception and expose a counter instead. I think N4152 explains the problem well enough, but the TL;DR for Rust is that it's impossible to reliably implement something like ScopeGuard, because we'll either notice a panic when there's none (because std::uncaught_exception is set at the beginning anyway), or ignore a panic when it does happen (which is a problem for e.g. MutexGuard currently, see #143471). I have found some unsoundness in the wild (1, 2, 3) due to this.

I don't have a specific proposal to fix this, e.g. I don't think exposing std::thread::panic_count is a good idea, but I at least want this problem to be known.

@rustbot label +T-lang +T-libs-api +T-libs -C-discussion +A-panic

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-panicArea: Panicking machineryI-lang-radarItems that are on lang's radar and will need eventual work or consideration.T-langRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions