Skip to content

miri reports undefined behavior #13

Description

@eric-seppanen

This unit test reports undefined behavior in miri:

#[test]
fn oops() {
    executor::run(async {
        let (s, r) = async_channel::unbounded();

        std::thread::spawn(move || {
            s.send_blocking("42").unwrap();
        });

        // Receive the value.
        let res = r.recv().await;
        assert_eq!(res, Ok("42"));
    })
}

Miri output:

test tests::oops ... error: Undefined Behavior: trying to retag from <90602> for SharedReadWrite permission at alloc22794[0x0], but that tag does not exist in the borrow stack for this location
   --> /home/eric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/non_null.rs:401:18
    |
401 |         unsafe { &*self.as_ptr().cast_const() }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                  |
    |                  trying to retag from <90602> for SharedReadWrite permission at alloc22794[0x0], but that tag does not exist in the borrow stack for this location
    |                  this error occurs as part of retag at alloc22794[0x0..0x28]
    |
    = 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
help: <90602> was created by a SharedReadWrite retag at offsets [0x18..0x51]
   --> src/lib.rs:6:9
    |
6   | /         executor::run(async {
7   | |             let (s, r) = async_channel::unbounded();
8   | |
9   | |             std::thread::spawn(move || {
...   |
15  | |             assert_eq!(res, Ok("42"));
16  | |         })
    | |__________^
    = note: BACKTRACE (of the first span) on thread `tests::oops`:
    = note: inside `std::ptr::NonNull::<alloc::sync::ArcInner<executor::Task<()>>>::as_ref::<'_>` at /home/eric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/non_null.rs:401:18: 401:46
    = note: inside `std::sync::Arc::<executor::Task<()>>::inner` at /home/eric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/sync.rs:1796:18: 1796:35
    = note: inside `<std::sync::Arc<executor::Task<()>> as std::clone::Clone>::clone` at /home/eric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/sync.rs:2075:24: 2075:36
    = note: inside `<std::mem::ManuallyDrop<std::sync::Arc<executor::Task<()>>> as std::clone::Clone>::clone` at /home/eric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/mem/manually_drop.rs:51:5: 51:13
    = note: inside `woke::increase_refcount::<executor::Task<()>>` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/woke-0.0.4/src/lib.rs:38:44: 38:55
    = note: inside `woke::clone_arc_raw::<executor::Task<()>>` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/woke-0.0.4/src/lib.rs:42:5: 42:33
    = note: inside `<std::task::Waker as std::clone::Clone>::clone` at /home/eric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/task/wake.rs:514:29: 514:71
    = note: inside `event_listener::TaskRef::<'_>::into_task` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/event-listener-5.2.0/src/lib.rs:1322:47: 1322:60
    = note: inside `event_listener::sys::<impl event_listener::Inner<()>>::register` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/event-listener-5.2.0/src/std.rs:165:45: 165:61
    = note: inside `event_listener::InnerListener::<(), std::sync::Arc<event_listener::Inner<()>>>::poll_internal` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/event-listener-5.2.0/src/lib.rs:1159:15: 1160:65
    = note: inside `<event_listener::EventListener as std::future::Future>::poll` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/event-listener-5.2.0/src/lib.rs:878:17: 878:54
    = note: inside `<event_listener_strategy::NonBlocking<'_> as event_listener_strategy::Strategy<'_>>::poll::<(), event_listener::EventListener>` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/event-listener-strategy-0.5.0/src/lib.rs:467:20: 472:23
    = note: inside `<async_channel::RecvInner<'_, &str> as event_listener_strategy::EventListenerFuture>::poll_with_strategy::<'_, event_listener_strategy::NonBlocking<'_>>` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/async-channel-2.2.0/src/lib.rs:1196:24: 1196:66
    = note: inside `<event_listener_strategy::FutureWrapper<async_channel::RecvInner<'_, &str>> as std::future::Future>::poll` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/event-listener-strategy-0.5.0/src/lib.rs:381:9: 383:70
    = note: inside `<async_channel::Recv<'_, &str> as std::future::Future>::poll` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/event-listener-strategy-0.5.0/src/lib.rs:259:17: 259:52
note: inside closure
   --> src/lib.rs:14:32
    |
14  |             let res = r.recv().await;
    |                                ^^^^^
    = note: inside `<std::sync::Arc<executor::Task<()>> as executor::Pendable>::is_pending` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/executor-0.8.4/src/lib.rs:47:18: 47:47
    = note: inside `executor::Executor::poll_tasks` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/executor-0.8.4/src/lib.rs:85:16: 85:33
    = note: inside `executor::Executor::run::<()>` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/executor-0.8.4/src/lib.rs:58:9: 58:26
    = note: inside `executor::run::<(), {async block@src/lib.rs:6:23: 16:10}>` at /home/eric/.cargo/registry/src/index.crates.io-6f17d22bba15001f/executor-0.8.4/src/lib.rs:98:5: 98:50
note: inside `tests::oops`
   --> src/lib.rs:6:9
    |
6   | /         executor::run(async {
7   | |             let (s, r) = async_channel::unbounded();
8   | |
9   | |             std::thread::spawn(move || {
...   |
15  | |             assert_eq!(res, Ok("42"));
16  | |         })
    | |__________^

This is with async-channel = "2.2.0", executor = "0.8.4".

The toolchain that was used:

$ rustc +nightly -V
rustc 1.78.0-nightly (d18480b84 2024-03-04)

Activity

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions