Skip to content

Condvar isn't RefUnwindSafe when building on Mac #118009

@ecton

Description

@ecton
Contributor
use std::sync::{Condvar, Mutex};
fn panic_catcher() {
    let condvar = Condvar::new();
    std::panic::catch_unwind(move || {
        let mutex = Mutex::new(());
        let guard = mutex.lock().unwrap();
        condvar.wait(guard);
    });
}

I expected to see this happen: No errors. This code compiles on Linux, as I would expect based on Condvar's documentation.

Instead, this happened: When compiling on Mac OS, I get this error:

error[E0277]: the type `UnsafeCell<libc::unix::bsd::apple::pthread_cond_t>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    --> src/lib.rs:176:30
     |
176  |       std::panic::catch_unwind(move || {
     |  _____------------------------_^
     | |     |
     | |     required by a bound introduced by this call
177  | |         let mutex = Mutex::new(());
178  | |         let guard = mutex.lock().unwrap();
179  | |         condvar.wait(guard);
180  | |     });
     | |_____^ `UnsafeCell<libc::unix::bsd::apple::pthread_cond_t>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
     |
     = help: within `std::sys::unix::locks::pthread_condvar::AllocatedCondvar`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<libc::unix::bsd::apple::pthread_cond_t>`
note: required because it appears within the type `AllocatedCondvar`
    --> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/sys/unix/locks/pthread_condvar.rs:12:8
     |
12   | struct AllocatedCondvar(UnsafeCell<libc::pthread_cond_t>);
     |        ^^^^^^^^^^^^^^^^
     = note: required for `*mut std::sys::unix::locks::pthread_condvar::AllocatedCondvar` to implement `UnwindSafe`
note: required because it appears within the type `UnsafeCell<*mut AllocatedCondvar>`
    --> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/cell.rs:1987:12
     |
1987 | pub struct UnsafeCell<T: ?Sized> {
     |            ^^^^^^^^^^
note: required because it appears within the type `AtomicPtr<AllocatedCondvar>`
    --> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:186:12
     |
186  | pub struct AtomicPtr<T> {
     |            ^^^^^^^^^
note: required because it appears within the type `LazyBox<AllocatedCondvar>`
    --> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/sys_common/lazy_box.rs:13:19
     |
13   | pub(crate) struct LazyBox<T: LazyInit> {
     |                   ^^^^^^^
note: required because it appears within the type `Condvar`
    --> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/sys/unix/locks/pthread_condvar.rs:14:12
     |
14   | pub struct Condvar {
     |            ^^^^^^^
note: required because it appears within the type `Condvar`
    --> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/sync/condvar.rs:107:12
     |
107  | pub struct Condvar {
     |            ^^^^^^^
note: required because it's used within this closure
    --> src/lib.rs:176:30
     |
176  |     std::panic::catch_unwind(move || {
     |                              ^^^^^^^
note: required by a bound in `catch_unwind`
    --> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:141:40
     |
141  | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
     |                                        ^^^^^^^^^^ required by this bound in `catch_unwind`

On Linux, this code compiles correctly, and the hosted Rust docs for Convdar document this type as UnwindSafe. I'm filing this issue to ask:

Is the current MacOS implementation not actually UnwindSafe? My workaround for this issue is to wrap Condvar in AssertUnwindwSafe, but I would like to confirm this is actually safe. My personal hope is that these sync primitives are UnwindSafe and that this is a safe workaround.

Meta

rustc --version --verbose:

rustc 1.74.0 (79e9716c9 2023-11-13)
binary: rustc
commit-hash: 79e9716c980570bfd1f666e3b16ac583f0168962
commit-date: 2023-11-13
host: x86_64-unknown-linux-gnu
release: 1.74.0
LLVM version: 17.0.4

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Nov 17, 2023
Jules-Bertholet

Jules-Bertholet commented on Nov 17, 2023

@Jules-Bertholet
Contributor

@rustbot label O-macos T-libs

added
O-macosOperating system: macOS
T-libsRelevant to the library team, which will review and decide on the PR/issue.
on Nov 17, 2023
added a commit that references this issue on Nov 17, 2023
Noratrieb

Noratrieb commented on Nov 17, 2023

@Noratrieb
Member

sounds like a bug, there's probably an implementation missing on some MacOS specific sys struct, the unwind safety traits are always forgotten
feel free to send a PR adding it

removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Nov 17, 2023
fzyzcjy

fzyzcjy commented on Dec 2, 2023

@fzyzcjy

Hi, is there any updates? I am seeing the same issue.

Noratrieb

Noratrieb commented on Dec 2, 2023

@Noratrieb
Member

No updates because no one has fixed this yet. Feel free to make a PR and fix if yourself :)

ecton

ecton commented on Dec 3, 2023

@ecton
ContributorAuthor

Is it correct to assume that Condvar is supposed to be UnwindSafe on all platforms? My basic understanding of this is that Condvar should be UnwindSafe and, barring any surprises, the data structures should already be unwind safe and are simply not marked as such.

it seems like this issue likely affects multiple platforms, as similar primitives are used across other sys Condvars without accompanying UnwindSafe impls.

I'm happy to try to put together a PR that adds a test asserting unwind safety (similar tests exist for other data structures) if someone more knowledgeable than me can confirm it is the correct thing to do. This would be my first contribution, which is also why I'm hesitant to throw in a PR about something I'm not sure I fully understand.

added a commit that references this issue on Dec 19, 2023
tomasstranik

tomasstranik commented on Feb 23, 2024

@tomasstranik

What's a current state of this bug, please?

Noratrieb

Noratrieb commented on Feb 23, 2024

@Noratrieb
Member

@ecton said they'd work on here, but nothing seems to have happened. If you want to, you can submit a PR fixing it.

ecton

ecton commented on Feb 23, 2024

@ecton
ContributorAuthor

@ecton said they'd work on here, but nothing seems to have happened. If you want to, you can submit a PR fixing it.

Actually the current state is asking whether it is the correct behavior for all platforms or not. My last comment expressed how I do not have confidence to know that it's the right choice, and was looking for confirmation on the approach before beginning work.

9 remaining items

Loading
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

    C-bugCategory: This is a bug.O-macosOperating system: macOST-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

      Participants

      @ecton@fzyzcjy@tomasstranik@rustbot@Noratrieb

      Issue actions

        Condvar isn't RefUnwindSafe when building on Mac · Issue #118009 · rust-lang/rust