Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miri subtree update #123041

Merged
merged 25 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3d6fcea
when a test fails, repeat the target after the failure report
RalfJung Mar 23, 2024
bb4ef1a
disable RUST_BACKTRACE in CI, set it inside the test harness instead
RalfJung Mar 23, 2024
8e978c3
Auto merge of #3399 - RalfJung:ci, r=RalfJung
bors Mar 23, 2024
2e464c2
Preparing for merge from rustc
RalfJung Mar 24, 2024
070e8ce
Merge from rustc
RalfJung Mar 24, 2024
1dd13ca
miri script: build with stable toolchain
RalfJung Mar 24, 2024
c7b86fc
Auto merge of #3403 - RalfJung:rustup, r=RalfJung
bors Mar 24, 2024
04b523f
CI tweaks and show which stable Rust we are using
RalfJung Mar 24, 2024
fdb5613
many-seeds: propagate failure properly
RalfJung Mar 24, 2024
acf3f52
miri-script/toolchain: make new_commit logic easier to follow
RalfJung Mar 24, 2024
04a69e4
Add libc test for rename and ftruncate
tiif Mar 22, 2024
624af51
Auto merge of #3398 - tiif:add_libc_fs_test, r=RalfJung
bors Mar 24, 2024
805f6ee
try to fix many-seeds tests on Windows
RalfJung Mar 24, 2024
a12decc
desperate hack: hard-code bash path on Windows
RalfJung Mar 24, 2024
f97f448
Auto merge of #3406 - RalfJung:many-seeds, r=RalfJung
bors Mar 24, 2024
dcddf24
Auto merge of #3402 - RalfJung:miri-script, r=RalfJung
bors Mar 24, 2024
89a32d7
CONTRIBUTING: vsocde settings: add --all-targets
RalfJung Mar 25, 2024
cf172a8
Auto merge of #3410 - RalfJung:all-targets, r=RalfJung
bors Mar 25, 2024
8afc486
test-cargo-miri: test anyhow
RalfJung Mar 25, 2024
98e1cbb
phase_rustdoc: add a heuristic to make us more certain that this is r…
RalfJung Mar 25, 2024
c461170
Auto merge of #3413 - RalfJung:cargo-miri-misc, r=RalfJung
bors Mar 25, 2024
5b1319c
Preparing for merge from rustc
RalfJung Mar 25, 2024
d8be714
Merge from rustc
RalfJung Mar 25, 2024
0d4ef69
support '--sysroot=' form of setting the sysroot as well
RalfJung Mar 25, 2024
cf1eb93
Auto merge of #3414 - RalfJung:rustup, r=RalfJung
bors Mar 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/tools/miri/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ jobs:
host_target: i686-pc-windows-msvc
runs-on: ${{ matrix.os }}
env:
RUST_BACKTRACE: 1
HOST_TARGET: ${{ matrix.host_target }}
steps:
- uses: actions/checkout@v3

- name: Show Rust version (stable toolchain)
run: |
rustup show
rustc -Vv
cargo -V

# Cache the global cargo directory, but NOT the local `target` directory which
# we cannot reuse anyway when the nightly changes (and it grows quite large
# over time).
Expand All @@ -58,21 +63,21 @@ jobs:
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
run: cargo install -f rustup-toolchain-install-master

- name: Install "master" toolchain
- name: Install miri toolchain
run: |
if [[ ${{ github.event_name }} == 'schedule' ]]; then
echo "Building against latest rustc git version"
git ls-remote /~https://github.com/rust-lang/rust/ HEAD | cut -f 1 > rust-version
fi
./miri toolchain --host ${{ matrix.host_target }}

- name: Show Rust version
- name: Show Rust version (miri toolchain)
run: |
rustup show
rustc -Vv
cargo -V

- name: Test
- name: Test Miri
run: ./ci/ci.sh

style:
Expand Down
15 changes: 10 additions & 5 deletions src/tools/miri/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,22 @@ For example, you can (cross-)run the driver on a particular file by doing
./miri run tests/pass/hello.rs --target i686-unknown-linux-gnu
```

and you can (cross-)run the entire test suite using:
Tests in ``pass-dep`` need to be run using ``./miri run --dep <filename>``.
For example:
```sh
./miri run --dep tests/pass-dep/shims/libc-fs.rs
```

You can (cross-)run the entire test suite using:

```
./miri test
MIRI_TEST_TARGET=i686-unknown-linux-gnu ./miri test
```

If your target doesn't support libstd that should usually just work. However, if you are using a
custom target file, you might have to set `MIRI_NO_STD=1`.

`./miri test FILTER` only runs those tests that contain `FILTER` in their filename (including the
base directory, e.g. `./miri test fail` will run all compile-fail tests). These filters are passed
to `cargo test`, so for multiple filers you need to use `./miri test -- FILTER1 FILTER2`.
to `cargo test`, so for multiple filters you need to use `./miri test -- FILTER1 FILTER2`.

#### Fine grained logging

Expand Down Expand Up @@ -178,6 +181,7 @@ to `.vscode/settings.json` in your local Miri clone:
"cargo",
"clippy", // make this `check` when working with a locally built rustc
"--message-format=json",
"--all-targets",
],
// Contrary to what the name suggests, this also affects proc macros.
"rust-analyzer.cargo.buildScripts.overrideCommand": [
Expand All @@ -187,6 +191,7 @@ to `.vscode/settings.json` in your local Miri clone:
"cargo",
"check",
"--message-format=json",
"--all-targets",
],
}
```
Expand Down
20 changes: 17 additions & 3 deletions src/tools/miri/cargo-miri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,18 @@ use std::{env, iter};

use crate::phases::*;

/// Returns `true` if our flags look like they may be for rustdoc, i.e., this is cargo calling us to
/// be rustdoc. It's hard to be sure as cargo does not have a RUSTDOC_WRAPPER or an env var that
/// would let us get a clear signal.
fn looks_like_rustdoc() -> bool {
// The `--test-run-directory` flag only exists for rustdoc and cargo always passes it. Perfect!
env::args().any(|arg| arg == "--test-run-directory")
}

fn main() {
// Rustc does not support non-UTF-8 arguments so we make no attempt either.
// (We do support non-UTF-8 environment variables though.)
let mut args = std::env::args();
let mut args = env::args();
// Skip binary name.
args.next().unwrap();

Expand Down Expand Up @@ -91,10 +99,16 @@ fn main() {
// (see /~https://github.com/rust-lang/cargo/issues/10886).
phase_rustc(args, RustcPhase::Build)
}
_ => {
// Everything else must be rustdoc. But we need to get `first` "back onto the iterator",
_ if looks_like_rustdoc() => {
// This is probably rustdoc. But we need to get `first` "back onto the iterator",
// it is some part of the rustdoc invocation.
phase_rustdoc(iter::once(first).chain(args));
}
_ => {
show_error!(
"`cargo-miri` failed to recognize which phase of the build process this is, please report a bug.\nThe command-line arguments were: {:#?}",
Vec::from_iter(env::args()),
);
}
}
}
2 changes: 1 addition & 1 deletion src/tools/miri/cargo-miri/src/phases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ pub fn phase_rustdoc(mut args: impl Iterator<Item = String>) {

// The `--test-builder` and `--runtool` arguments are unstable rustdoc features,
// which are disabled by default. We first need to enable them explicitly:
cmd.arg("-Z").arg("unstable-options");
cmd.arg("-Zunstable-options");

// rustdoc needs to know the right sysroot.
cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap());
Expand Down
14 changes: 12 additions & 2 deletions src/tools/miri/ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ function endgroup {

begingroup "Building Miri"

# Special Windows hacks
if [ "$HOST_TARGET" = i686-pc-windows-msvc ]; then
# The $BASH variable is `/bin/bash` here, but that path does not actually work. There are some
# hacks in place somewhere to try to paper over this, but the hacks dont work either (see
# </~https://github.com/rust-lang/miri/pull/3402>). So we hard-code the correct location for Github
# CI instead.
BASH="C:/Program Files/Git/usr/bin/bash"
fi

# Determine configuration for installed build
echo "Installing release version of Miri"
export RUSTFLAGS="-D warnings"
Expand Down Expand Up @@ -58,12 +67,13 @@ function run_tests {
MIRIFLAGS="${MIRIFLAGS:-} -O -Zmir-opt-level=4 -Cdebug-assertions=yes" MIRI_SKIP_UI_CHECKS=1 ./miri test -- tests/{pass,panic}

# Also run some many-seeds tests. 64 seeds means this takes around a minute per test.
# (Need to invoke via explicit `bash -c` for Windows.)
for FILE in tests/many-seeds/*.rs; do
MIRI_SEEDS=64 ./miri many-seeds ./miri run "$FILE"
MIRI_SEEDS=64 ./miri many-seeds "$BASH" -c "./miri run '$FILE'"
done

# Check that the benchmarks build and run, but without actually benchmarking.
HYPERFINE="bash -c" ./miri bench
HYPERFINE="'$BASH' -c" ./miri bench
fi

## test-cargo-miri
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/miri
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ set -e
# Instead of doing just `cargo run --manifest-path .. $@`, we invoke miri-script binary directly. Invoking `cargo run` goes through
# rustup (that sets it's own environmental variables), which is undesirable.
MIRI_SCRIPT_TARGET_DIR="$(dirname "$0")"/miri-script/target
cargo build $CARGO_EXTRA_FLAGS -q --target-dir "$MIRI_SCRIPT_TARGET_DIR" --manifest-path "$(dirname "$0")"/miri-script/Cargo.toml
cargo +stable build $CARGO_EXTRA_FLAGS -q --target-dir "$MIRI_SCRIPT_TARGET_DIR" --manifest-path "$(dirname "$0")"/miri-script/Cargo.toml
"$MIRI_SCRIPT_TARGET_DIR"/debug/miri-script "$@"
10 changes: 5 additions & 5 deletions src/tools/miri/miri-script/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl Command {
.context("Please install rustup-toolchain-install-master by running 'cargo install rustup-toolchain-install-master'")?;
let sh = Shell::new()?;
sh.change_dir(miri_dir()?);
let new_commit = Some(sh.read_file("rust-version")?.trim().to_owned());
let new_commit = sh.read_file("rust-version")?.trim().to_owned();
let current_commit = {
let rustc_info = cmd!(sh, "rustc +miri --version -v").read();
if rustc_info.is_err() {
Expand All @@ -193,7 +193,7 @@ impl Command {
}
};
// Check if we already are at that commit.
if current_commit == new_commit {
if current_commit.as_ref() == Some(&new_commit) {
if active_toolchain()? != "miri" {
cmd!(sh, "rustup override set miri").run()?;
}
Expand All @@ -202,7 +202,7 @@ impl Command {
// Install and setup new toolchain.
cmd!(sh, "rustup toolchain uninstall miri").run()?;

cmd!(sh, "rustup-toolchain-install-master -n miri -c cargo -c rust-src -c rustc-dev -c llvm-tools -c rustfmt -c clippy {flags...} -- {new_commit...}").run()?;
cmd!(sh, "rustup-toolchain-install-master -n miri -c cargo -c rust-src -c rustc-dev -c llvm-tools -c rustfmt -c clippy {flags...} -- {new_commit}").run()?;
cmd!(sh, "rustup override set miri").run()?;
// Cleanup.
cmd!(sh, "cargo clean").run()?;
Expand Down Expand Up @@ -380,9 +380,9 @@ impl Command {
.env("MIRIFLAGS", miriflags)
.quiet()
.run();
if status.is_err() {
if let Err(err) = status {
println!("Failing seed: {seed}");
break;
return Err(err.into());
}
}
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/miri.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set MIRI_SCRIPT_TARGET_DIR=%0\..\miri-script\target

:: If any other steps are added, the "|| exit /b" must be appended to early
:: return from the script. If not, it will continue execution.
cargo build %CARGO_EXTRA_FLAGS% -q --target-dir %MIRI_SCRIPT_TARGET_DIR% --manifest-path %0\..\miri-script\Cargo.toml || exit /b
cargo +stable build %CARGO_EXTRA_FLAGS% -q --target-dir %MIRI_SCRIPT_TARGET_DIR% --manifest-path %0\..\miri-script\Cargo.toml || exit /b

:: Forwards all arguments to this file to the executable.
:: We invoke the binary directly to avoid going through rustup, which would set some extra
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
c3b05c6e5b5b59613350b8c2875b0add67ed74df
cb7c63606e53715f94f3ba04d38e50772e4cd23d
2 changes: 1 addition & 1 deletion src/tools/miri/src/bin/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ fn run_compiler(
// If no `--sysroot` is given, the `MIRI_SYSROOT` env var is consulted to find where
// that sysroot lives, and that is passed to rustc.
let sysroot_flag = "--sysroot";
if !args.iter().any(|e| e == sysroot_flag) {
if !args.iter().any(|e| e.starts_with(sysroot_flag)) {
// Using the built-in default here would be plain wrong, so we *require*
// the env var to make sure things make sense.
let miri_sysroot = env::var("MIRI_SYSROOT").unwrap_or_else(|_| {
Expand Down
7 changes: 7 additions & 0 deletions src/tools/miri/test-cargo-miri/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
# It is not intended for manual editing.
version = 3

[[package]]
name = "anyhow"
version = "1.0.81"
source = "registry+/~https://github.com/rust-lang/crates.io-index"
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"

[[package]]
name = "autocfg"
version = "1.1.0"
Expand All @@ -24,6 +30,7 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
name = "cargo-miri-test"
version = "0.1.0"
dependencies = [
"anyhow",
"autocfg",
"byteorder 0.5.3",
"byteorder 1.4.3",
Expand Down
3 changes: 3 additions & 0 deletions src/tools/miri/test-cargo-miri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ issue_rust_86261 = { path = "issue-rust-86261" }
byteorder_2 = { package = "byteorder", version = "0.5" } # to test dev-dependencies behave as expected, with renaming
# Not actually used, but exercises some unique code path (`--extern` .so file).
serde_derive = "1.0.185"
# Not actually used, but uses a custom build probe so let's make sure that works.
# (Ideally we'd check if the probe was successful, but that's not easily possible.)
anyhow = "1.0"

[build-dependencies]
autocfg = "1"
Expand Down
63 changes: 63 additions & 0 deletions src/tools/miri/tests/pass-dep/shims/libc-fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ mod utils;
fn main() {
test_dup_stdout_stderr();
test_canonicalize_too_long();
test_rename();
test_ftruncate::<libc::off_t>(libc::ftruncate);
#[cfg(target_os = "linux")]
test_ftruncate::<libc::off64_t>(libc::ftruncate64);
test_readlink();
test_file_open_unix_allow_two_args();
test_file_open_unix_needs_three_args();
Expand Down Expand Up @@ -133,6 +137,65 @@ fn test_readlink() {
assert_eq!(Error::last_os_error().kind(), ErrorKind::NotFound);
}

fn test_rename() {
let path1 = prepare("miri_test_libc_fs_source.txt");
let path2 = prepare("miri_test_libc_fs_rename_destination.txt");

let file = File::create(&path1).unwrap();
drop(file);

let c_path1 = CString::new(path1.as_os_str().as_bytes()).expect("CString::new failed");
let c_path2 = CString::new(path2.as_os_str().as_bytes()).expect("CString::new failed");

// Renaming should succeed
unsafe { libc::rename(c_path1.as_ptr(), c_path2.as_ptr()) };
// Check that old file path isn't present
assert_eq!(ErrorKind::NotFound, path1.metadata().unwrap_err().kind());
// Check that the file has moved successfully
assert!(path2.metadata().unwrap().is_file());

// Renaming a nonexistent file should fail
let res = unsafe { libc::rename(c_path1.as_ptr(), c_path2.as_ptr()) };
assert_eq!(res, -1);
assert_eq!(Error::last_os_error().kind(), ErrorKind::NotFound);

remove_file(&path2).unwrap();
}

fn test_ftruncate<T: From<i32>>(
ftruncate: unsafe extern "C" fn(fd: libc::c_int, length: T) -> libc::c_int,
) {
// libc::off_t is i32 in target i686-unknown-linux-gnu
// https://docs.rs/libc/latest/i686-unknown-linux-gnu/libc/type.off_t.html

let bytes = b"hello";
let path = prepare("miri_test_libc_fs_ftruncate.txt");
let mut file = File::create(&path).unwrap();
file.write(bytes).unwrap();
file.sync_all().unwrap();
assert_eq!(file.metadata().unwrap().len(), 5);

let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed");
let fd = unsafe { libc::open(c_path.as_ptr(), libc::O_RDWR) };

// Truncate to a bigger size
let mut res = unsafe { ftruncate(fd, T::from(10)) };
assert_eq!(res, 0);
assert_eq!(file.metadata().unwrap().len(), 10);

// Write after truncate
file.write(b"dup").unwrap();
file.sync_all().unwrap();
assert_eq!(file.metadata().unwrap().len(), 10);

// Truncate to smaller size
res = unsafe { ftruncate(fd, T::from(2)) };
assert_eq!(res, 0);
assert_eq!(file.metadata().unwrap().len(), 2);

remove_file(&path).unwrap();
}

#[cfg(target_os = "linux")]
fn test_o_tmpfile_flag() {
use std::fs::{create_dir, OpenOptions};
Expand Down
13 changes: 10 additions & 3 deletions src/tools/miri/tests/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ use std::ffi::OsString;
use std::num::NonZeroUsize;
use std::path::{Path, PathBuf};
use std::{env, process::Command};
use ui_test::{color_eyre::Result, Config, Match, Mode, OutputConflictHandling};
use ui_test::{status_emitter, CommandBuilder, Format, RustfixMode};
use ui_test::color_eyre::eyre::{Context, Result};
use ui_test::{
status_emitter, CommandBuilder, Config, Format, Match, Mode, OutputConflictHandling,
RustfixMode,
};

fn miri_path() -> PathBuf {
PathBuf::from(option_env!("MIRI").unwrap_or(env!("CARGO_BIN_EXE_miri")))
Expand Down Expand Up @@ -124,6 +127,9 @@ fn run_tests(
// Let the tests know where to store temp files (they might run for a different target, which can make this hard to find).
config.program.envs.push(("MIRI_TEMP".into(), Some(tmpdir.to_owned().into())));

// If a test ICEs, we want to see a backtrace.
config.program.envs.push(("RUST_BACKTRACE".into(), Some("1".into())));

// Handle command-line arguments.
let args = ui_test::Args::test()?;
let default_bless = env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0");
Expand Down Expand Up @@ -223,14 +229,15 @@ fn ui(
with_dependencies: Dependencies,
tmpdir: &Path,
) -> Result<()> {
let msg = format!("## Running ui tests in {path} against miri for {target}");
let msg = format!("## Running ui tests in {path} for {target}");
eprintln!("{}", msg.green().bold());

let with_dependencies = match with_dependencies {
WithDependencies => true,
WithoutDependencies => false,
};
run_tests(mode, path, target, with_dependencies, tmpdir)
.with_context(|| format!("ui tests in {path} for {target} failed"))
}

fn get_target() -> String {
Expand Down
Loading