From cf5b53e52fc0267aa9be95a6a2544eeb9761cd7f Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 12 Nov 2019 10:19:13 -0500 Subject: [PATCH 01/11] Rustup for panic changes This gets Miri working again, but doesn't actually implement unwinding --- src/eval.rs | 2 +- src/machine.rs | 17 +++++++++++++---- src/shims/foreign_items.rs | 2 +- src/shims/intrinsics.rs | 2 +- src/shims/mod.rs | 2 +- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/eval.rs b/src/eval.rs index b09fb5918c..65f6d5dd02 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -213,7 +213,7 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) { }; e.print_backtrace(); if let Some(frame) = ecx.stack().last() { - let block = &frame.body.basic_blocks()[frame.block]; + let block = &frame.body.basic_blocks()[frame.block.unwrap()]; let span = if frame.stmt < block.statements.len() { block.statements[frame.stmt].source_info.span } else { diff --git a/src/machine.rs b/src/machine.rs index c76cc2e568..20abfdcf54 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -173,6 +173,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { args: &[OpTy<'tcx, Tag>], dest: Option>, ret: Option, + _unwind: Option, ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> { ecx.find_fn(instance, args, dest, ret) } @@ -194,8 +195,14 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { span: Span, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, Tag>], - dest: PlaceTy<'tcx, Tag>, + dest: Option>, + _ret: Option, + _unwind: Option ) -> InterpResult<'tcx> { + let dest = match dest { + Some(dest) => dest, + None => throw_ub!(Unreachable) + }; ecx.call_intrinsic(span, instance, args, dest) } @@ -353,13 +360,15 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { fn stack_pop( ecx: &mut InterpCx<'mir, 'tcx, Self>, extra: stacked_borrows::CallId, - ) -> InterpResult<'tcx> { - Ok(ecx + _unwinding: bool + ) -> InterpResult<'tcx, StackPopInfo> { + ecx .memory .extra .stacked_borrows .borrow_mut() - .end_call(extra)) + .end_call(extra); + Ok(StackPopInfo::Normal) } #[inline(always)] diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index 1f43a83576..55ec36387f 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -335,7 +335,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx mir, Some(ret_place), // Directly return to caller. - StackPopCleanup::Goto(Some(ret)), + StackPopCleanup::Goto { ret: Some(ret), unwind: None }, )?; let mut args = this.frame().body.args_iter(); diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index 7470090f52..2e41ab1ca6 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -22,7 +22,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx dest: PlaceTy<'tcx, Tag>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - if this.emulate_intrinsic(span, instance, args, dest)? { + if this.emulate_intrinsic(span, instance, args, Some(dest))? { return Ok(()); } let tcx = &{this.tcx.tcx}; diff --git a/src/shims/mod.rs b/src/shims/mod.rs index 3302143f48..d9de27596c 100644 --- a/src/shims/mod.rs +++ b/src/shims/mod.rs @@ -27,7 +27,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx ); // First, run the common hooks also supported by CTFE. - if this.hook_fn(instance, args, dest)? { + if this.hook_panic_fn(instance, args, dest)? { this.goto_block(ret)?; return Ok(None); } From 7bb305201d5186e44538e9ea7e7492f0e8cc38d6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 13 Nov 2019 19:40:18 +0100 Subject: [PATCH 02/11] bump Rust --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index e6d05f2ed0..4e7d0d7831 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -56237d75b4271a8a2e0f47d86ea76ebf6d966152 +a333eed7fc0c903df9d6befcfb40af02148bf255 From c6d3179e26c51dd0039f8ad348aab906431abbab Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 13 Nov 2019 17:27:01 -0500 Subject: [PATCH 03/11] Pass `-Z no-codegen` when invoking rustc. We only need crate metadata and MIR, not the built object files, so this allows us to skip unecessary work when building `libstd`. It also prevents us from trying to codegen the `try` panicking intrinsic, which assumes that `libpanic_unwind` is being compiled for the target platform. We built `libpanic_unwind` with `cfg(miri)`, which may invalidate these assumptions (e.g. the `eh_catch_typeinfo` lang item is no longer defined). --- README.md | 5 +++++ src/lib.rs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d0173aaf0..eb60b88fef 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,11 @@ Several `-Z` flags are relevant for Miri: sets this flag per default. * `-Zmir-emit-retag` controls whether `Retag` statements are emitted. Miri enables this per default because it is needed for validation. +* `-Zno-codegen` makes rustc skip generating LLVM IR for MIR (though it still + writes out empty object files). This is needed to prevent rustc from trying + to codegen certain panic-related intrinsics, which will not work with a + `libpanic_unwind` compiled in `cfg(miri)` mode. It also speeds up + building our custom libstd. Moreover, Miri recognizes some environment variables: diff --git a/src/lib.rs b/src/lib.rs index 59acff3586..c84d13795a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,5 +51,5 @@ pub use crate::eval::{eval_main, create_ecx, MiriConfig}; /// Insert rustc arguments at the beginning of the argument list that Miri wants to be /// set per default, for maximal validation power. pub fn miri_default_args() -> &'static [&'static str] { - &["-Zalways-encode-mir", "-Zmir-emit-retag", "-Zmir-opt-level=0", "--cfg=miri"] + &["-Zalways-encode-mir", "-Zmir-emit-retag", "-Zmir-opt-level=0", "-Zno-codegen", "--cfg=miri"] } From 07fa6f884ba1043de6f37c5c6a0c3cd570262762 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 13 Nov 2019 18:17:03 -0500 Subject: [PATCH 04/11] Revert "Pass `-Z no-codegen` when invoking rustc." This reverts commit c6d3179e26c51dd0039f8ad348aab906431abbab. --- README.md | 5 ----- src/lib.rs | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index eb60b88fef..6d0173aaf0 100644 --- a/README.md +++ b/README.md @@ -172,11 +172,6 @@ Several `-Z` flags are relevant for Miri: sets this flag per default. * `-Zmir-emit-retag` controls whether `Retag` statements are emitted. Miri enables this per default because it is needed for validation. -* `-Zno-codegen` makes rustc skip generating LLVM IR for MIR (though it still - writes out empty object files). This is needed to prevent rustc from trying - to codegen certain panic-related intrinsics, which will not work with a - `libpanic_unwind` compiled in `cfg(miri)` mode. It also speeds up - building our custom libstd. Moreover, Miri recognizes some environment variables: diff --git a/src/lib.rs b/src/lib.rs index c84d13795a..59acff3586 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,5 +51,5 @@ pub use crate::eval::{eval_main, create_ecx, MiriConfig}; /// Insert rustc arguments at the beginning of the argument list that Miri wants to be /// set per default, for maximal validation power. pub fn miri_default_args() -> &'static [&'static str] { - &["-Zalways-encode-mir", "-Zmir-emit-retag", "-Zmir-opt-level=0", "-Zno-codegen", "--cfg=miri"] + &["-Zalways-encode-mir", "-Zmir-emit-retag", "-Zmir-opt-level=0", "--cfg=miri"] } From da61b244ed80390bbbb264bc13e26ebf106a16c1 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 13 Nov 2019 18:19:40 -0500 Subject: [PATCH 05/11] Run `xargo check` instead of `xargo build` to build libstd This gives us crate metadata without running any codegen --- src/bin/cargo-miri.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs index 36545766d1..26cd0ab380 100644 --- a/src/bin/cargo-miri.rs +++ b/src/bin/cargo-miri.rs @@ -318,7 +318,12 @@ path = "lib.rs" let target = get_arg_flag_value("--target"); let print_sysroot = !ask_user && has_arg_flag("--print-sysroot"); // whether we just print the sysroot path let mut command = xargo(); - command.arg("build").arg("-q"); + // This may seen somewhat suprising - we are 'building' libstd + // by running (the equivalent of) `cargo check`. It turns out + // that `cargo check` has exactly the behavior that we want: + // it emits crate metadata (including MIR) without running any + // codegen. + command.arg("check").arg("-q"); command.current_dir(&dir); command.env("RUSTFLAGS", miri::miri_default_args().join(" ")); command.env("XARGO_HOME", dir.to_str().unwrap()); From 2e1ede77328c80625ff675b40a66c5581557267e Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 13 Nov 2019 19:05:08 -0500 Subject: [PATCH 06/11] Use custom Xargo with `cargo_mode` support --- src/bin/cargo-miri.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs index 26cd0ab380..803026574d 100644 --- a/src/bin/cargo-miri.rs +++ b/src/bin/cargo-miri.rs @@ -6,7 +6,7 @@ use std::path::{PathBuf, Path}; use std::process::Command; use std::ops::Not; -const XARGO_MIN_VERSION: (u32, u32, u32) = (0, 3, 17); +const XARGO_MIN_VERSION: (u32, u32, u32) = (0, 3, 18); const CARGO_MIRI_HELP: &str = r#"Interprets bin crates and tests in Miri @@ -266,7 +266,7 @@ fn setup(ask_user: bool) { show_error(format!("Your xargo is too old; please upgrade to the latest version")) } let mut cmd = cargo(); - cmd.args(&["install", "xargo", "-f"]); + cmd.args(&["install", "-f", "--git", "https://github.com/Aaron1011/xargo", "--branch", "feature/cargo-mode"]); ask_to_run(cmd, ask_user, "install a recent enough xargo"); } @@ -294,6 +294,7 @@ fn setup(ask_user: bool) { // The interesting bit: Xargo.toml File::create(dir.join("Xargo.toml")).unwrap() .write_all(br#" +cargo_mode = "check" [dependencies.std] default_features = false # We need the `panic_unwind` feature because we use the `unwind` panic strategy. @@ -323,7 +324,7 @@ path = "lib.rs" // that `cargo check` has exactly the behavior that we want: // it emits crate metadata (including MIR) without running any // codegen. - command.arg("check").arg("-q"); + command.arg("check").arg("-v"); command.current_dir(&dir); command.env("RUSTFLAGS", miri::miri_default_args().join(" ")); command.env("XARGO_HOME", dir.to_str().unwrap()); From 9bdb94fcbfac928f3a4d6491693fc09f3d7a306a Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 13 Nov 2019 19:36:39 -0500 Subject: [PATCH 07/11] Hack around build script issue --- src/bin/cargo-miri.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs index 803026574d..6858adec01 100644 --- a/src/bin/cargo-miri.rs +++ b/src/bin/cargo-miri.rs @@ -476,12 +476,19 @@ fn in_cargo_miri() { fn inside_cargo_rustc() { let sysroot = std::env::var("MIRI_SYSROOT").expect("The wrapper should have set MIRI_SYSROOT"); + let rustc_args = std::env::args().skip(2); // skip `cargo rustc` - let mut args: Vec = rustc_args - .chain(Some("--sysroot".to_owned())) - .chain(Some(sysroot)) - .collect(); - args.splice(0..0, miri::miri_default_args().iter().map(ToString::to_string)); + + let mut args = if std::env::args().skip(2).find(|arg| arg == "build_script_build").is_some() { + rustc_args.collect() + } else { + let mut args: Vec = rustc_args + .chain(Some("--sysroot".to_owned())) + .chain(Some(sysroot)) + .collect(); + args.splice(0..0, miri::miri_default_args().iter().map(ToString::to_string)); + args + }; // See if we can find the `cargo-miri` markers. Those only get added to the binary we want to // run. They also serve to mark the user-defined arguments, which we have to move all the way From b1b454db4e4ed89a3cac201ccc20d8ed7cfb86f7 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 13 Nov 2019 20:24:34 -0500 Subject: [PATCH 08/11] Switch back to non-verbose mode --- src/bin/cargo-miri.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs index 6858adec01..fc22813e3e 100644 --- a/src/bin/cargo-miri.rs +++ b/src/bin/cargo-miri.rs @@ -324,7 +324,7 @@ path = "lib.rs" // that `cargo check` has exactly the behavior that we want: // it emits crate metadata (including MIR) without running any // codegen. - command.arg("check").arg("-v"); + command.arg("check").arg("-q"); command.current_dir(&dir); command.env("RUSTFLAGS", miri::miri_default_args().join(" ")); command.env("XARGO_HOME", dir.to_str().unwrap()); From db95061b37bfc3cfb0ffcccd1771d032192c144d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 14 Nov 2019 14:19:57 -0500 Subject: [PATCH 09/11] Even more hacks --- src/bin/cargo-miri.rs | 83 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs index fc22813e3e..f10bd1b767 100644 --- a/src/bin/cargo-miri.rs +++ b/src/bin/cargo-miri.rs @@ -80,7 +80,7 @@ fn get_arg_flag_value(name: &str) -> Option { } } -fn list_targets() -> impl Iterator { +fn list_targets() -> (impl Iterator, String) { // We need to get the manifest, and then the metadata, to enumerate targets. let manifest_path = get_arg_flag_value("--manifest-path").map(|m| Path::new(&m).canonicalize().unwrap() @@ -119,7 +119,7 @@ fn list_targets() -> impl Iterator { let package = metadata.packages.remove(package_index); // Finally we got the list of targets to build - package.targets.into_iter() + (package.targets.into_iter(), metadata.workspace_root.to_string_lossy().to_string()) } /// Returns the path to the `miri` binary @@ -342,6 +342,7 @@ path = "lib.rs" show_error(format!("Failed to run xargo")); } + // That should be it! But we need to figure out where xargo built stuff. // Unfortunately, it puts things into a different directory when the // architecture matches the host. @@ -410,8 +411,10 @@ fn in_cargo_miri() { return; } + let (targets, root_dir) = list_targets(); + // Now run the command. - for target in list_targets() { + for target in targets { let mut args = std::env::args().skip(skip); let kind = target.kind.get(0).expect( "badly formatted cargo metadata: target::kind is an empty array", @@ -420,7 +423,7 @@ fn in_cargo_miri() { // change to add additional arguments. `FLAGS` is set to identify // this target. The user gets to control what gets actually passed to Miri. let mut cmd = cargo(); - cmd.arg("rustc"); + cmd.arg("check"); match (subcommand, kind.as_str()) { (MiriCommand::Run, "bin") => { // FIXME: we just run all the binaries here. @@ -447,14 +450,24 @@ fn in_cargo_miri() { } cmd.arg(arg); } + + let mut prefixed_args = String::new(); + for arg in args { + prefixed_args += &arg.len().to_string(); + prefixed_args.push(';'); + prefixed_args += &arg; + } + + cmd.env("MIRI_MAGIC_ARGS", prefixed_args); + cmd.env("MIRI_MAGIC_DIR", root_dir.clone()); // Add `--` (to end the `cargo` flags), and then the user flags. We add markers around the // user flags to be able to identify them later. "cargo rustc" adds more stuff after this, // so we have to mark both the beginning and the end. - cmd + /*cmd .arg("--") .arg("cargo-miri-marker-begin") .args(args) - .arg("cargo-miri-marker-end"); + .arg("cargo-miri-marker-end");*/ let path = std::env::current_exe().expect("current executable path invalid"); cmd.env("RUSTC_WRAPPER", path); if verbose { @@ -479,31 +492,71 @@ fn inside_cargo_rustc() { let rustc_args = std::env::args().skip(2); // skip `cargo rustc` - let mut args = if std::env::args().skip(2).find(|arg| arg == "build_script_build").is_some() { - rustc_args.collect() + let (mut args, is_build_script) = if std::env::args().skip(2).find(|arg| arg == "build_script_build").is_some() { + (rustc_args.collect(), true) } else { let mut args: Vec = rustc_args .chain(Some("--sysroot".to_owned())) .chain(Some(sysroot)) .collect(); args.splice(0..0, miri::miri_default_args().iter().map(ToString::to_string)); - args + (args, false) }; + + let is_test = args.contains(&"--test".to_string()); + let mut is_bin = false; + for (i, arg) in args.iter().enumerate() { + if arg == "--crate-type" && args[i + 1] == "bin" { + is_bin = true; + break; + } + } + + + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").ok(); + let expected_dir = std::env::var("MIRI_MAGIC_DIR").ok(); + + //eprintln!("Manifest: {:?}", manifest_dir); + //eprintln!("Magic dir: {:?}", expected_dir); + + // See if we can find the `cargo-miri` markers. Those only get added to the binary we want to // run. They also serve to mark the user-defined arguments, which we have to move all the way // to the end (they get added somewhere in the middle). - let needs_miri = if let Some(begin) = args.iter().position(|arg| arg == "cargo-miri-marker-begin") { - let end = args + //let needs_miri = if let Some(begin) = args.iter().position(|arg| arg == "cargo-miri-marker-begin") { + let needs_miri = if manifest_dir == expected_dir && (is_bin || is_test) && !is_build_script { + /*let end = args .iter() .position(|arg| arg == "cargo-miri-marker-end") .expect("cannot find end marker"); // These mark the user arguments. We remove the first and last as they are the markers. - let mut user_args = args.drain(begin..=end); - assert_eq!(user_args.next().unwrap(), "cargo-miri-marker-begin"); - assert_eq!(user_args.next_back().unwrap(), "cargo-miri-marker-end"); + let mut user_args = args.drain(begin..=end);*/ + + let raw_args = std::env::var("MIRI_MAGIC_ARGS").expect("Misisng magic!"); + let mut user_args = vec![]; + let mut slice = raw_args.as_str(); + //eprintln!("Raw args: {:?}", raw_args); + loop { + match slice.find(';') { + Some(pos) => { + //eprintln!("Slice: {:?} Len str: (pos {}) {:?}", slice, pos, &slice[..(pos)]); + let len: usize = slice[..(pos)].parse().unwrap(); + //eprintln!("Parsed len: {:?}", len); + let arg = slice[(pos+1)..=(pos+len)].to_string(); + user_args.push(arg); + slice = &slice[(pos+len+1)..]; + }, + None => break + } + } + + //println!("User args: {:?}", user_args); + + //assert_eq!(user_args.next().unwrap(), "cargo-miri-marker-begin"); + //assert_eq!(user_args.next_back().unwrap(), "cargo-miri-marker-end"); // Collect the rest and add it back at the end. - let mut user_args = user_args.collect::>(); + //let mut user_args = user_args.collect::>(); args.append(&mut user_args); // Run this in Miri. true From f41c720e919673687be0cb3bbb8abd7fd5a16d4f Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 14 Nov 2019 15:08:05 -0500 Subject: [PATCH 10/11] A bunch of cleanup, fix check for build script --- src/bin/cargo-miri.rs | 93 ++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs index f10bd1b767..a05f62547e 100644 --- a/src/bin/cargo-miri.rs +++ b/src/bin/cargo-miri.rs @@ -80,7 +80,36 @@ fn get_arg_flag_value(name: &str) -> Option { } } -fn list_targets() -> (impl Iterator, String) { +fn is_build_dep(mut args: impl Iterator) -> bool { + args.any(|arg| arg.starts_with("--emit=") && arg.contains("link")) +} + +// Returns whether or not Cargo invoked the wrapper (this binary) to compile +// the final, target crate (either a test for 'cargo test', or a binary for 'cargo run') +// Right now, this is an awful hack that checks several different pieces of information +// to try to figure out if the crate being compiled is the right one. +// Ideally, Cargo would set en environment variable indicating whether or +// not the wrapper is being invoked on the target crate. +// For now, this is the best we can do +fn is_target_crate(is_build_script: bool) -> bool { + // Cargo sets this to the directory containing the manifest of the crate + // the wrapper is being invoekd to compile. This should be unique + // across the entire build (except for build scripts, which we handle below). + // We cannot check the crate name, since this may not be unique + // (e.g. if the build contains multiple versions of the same crate, + // or the same crate from multiple sources) + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").ok(); + + // The manifest directory for our target crate. This is set by `cargo-miri` + // (the original invoation by the user) by using `cargo_metadata` to locate + // the manifest. + let expected_dir = std::env::var("MIRI_MAGIC_DIR").expect("MIRI_MAGIC_DIR not set!"); + + manifest_dir == Some(expected_dir) && !is_build_script + +} + +fn read_cargo_metadata() -> (impl Iterator, String) { // We need to get the manifest, and then the metadata, to enumerate targets. let manifest_path = get_arg_flag_value("--manifest-path").map(|m| Path::new(&m).canonicalize().unwrap() @@ -411,7 +440,7 @@ fn in_cargo_miri() { return; } - let (targets, root_dir) = list_targets(); + let (targets, root_dir) = read_cargo_metadata(); // Now run the command. for target in targets { @@ -460,14 +489,7 @@ fn in_cargo_miri() { cmd.env("MIRI_MAGIC_ARGS", prefixed_args); cmd.env("MIRI_MAGIC_DIR", root_dir.clone()); - // Add `--` (to end the `cargo` flags), and then the user flags. We add markers around the - // user flags to be able to identify them later. "cargo rustc" adds more stuff after this, - // so we have to mark both the beginning and the end. - /*cmd - .arg("--") - .arg("cargo-miri-marker-begin") - .args(args) - .arg("cargo-miri-marker-end");*/ + let path = std::env::current_exe().expect("current executable path invalid"); cmd.env("RUSTC_WRAPPER", path); if verbose { @@ -492,57 +514,34 @@ fn inside_cargo_rustc() { let rustc_args = std::env::args().skip(2); // skip `cargo rustc` - let (mut args, is_build_script) = if std::env::args().skip(2).find(|arg| arg == "build_script_build").is_some() { - (rustc_args.collect(), true) + + eprintln!("cargo rustc env: {:?}", std::env::vars().collect::>()); + + let in_build_script = is_build_dep(std::env::args().skip(2)); + + + let mut args = if in_build_script { + rustc_args.collect() } else { let mut args: Vec = rustc_args .chain(Some("--sysroot".to_owned())) .chain(Some(sysroot)) .collect(); args.splice(0..0, miri::miri_default_args().iter().map(ToString::to_string)); - (args, false) + args }; - - let is_test = args.contains(&"--test".to_string()); - let mut is_bin = false; - for (i, arg) in args.iter().enumerate() { - if arg == "--crate-type" && args[i + 1] == "bin" { - is_bin = true; - break; - } - } - - - let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").ok(); - let expected_dir = std::env::var("MIRI_MAGIC_DIR").ok(); - - //eprintln!("Manifest: {:?}", manifest_dir); - //eprintln!("Magic dir: {:?}", expected_dir); - - // See if we can find the `cargo-miri` markers. Those only get added to the binary we want to // run. They also serve to mark the user-defined arguments, which we have to move all the way // to the end (they get added somewhere in the middle). - //let needs_miri = if let Some(begin) = args.iter().position(|arg| arg == "cargo-miri-marker-begin") { - let needs_miri = if manifest_dir == expected_dir && (is_bin || is_test) && !is_build_script { - /*let end = args - .iter() - .position(|arg| arg == "cargo-miri-marker-end") - .expect("cannot find end marker"); - // These mark the user arguments. We remove the first and last as they are the markers. - let mut user_args = args.drain(begin..=end);*/ - - let raw_args = std::env::var("MIRI_MAGIC_ARGS").expect("Misisng magic!"); + let needs_miri = if is_target_crate(in_build_script) { + let raw_args = std::env::var("MIRI_MAGIC_ARGS").expect("Missing magic!"); let mut user_args = vec![]; let mut slice = raw_args.as_str(); - //eprintln!("Raw args: {:?}", raw_args); loop { match slice.find(';') { Some(pos) => { - //eprintln!("Slice: {:?} Len str: (pos {}) {:?}", slice, pos, &slice[..(pos)]); let len: usize = slice[..(pos)].parse().unwrap(); - //eprintln!("Parsed len: {:?}", len); let arg = slice[(pos+1)..=(pos+len)].to_string(); user_args.push(arg); slice = &slice[(pos+len+1)..]; @@ -551,12 +550,6 @@ fn inside_cargo_rustc() { } } - //println!("User args: {:?}", user_args); - - //assert_eq!(user_args.next().unwrap(), "cargo-miri-marker-begin"); - //assert_eq!(user_args.next_back().unwrap(), "cargo-miri-marker-end"); - // Collect the rest and add it back at the end. - //let mut user_args = user_args.collect::>(); args.append(&mut user_args); // Run this in Miri. true From 4e56a43a4078ad242dadc3e904d184a3dccdd218 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 14 Nov 2019 15:35:27 -0500 Subject: [PATCH 11/11] Remove debug env printing --- src/bin/cargo-miri.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs index a05f62547e..c1832e8b39 100644 --- a/src/bin/cargo-miri.rs +++ b/src/bin/cargo-miri.rs @@ -514,12 +514,8 @@ fn inside_cargo_rustc() { let rustc_args = std::env::args().skip(2); // skip `cargo rustc` - - eprintln!("cargo rustc env: {:?}", std::env::vars().collect::>()); - let in_build_script = is_build_dep(std::env::args().skip(2)); - let mut args = if in_build_script { rustc_args.collect() } else {