From cfcea21074f922aa2fd184751842513e574b2e37 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 13 Jun 2024 20:02:02 +0200 Subject: [PATCH] document --many-seeds; set the default range to 0..64 --- src/tools/miri/README.md | 32 ++++++++++++------------- src/tools/miri/cargo-miri/src/phases.rs | 4 +++- src/tools/miri/miri-script/src/main.rs | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index c437619a76ea..4b4f2f83062f 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -151,6 +151,21 @@ platform. For example `cargo miri test --target s390x-unknown-linux-gnu` will run your test suite on a big-endian target, which is useful for testing endian-sensitive code. +### Testing multiple different executions + +Certain parts of the execution are picked randomly by Miri, such as the exact base address +allocations are stored at and the interleaving of concurrently executing threads. Sometimes, it can +be useful to explore multiple different execution, e.g. to make sure that your code does not depend +on incidental "super-alignment" of new allocations and to test different thread interleavings. +This can be done with the `--many-seeds` flag: + +``` +cargo miri test --many-seeds # tries the seeds in 0..64 +cargo miri test --many-seeds=0..16 +``` + +The default of 64 different seeds is quite slow, so you probably want to specify a smaller range. + ### Running Miri on CI When running Miri on CI, use the following snippet to install a nightly toolchain with the Miri @@ -183,23 +198,6 @@ Here is an example job for GitHub Actions: The explicit `cargo miri setup` helps to keep the output of the actual test step clean. -### Testing for alignment issues - -Miri can sometimes miss misaligned accesses since allocations can "happen to be" -aligned just right. You can use `-Zmiri-symbolic-alignment-check` to definitely -catch all such issues, but that flag will also cause false positives when code -does manual pointer arithmetic to account for alignment. Another alternative is -to call Miri with various values for `-Zmiri-seed`; that will alter the -randomness that is used to determine allocation base addresses. The following -snippet calls Miri in a loop with different values for the seed: - -``` -for SEED in $(seq 0 255); do - echo "Trying seed: $SEED" - MIRIFLAGS=-Zmiri-seed=$SEED cargo miri test || { echo "Failing seed: $SEED"; break; }; -done -``` - ### Supported targets Miri does not support all targets supported by Rust. The good news, however, is diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index 6773cff89abf..3c36f606d845 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -34,6 +34,8 @@ Examples: "; +const DEFAULT_MANY_SEEDS: &str = "0..64"; + fn show_help() { println!("{CARGO_MIRI_HELP}"); } @@ -171,7 +173,7 @@ pub fn phase_cargo_miri(mut args: impl Iterator) { ArgSplitFlagValue::from_string_iter(&mut args, "--target-dir").filter_map(Result::err) { if arg == "--many-seeds" { - many_seeds = Some(format!("0..256")); + many_seeds = Some(DEFAULT_MANY_SEEDS.to_owned()); } else if let Some(val) = arg.strip_prefix("--many-seeds=") { many_seeds = Some(val.to_owned()); } else { diff --git a/src/tools/miri/miri-script/src/main.rs b/src/tools/miri/miri-script/src/main.rs index f4448146c55c..c4f0d808d93e 100644 --- a/src/tools/miri/miri-script/src/main.rs +++ b/src/tools/miri/miri-script/src/main.rs @@ -98,7 +98,7 @@ Build miri, set up a sysroot and then run the test suite. Build miri, set up a sysroot and then run the driver with the given . (Also respects MIRIFLAGS environment variable.) If `--many-seeds` is present, Miri is run many times in parallel with different seeds. -The range defaults to `0..256`. +The range defaults to `0..64`. ./miri fmt : Format all sources and tests. are passed to `rustfmt`. @@ -180,7 +180,7 @@ fn main() -> Result<()> { dep = true; } else if args.get_long_flag("verbose")? || args.get_short_flag('v')? { verbose = true; - } else if let Some(val) = args.get_long_opt_with_default("many-seeds", "0..256")? { + } else if let Some(val) = args.get_long_opt_with_default("many-seeds", "0..64")? { let (from, to) = val.split_once("..").ok_or_else(|| { anyhow!("invalid format for `--many-seeds`: expected `from..to`") })?;