Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catch panics in critical section of thread::scope #724

Closed
wants to merge 1 commit into from

Conversation

Enkelmann
Copy link
Contributor

The problem

The current implementation of the scope function for generating scoped threads contains a critical section:
If an unwinding panic occurs after execution of the user-provided closure but before all scoped threads are successfully joined then a scoped thread may escape the scope. So we have to ensure that no unwinding panics can occur in this critical section.

Can an unwinding panic occur in the critical section?

Maybe? My investigation into this turned up some obvious candidates for panics, but it could be that they all are aborting panics:

  • The call to wg.wait() may panic on an integer overflow when internally calling Arc::clone(). Luckily, the panic is implemented as an aborting panic.
  • The call to scope.handles.lock().unwrap() may panic if the lock is poisoned. The only way I found to (theoretically) poison the lock is to cause an out-of-memory error. But we are lucky again, since out-of-memory errors themselves already cause aborting panics.
  • The call to .collect() at the end of the critical section may panic when trying to allocate a Vec<_>. To be honest I am not sure whether this can only cause aborting out-of-memory panics or whether there is some corner case where this would cause an unwinding panic. My concern here is that even if we are sure that this only causes aborting panics right now, can we be sure that this is also true for future versions of Rust?

The proposed solution

Just wrap the critical section in a catch_unwind(..) block that promotes unwinding panics to aborting panics until all scoped threads are successfully joined.

@taiki-e
Copy link
Member

taiki-e commented Aug 7, 2021

Hmm, if I understand correctly, there is no way actually to cause this at this time. (That said, we can do this with zero cost using RAII guards that abort on drop.)

@Enkelmann
Copy link
Contributor Author

Hmm, if I understand correctly, there is no way actually to cause this at this time.

At least I hope so. But there is already an accepted RFC for Rust to change the behaviour of out-of-memory panics to unwinding panics on user request. So when this is implemented (it may already be on nightly, I haven't checked) and hits stable, the current implementation will be unsound.

(That said, we can do this with zero cost using RAII guards that abort on drop.)

Ohh, good idea! I should change the code accordingly. Before I start reinventing the wheel: Do you know whether this particular guard is already implemented somewhere?

@taiki-e
Copy link
Member

taiki-e commented Aug 10, 2021

But there is already an accepted RFC for Rust to change the behaviour of out-of-memory panics to unwinding panics on user request. So when this is implemented (it may already be on nightly, I haven't checked) and hits stable, the current implementation will be unsound.

Oh, you are right. The linked RFC is not implemented yet (rust-lang/rust#43596), but I found that there is an unstable feature that does something similar: rust-lang/rust#51245

Do you know whether this particular guard is already implemented somewhere?

I don't remember if it's already in the crossbeam, but it's so small, so I don't mind duplication.

struct Bomb;

impl Drop for Bomb {
    fn drop(&mut self) {
        std::process::abort();
    }
}

let bomb = Bomb;

// processes that may panic...

mem::forget(bomb);

@taiki-e taiki-e added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author label May 28, 2022
bors bot added a commit that referenced this pull request Jul 23, 2022
844: Change panic handling in scoped thread r=taiki-e a=taiki-e

- Panic instead of returning result
- Do not own join handles in main thread

Fixes #816
Closes #724

Co-authored-by: Taiki Endo <[email protected]>
taiki-e added a commit that referenced this pull request Dec 2, 2023
@taiki-e taiki-e mentioned this pull request Dec 2, 2023
@taiki-e taiki-e closed this in #1045 Dec 2, 2023
taiki-e added a commit that referenced this pull request Dec 2, 2023
taiki-e added a commit that referenced this pull request Dec 13, 2023
taiki-e added a commit that referenced this pull request Dec 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crossbeam-utils S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author
Development

Successfully merging this pull request may close these issues.

2 participants