How do you decipher the error messages of Miri?
Promptet by this thread
I tried to comprehend the following Miri error message:
Compiling playground v0.0.1 (/playground)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.64s
Running `/playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri runner target/miri/x86_64-unknown-linux-gnu/debug/playground`
error: Undefined Behavior: attempting a read access using <3563> at alloc1606[0x0], but that tag does not exist in the borrow stack for this location
--> src/main.rs:11:9
|
11 | core::ptr::copy(src_ptr, dst_ptr, 8);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| attempting a read access using <3563> at alloc1606[0x0], but that tag does not exist in the borrow stack for this location
| this error occurs as part of an access at alloc1606[0x0..0x8]
|
= 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: <3563> was created by a SharedReadOnly retag at offsets [0x0..0x10]
--> src/main.rs:9:34
|
9 | let src_ptr: *const u8 = bytes.as_ptr().cast();
| ^^^^^^^^^^^^^^
help: <3563> was later invalidated at offsets [0x0..0x10] by a Unique retag
--> src/main.rs:10:23
|
10 | let dst_ptr = bytes.as_mut_ptr().cast::<u8>().add(8);
| ^^^^^
= note: BACKTRACE (of the first span):
= note: inside `main` at src/main.rs:11:9: 11:45
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
Produced by running this code
use core::mem::MaybeUninit;
fn main() {
let mut bytes: [MaybeUninit<u8>; 16] = [MaybeUninit::uninit(); 16];
for i in 0..16 {
bytes[i] = MaybeUninit::new(i as u8);
}
unsafe {
let src_ptr: *const u8 = bytes.as_ptr().cast();
let dst_ptr = bytes.as_mut_ptr().cast::<u8>().add(8);
core::ptr::copy(src_ptr, dst_ptr, 8);
}
for i in 0..16 {
println!("{}", unsafe{ bytes[i].assume_init()});
}
}
It mentiones tags which I believe <3563>
is an example of and allocations like alloc1606[0x0]
. But I don't see a way of mapping these concepts back to the source code in order to be able to find out what went wrong. What is a tag? Is it a variable? And how would I find out which one? And how can I track where an allocation originated?
The solution to this Miri error turned out to be that if you want mutiple *mut and *const pointers you need to derive them from a single *mut pointer obtained through a &mut
reference. But how would you deduce this from the miri error? Can you give me some tips how you would go about reading this error?