Add support for panicking in the emulated application when unsupported functionality is encountered
This PR fixes#1807 and allows an optional flag to be specified to panic when an unsupported syscall is encountered. In essence, instead of bubbling up an error in the context of the Miri application Miri will panic within the context of the *emulated* application. This feature is desired to allow CI pipelines to determine if a Miri failure is unsupported functionality or actual UB. Please read [this comment](https://github.com/rust-lang/miri/issues/1807#issuecomment-845425076) for the rationale behind this change.
Note: this change does not cover all cases where unsupported functionality errors may be raised. If you search the repo for `throw_unsup_format!` there are many cases that I think are less likely to occur and may still be problematic for some folks.
TODO:
- [x] README documentation on this new flag
- [x] Add tests
fix: avoid stopping machine upon running env operations in isolation
get and set current dir operations used to halt the machine by
throwing an exception in isolation mode. This change updates them to
return a dummy `NotFound` error instead, and keep the machine running.
I started with a custom error using `ErrorKind::Other`, but since it
can't be mapped to a raw OS error, I dropped it. `NotFound` kind of make
sense for get operations, but not much for set operations. But that's
the only error supported for windows currently.
In user interface, added a new flag `-Zmiri-isolation-error` which
takes one of the four values -- hide, warn, warn-nobacktrace, and
abort. This option can be used to configure Miri to either abort or
return an error code upon executing isolated op. If not aborted, Miri
prints a warning, whose verbosity can be configured using this flag.
In implementation, added a new enum `IsolatedOp` to capture all the
settings related to ops requiring communication with the
host. Old `communicate` flag in both miri configs and machine
stats is replaced with a new helper function `communicate()` which
checks `isolated_op` internally.
Added a new helper function `reject_in_isolation` which can be called
by shims to reject ops according to the reject_with settings. Use miri
specific diagnostics function `report_msg` to print backtrace in the
warning. Update it to take an enum value instead of a bool, indicating
the level of diagnostics.
Updated shims related to current dir to use the new APIs. Added a new
test for current dir ops in isolation without halting machine.
Detect `std` by checking if the crate defines `#[lang = "start"]` rather than string comparison
I also considered to compare the crate name with `sym::std`, but it's easy to name any crate `std` by using `--crate-name std`, so I don't think that is robust enough.
Note that this only checks the crate, it does not check whether the call is in `sys::unix` or `sys::windows`, unlike the previous implementation, but I think it's already robust enough.
Fixes#1821.
added a strings.rs regression test case for potential future UB
This PR adds a regression test for the aliasing rules of a `Unique<T>` pointer.
At the time of writing this test case, Miri does not treat `Unique<T>`
pointers as a special case, these are treated like any other raw pointer.
However, there are existing Github issues which may lead to `Unique<T>`
becoming a special case through asserting unique ownership over the pointee:
- https://github.com/rust-lang/unsafe-code-guidelines/issues/258
- https://github.com/rust-lang/unsafe-code-guidelines/issues/262
In the new test case, the calls to `String::remove` and `String::insert[_str]` follow
code paths that would trigger undefined behavior in case `Unique<T>`
would ever assert semantic ownership over the pointee. Internally,
these methods call `self.vec.as_ptr()` and `self.vec.as_mut_ptr()` on
the vector of bytes that are backing the `String`. That `Vec<u8>` holds a
`Unique<u8>` internally. The second call to `Vec::as_mut_ptr(&mut self)`
would then invalidate the pointers derived from `Vec::as_ptr(&self)`.
Note that as long as `Unique<T>` is treated like any other raw pointer,
this test case should pass. It is merely here as a canary test for
potential future undefined behavior.
regression tests for pointer invalidation in core library slice methods
A fix for a pointer invalidation bug in `<[T]>::copy_within` has [landed](https://github.com/rust-lang/rust/pull/85610) on the Rust master branch. This PR updates the `rust-version` file to the latest master commit hash and adds extra tests to the Miri test suite to ensure that regressions of this type of bug can be detected for various slice methods with the `-Zmiri-track-raw-pointers` flag.
I took the liberty of adding 2 extra `#![feature]` attributes at the top of `slices.rs`, since there already was one unstable feature. I hope this is okay 😄
One thing I noticed when running the entire Miri test suite with `MIRIFLAGS="-Zmiri-track-raw-pointers" ./miri test` is that there are currently failing tests on the master branch:
```
failures:
[ui] run-pass/align.rs
[ui] run-pass/box.rs
[ui] run-pass/concurrency/simple.rs
[ui] run-pass/libc.rs
[ui] run-pass/ptr_int_casts.rs
[ui] run-pass/stacked-borrows/int-to-ptr.rs
test result: FAILED. 199 passed; 6 failed; 1 ignored; 0 measured; 0 filtered out; finished in 12.95s
```
These failures were not fixed in this PR and already existed prior to this PR. I haven't investigated these yet, but am interested in helping out if possible!
Thanks!
`original_crate_name` -> `crate_name`
`original_crate_name` was removed in rust-lang/rust#85904, and according to that PR, it "had the exact same implementation" as `crate_name`.
cc rust-lang/rust#85946