Skip to content

Data race false positive due to delayed allocation optimization #3242

Closed
rust-lang/rust
#129828
@RalfJung

Description

@RalfJung

The following code should be fine, but Miri raises an error:

use std::sync::atomic::Ordering::*;
use std::sync::atomic::*;

static P: AtomicPtr<u8> = AtomicPtr::new(core::ptr::null_mut());

fn main() {
    // Create the local variable, and initialize it.
    let mut val: u8 = 0;

    let t1 = std::thread::spawn(|| {
        while P.load(Relaxed).is_null() {
            std::hint::spin_loop();
        }
        unsafe {
            // Initialize `*P`.
            let ptr = P.load(Relaxed);
            *ptr = 127;
        }
    });

    // Actually generate memory for the local variable.
    // This is the time its value is actually written to memory:
    // that's *after* the thread above was spawned!
    P.store(std::ptr::addr_of_mut!(val), Relaxed);
    
    // Wait for the thread to be done.
    t1.join().unwrap();

    // Read initialized value.
    assert_eq!(val, 127);
}

The issue has been described well by CAD97 here:

Without having dived into Miri, it likely is a false positive due to places not being allocated into memory until their reference is taken. It's an optimization for most cases (there's a lot of bookkeeping happening for allocations in Miri) but results in a false positive here. Assuming that's a correct assessment, the fix would be to assign a timestamp corresponding to the local place initialization when reifying into an allocation, instead of the timestamp of the reification itself.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-data-raceArea: data race detectorC-bugCategory: This is a bug.I-false-UBImpact: makes Miri falsely report UB, i.e., a false positive (with default settings)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions