Skip to content

Miri data race in futex test between volatile write in wait and futex_word.store(1, Ordering::SeqCst) #1009

Description

@lschuermann

Miri has detected the following data race:

$ MIRIFLAGS='-Zmiri-permissive-provenance -Zmiri-disable-isolation -Zmiri-ignore-leaks'
rustup run nightly cargo miri test -p litebox test_futex_multiple_waiters_with_timeout
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.18s
     Running unittests src/lib.rs (target/miri/x86_64-unknown-linux-gnu/debug/deps/litebox-656da94cab53557b)

running 1 test
test sync::futex::tests::test_futex_multiple_waiters_with_timeout ... error: Undefined Behavior: Data race detected between (1) non-atomic read on thread `unnamed-2` and (2) atomic store on thread `sync::futex::te` at alloc117191+0x10
   --> litebox/src/sync/futex.rs:336:9
    |
336 |         futex_word.store(1, Ordering::SeqCst);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (2) just happened here
    |
help: and (1) occurred earlier here
   --> litebox/src/platform/trivial_providers.rs:146:39
    |
146 |             1 | 2 | 4 | 8 => unsafe { ptr.offset(count).read_volatile() },
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: this is on thread `sync::futex::te`
    = note: stack backtrace:
            0: sync::futex::tests::test_futex_multiple_waiters_with_timeout
                at litebox/src/sync/futex.rs:336:9: 336:46
            1: sync::futex::tests::test_futex_multiple_waiters_with_timeout::{closure#0}
                at litebox/src/sync/futex.rs:296:50: 296:50

From a cursory read of the issue, this probably wants "volatile atomic" semantics (rust-lang/unsafe-code-guidelines#615): read should have volatile semantics (only once, non-tearing, ...), but it also synchronizes with an atomic in userspace.

Now, this is somewhat moot: most real targets do use RawConstPtr, which does use assembly, and thus effectively is a stand-in for the currently unsupported volatile atomics and does deliver the correct semantics. However, the (Miri) test should probably use a stand-in with real atomic accesses instead.

Looking at this infrastructure, there might be another actual synchronization bug between the entry.done.store(true, Ordering::Relaxed) and entry.get().done.load(Ordering::Acquire), but I'd need to look into this further, and it's a separate issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions