critical-section icon indicating copy to clipboard operation
critical-section copied to clipboard

Mitigate Miri violation

Open Catamantaloedis opened this issue 1 year ago • 4 comments
trafficstars

While testing an embassy project on Windows using Miri, I encountered a hard-to-diagnose violation involving a conflict between writing to and dropping critical-section's GLOBAL_GUARD.

I believe the change proposed in this PR is low-risk and should work exactly the same as before while appeasing Miri and potentially mitigating a program bug.

Minimal project to produce Miri complaint:

Cargo.toml:

// ...
[dependencies]
embassy-executor = { version = "0.5.0", features = ["task-arena-size-131072", "arch-std", "executor-thread", "integrated-timers"] }
embassy-time = { version = "0.3.0", features = ["std"] }

main.rs:

#[embassy_executor::main]
async fn main(_spawner: embassy_executor::Spawner) {
    loop {
        embassy_time::Timer::after_millis(1000).await;
    }
}

Miri command (on Windows): cargo +nightly-2024-04-10 miri run

Sample output:

error: Undefined Behavior: not granting access to tag <39012> because that would remove [Unique for <38804>] which is strongly protected because it is an argument of call 8084
   --> C:\...\lib\rustlib\src\rust\library\core\src\mem\maybe_uninit.rs:493:24      
    |
493 |     pub const fn write(&mut self, val: T) -> &mut T {
    |                        ^^^^^^^^^ not granting access to tag <39012> because that would remove [Unique for <38804>] which is strongly protected because it is an argument of call 8084

Catamantaloedis avatar Apr 12 '24 15:04 Catamantaloedis

interesting.

do you have some understanding/explanation for why the original code causes a miri error and the change doesn't? Miri doesn't have false positives, so if the original code fails we definitely should fix it. However, it does have false negatives, so it's possible if we do this change without fully understanding why the original is bad and the new is good, we're just randomly changing the code to mask the issue (false negative) instead of actually fixing it.

Dirbaio avatar Apr 12 '24 15:04 Dirbaio

Hi. I was looking at this with @Catamantaloedis earlier today, and had suggested that change on a hunch.

Without having a completely solid grasp of Rust's semantics in this area, my guess is that it comes down to assume_init_drop being an in-place drop, and the need for drop to hold exclusive mutable access to what is being dropped. In this case, dropping a MutexGuard unlocks the mutex during the drop, but the &mut bound to the MutexGuard lives on for the entirety of the drop operation. This means that there's a portion of execution (if not in practice, then at least semantically) where the mutex is unlocked but an &mut reference to the contents of GLOBAL_GUARD is still alive, which is "racy" insofar as that the mutex is itself being used to synchronize access to GLOBAL_GUARD.

The "fix" was based on the observation that there's no need to actually do the drop in-place; the drop is just for its side-effect of unlocking the mutex, and not for any mutation it may or may not perform to the guard object itself. The change to

let _ = GLOBAL_GUARD.assume_init_read();

means that the drop is instead performed on a temporary loaded out of GLOBAL_GUARD, so there's never a mutating reference bound to GLOBAL_GUARD in the first place.

distractedlambda avatar Apr 12 '24 16:04 distractedlambda

I can't reproduce this, Miri is giving an ICE...

  • Can you post the full miri error?
  • Do you have a more reduced version to trigger this, that doesn't depend on embassy crates?

Dirbaio avatar Apr 26 '24 22:04 Dirbaio

I'm hitting the same UB report on Linux too.

I can't reproduce this, Miri is giving an ICE...

Miri has a bug for clock for now. See https://github.com/rust-lang/miri/issues/3647 (with reproducible code in there but on top of embassy).

So miri should be run in host system environment instead of faked one via MIRIFLAGS="-Zmiri-disable-isolation" cargo miri run

Full error with 1 sec tick
embassy-local ✗ MIRIFLAGS="-Zmiri-disable-isolation" cargo miri run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s
     Running `/root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri runner target/miri/x86_64-unknown-linux-gnu/debug/embassy-local`
[2024-06-05T02:15:37Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:38Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:39Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:40Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:41Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:42Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:43Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:45Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:46Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:47Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:48Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:49Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:50Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:51Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:52Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:54Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:55Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:56Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:57Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:58Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:15:59Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:00Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:02Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:03Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:04Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:05Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:06Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:07Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:08Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:10Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:11Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:12Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:13Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:14Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:15Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:16Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:17Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:19Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:20Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:21Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:22Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:23Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:24Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:25Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:27Z INFO  embassy_local] tick for 1 sec
[2024-06-05T02:16:28Z INFO  embassy_local] tick for 1 sec
error: Undefined Behavior: not granting access to tag <1457496> because that would remove [Unique for <1457358>] which is strongly protected because it is an argument of call 310298
   --> /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/mem/maybe_uninit.rs:493:24
    |
493 |     pub const fn write(&mut self, val: T) -> &mut T {
    |                        ^^^^^^^^^ not granting access to tag <1457496> because that would remove [Unique for <1457358>] which is strongly protected because it is an argument of call 310298
    |
    = 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: <1457496> was created by a SharedReadWrite retag at offsets [0x0..0x10]
   --> /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/std.rs:38:13
    |
38  |             GLOBAL_GUARD.write(guard);
    |             ^^^^^^^^^^^^
help: <1457358> is this argument
   --> src/main.rs:20:1
    |
20  | #[embassy_executor::main]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: BACKTRACE (of the first span) on thread `unnamed-1`:
    = note: inside `std::mem::MaybeUninit::<std::sync::MutexGuard<'_, ()>>::write` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/mem/maybe_uninit.rs:493:24: 493:33
    = note: inside closure at /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/std.rs:38:13: 38:38
    = note: inside `std::thread::LocalKey::<std::cell::Cell<bool>>::try_with::<{closure@<critical_section::std::StdCriticalSection as critical_section::Impl>::acquire::{closure#0}}, bool>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:286:12: 286:27
    = note: inside `std::thread::LocalKey::<std::cell::Cell<bool>>::with::<{closure@<critical_section::std::StdCriticalSection as critical_section::Impl>::acquire::{closure#0}}, bool>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:262:9: 262:25
    = note: inside `<critical_section::std::StdCriticalSection as critical_section::Impl>::acquire` at /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/std.rs:18:9: 41:11
    = note: inside `critical_section::std::_critical_section_1_0_acquire` at /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/lib.rs:282:13: 282:44
    = note: inside `critical_section::acquire` at /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/lib.rs:183:18: 183:49
    = note: inside `critical_section::with::<u64, {closure@embassy_time::driver_std::TimeDriver::alarm_thread::{closure#0}}>` at /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/lib.rs:226:26: 226:35
    = note: inside `embassy_time::driver_std::TimeDriver::alarm_thread` at /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/embassy-time-0.3.0/src/driver_std.rs:72:30: 103:15
    = note: inside `<fn() {embassy_time::driver_std::TimeDriver::alarm_thread} as std::ops::FnOnce<()>>::call_once - shim(fn() {embassy_time::driver_std::TimeDriver::alarm_thread})` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5: 250:71
    = note: inside `std::sys_common::backtrace::__rust_begin_short_backtrace::<fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:155:18: 155:21
    = note: inside closure at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/mod.rs:542:17: 542:78
    = note: inside `<std::panic::AssertUnwindSafe<{closure@std::thread::Builder::spawn_unchecked_<'_, '_, fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>::{closure#2}::{closure#0}}> as std::ops::FnOnce<()>>::call_once` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:272:9: 272:19
    = note: inside `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<{closure@std::thread::Builder::spawn_unchecked_<'_, '_, fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>::{closure#2}::{closure#0}}>, ()>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:559:40: 559:43
    = note: inside `std::panicking::r#try::<(), std::panic::AssertUnwindSafe<{closure@std::thread::Builder::spawn_unchecked_<'_, '_, fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>::{closure#2}::{closure#0}}>>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:523:19: 523:88
    = note: inside `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<{closure@std::thread::Builder::spawn_unchecked_<'_, '_, fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>::{closure#2}::{closure#0}}>, ()>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:149:14: 149:33
    = note: inside closure at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/mod.rs:541:30: 543:16
    = note: inside `<{closure@std::thread::Builder::spawn_unchecked_<'_, '_, fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>::{closure#2}} as std::ops::FnOnce<()>>::call_once - shim(vtable)` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5: 250:71
    = note: inside `<std::boxed::Box<dyn std::ops::FnOnce()> as std::ops::FnOnce<()>>::call_once` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:2063:9: 2063:52
    = note: inside `<std::boxed::Box<std::boxed::Box<dyn std::ops::FnOnce()>> as std::ops::FnOnce<()>>::call_once` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:2063:9: 2063:52
    = note: inside `std::sys::pal::unix::thread::Thread::new::thread_start` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/pal/unix/thread.rs:108:17: 108:64
    = note: this error originates in the attribute macro `embassy_executor::main` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 1 previous error

I tried to make backtrace readable as below

std::mem::MaybeUninit::<std::sync::MutexGuard<'_, ()>>::write
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/mem/maybe_uninit.rs:493:24: 493:33
closure
    /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/std.rs:38:13: 38:38
std::thread::LocalKey::<std::cell::Cell<bool>>::try_with::<{closure@<critical_section::std::StdCriticalSection as critical_section::Impl>::acquire::{closure#0}}, bool>
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:286:12: 286:27
std::thread::LocalKey::<std::cell::Cell<bool>>::with::<{closure@<critical_section::std::StdCriticalSection as critical_section::Impl>::acquire::{closure#0}}, bool>
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:262:9: 262:25
<critical_section::std::StdCriticalSection as critical_section::Impl>::acquire
    /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/std.rs:18:9: 41:11
critical_section::std::_critical_section_1_0_acquire
    /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/lib.rs:282:13: 282:44
critical_section::acquire
    /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/lib.rs:183:18: 183:49
critical_section::with::<u64, {closure@embassy_time::driver_std::TimeDriver::alarm_thread::{closure#0}}>
    /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/lib.rs:226:26: 226:35
embassy_time::driver_std::TimeDriver::alarm_thread
    /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/embassy-time-0.3.0/src/driver_std.rs:72:30: 103:15
<fn() {embassy_time::driver_std::TimeDriver::alarm_thread} as std::ops::FnOnce<()>>::call_once - shim(fn() {embassy_time::driver_std::TimeDriver::alarm_thread})
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5: 250:71
std::sys_common::backtrace::__rust_begin_short_backtrace::<fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:155:18: 155:21
closure
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/mod.rs:542:17: 542:78
<std::panic::AssertUnwindSafe<{closure@std::thread::Builder::spawn_unchecked_<'_, '_, fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>::{closure#2}::{closure#0}}> as std::ops::FnOnce<()>>::call_once
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:272:9: 272:19
std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<{closure@std::thread::Builder::spawn_unchecked_<'_, '_, fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>::{closure#2}::{closure#0}}>, ()>
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:559:40: 559:43
std::panicking::r#try::<(), std::panic::AssertUnwindSafe<{closure@std::thread::Builder::spawn_unchecked_<'_, '_, fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>::{closure#2}::{closure#0}}>>
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:523:19: 523:88
std::panic::catch_unwind::<std::panic::AssertUnwindSafe<{closure@std::thread::Builder::spawn_unchecked_<'_, '_, fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>::{closure#2}::{closure#0}}>, ()>
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:149:14: 149:33
closure
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/mod.rs:541:30: 543:16
<{closure@std::thread::Builder::spawn_unchecked_<'_, '_, fn() {embassy_time::driver_std::TimeDriver::alarm_thread}, ()>::{closure#2}} as std::ops::FnOnce<()>>::call_once - shim(vtable)
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5: 250:71
<std::boxed::Box<dyn std::ops::FnOnce()> as std::ops::FnOnce<()>>::call_once
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:2063:9: 2063:52
<std::boxed::Box<std::boxed::Box<dyn std::ops::FnOnce()>> as std::ops::FnOnce<()>>::call_once
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:2063:9: 2063:52
std::sys::pal::unix::thread::Thread::new::thread_start
    /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/pal/unix/thread.rs:108:17: 108:64

It basically says aliasing rules are violated. I agree with @distractedlambda that there are two mutable/exclusive reference caused by dropping, because when I tuned the tick frequency to 10 ms, miri points out drop removes Unique tag.

embassy-local ✗ MIRIFLAGS="-Zmiri-disable-isolation" cargo miri run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.43s
     Running `/root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri runner target/miri/x86_64-unknown-linux-gnu/debug/embassy-local`
[2024-06-05T03:46:58Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:46:58Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:46:59Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:46:59Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:46:59Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:46:59Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:46:59Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:46:59Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:47:00Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:47:00Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:47:00Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:47:00Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:47:00Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:47:00Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:47:00Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:47:01Z INFO  embassy_local] tick for 10 millis
[2024-06-05T03:47:01Z INFO  embassy_local] tick for 10 millis
error: Undefined Behavior: not granting access to tag <526578> because that would remove [Unique for <526360>] which is strongly protected because it is an argument of call 112396
   --> /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/mem/maybe_uninit.rs:493:24
    |
493 |     pub const fn write(&mut self, val: T) -> &mut T {
    |                        ^^^^^^^^^ not granting access to tag <526578> because that would remove [Unique for <526360>] which is strongly protected because it is an argument of call 112396
    |
    = 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: <526578> was created by a SharedReadWrite retag at offsets [0x0..0x10]
   --> src/main.rs:20:1
    |
20  | #[embassy_executor::main]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
help: <526360> is this argument
   --> /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sync/mutex.rs:548:13
    |
548 |     fn drop(&mut self) {
    |             ^^^^^^^^^
    = note: BACKTRACE (of the first span):
    = note: inside `std::mem::MaybeUninit::<std::sync::MutexGuard<'_, ()>>::write` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/mem/maybe_uninit.rs:493:24: 493:33
    = note: inside closure at /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/critical-section-1.1.2/src/std.rs:38:13: 38:38
    = note: inside `std::thread::LocalKey::<std::cell::Cell<bool>>::try_with::<{closure@<critical_section::std::StdCriticalSection as critical_section::Impl>::acquire::{closure#0}}, bool>` at /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:286:12: 286:27
...

With the code in this PR, miri doesn't complain any more.

zjp-CN avatar Jun 05 '24 04:06 zjp-CN