Skip to content

Miri detects undefined behavior in the test suite #952

@197g

Description

@197g

(Found while scrolling through https://miri.saethlin.dev/ub?crate=rayon&version=1.5.3)

Undefined Behavior: deallocating while item is protected: [SharedReadOnly for <2273653> (call 593590)]
    --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.3/src/registry.rs:479:9
     |
479  |         })
     |         ^ deallocating while item is protected: [SharedReadOnly for <2273653> (call 593590)]

Since this is a at the end of the closure, is it referring to deallocating a local variable? Such as a dangling reference to the job?


Further investigation running with full backtrace: It seems the issue only occurs when running a multi-threaded tests. The exact location varies from run to run (non-deterministic). The command used to run the test suite for me is:

MIRIFLAGS="-Zmiri-backtrace=full -Zmiri-disable-isolation" cargo +nightly miri test -- --test-threads=2

The location pin-pointed stays the same:

error: Undefined Behavior: deallocating while item is protected: [SharedReadOnly for <18205362> (call 4948034)]
    --> /home/andreas/code/investigate/rayon/rayon-core/src/registry.rs:479:9
     |
479  |         })
     |         ^ deallocating while item is protected: [SharedReadOnly for <18205362> (call 4948034)]
     |
     = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
     = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
             
     = note: inside closure at /home/andreas/code/investigate/rayon/rayon-core/src/registry.rs:479:9
     = note: inside `std::thread::LocalKey::<rayon_core::latch::LockLatch>::try_with::<[closure@rayon_core::registry::Registry::in_worker_cold<[closure@rayon_core::join_context<[closure@src/iter/plumbing/mod.rs:417:17: 425:18], [closure@src/iter/plumbing/mod.rs:426:17: 434:18], iter::collect::consumer::CollectResult<std::vec::Vec<i32>>, iter::collect::consumer::CollectResult<std::vec::Vec<i32>>>::{closure#0}], (iter::collect::consumer::CollectResult<std::vec::Vec<i32>>, iter::collect::consumer::CollectResult<std::vec::Vec<i32>>)>::{closure#0}], (iter::collect::consumer::CollectResult<std::vec::Vec<i32>>, iter::collect::consumer::CollectResult<std::vec::Vec<i32>>)>` at /home/andreas/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:445:16
     = note: inside `std::thread::LocalKey::<rayon_core::latch::LockLatch>::with::<[closure@rayon_core::registry::Registry::in_worker_cold<[closure@rayon_core::join_context<[closure@src/iter/plumbing/mod.rs:417:17: 425:18], [closure@src/iter/plumbing/mod.rs:426:17: 434:18], iter::collect::consumer::CollectResult<std::vec::Vec<i32>>, iter::collect::consumer::CollectResult<std::vec::Vec<i32>>>::{closure#0}], (iter::collect::consumer::CollectResult<std::vec::Vec<i32>>, iter::collect::consumer::CollectResult<std::vec::Vec<i32>>)>::{closure#0}], (iter::collect::consumer::CollectResult<std::vec::Vec<i32>>, iter::collect::consumer::CollectResult<std::vec::Vec<i32>>)>` at /home/andreas/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:421:9
note: inside `rayon_core::registry::Registry::in_worker_cold::<[closure@rayon_core::join_context<[closure@src/iter/plumbing/mod.rs:417:17: 425:18], [closure@src/iter/plumbing/mod.rs:426:17: 434:18], iter::collect::consumer::CollectResult<std::vec::Vec<i32>>, iter::collect::consumer::CollectResult<std::vec::Vec<i32>>>::{closure#0}], (iter::collect::consumer::CollectResult<std::vec::Vec<i32>>, iter::collect::consumer::CollectResult<std::vec::Vec<i32>>)>` at /home/andreas/code/investigate/rayon/rayon-core/src/registry.rs:461:9
    --> /home/andreas/code/investigate/rayon/rayon-core/src/registry.rs:461:9
     |
461  | /         LOCK_LATCH.with(|l| {
462  | |             // This thread isn't a member of *any* thread pool, so just block.
463  | |             debug_assert!(WorkerThread::current().is_null());
464  | |             let job = StackJob::new(
...    |
478  | |             job.into_result()
479  | |         })
     | |__________^
note: inside `rayon_core::registry::in_worker::<[closure@rayon_core::join_context<[closure@src/iter/plumbing/mod.rs:417:17: 425:18], [closure@src/iter/plumbing/mod.rs:426:17: 434:18], iter::collect::consumer::CollectResult<std::vec::Vec<i32>>, iter::collect::consumer::CollectResult<std::vec::Vec<i32>>>::{closure#0}], (iter::collect::consumer::CollectResult<std::vec::Vec<i32>>, iter::collect::consumer::CollectResult<std::vec::Vec<i32>>)>` at /home/andreas/code/investigate/rayon/rayon-core/src/registry.rs:879:13
    --> /home/andreas/code/investigate/rayon/rayon-core/src/registry.rs:879:13
     |
879  |             global_registry().in_worker_cold(op)
     |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions