diff --git a/src/bin/miri.rs b/src/bin/miri.rs index 489eb959906..430f9e2f637 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -306,6 +306,11 @@ fn parse_comma_list(input: &str) -> Result, T::Err> { } fn main() { + // Snapshot a copy of the environment before `rustc` starts messing with it. + // (`install_ice_hook` might change `RUST_BACKTRACE`.) + let env_snapshot = env::vars_os().collect::>(); + + // Earliest rustc setup. rustc_driver::install_ice_hook(); // If the environment asks us to actually be rustc, then do that. @@ -333,6 +338,8 @@ fn main() { // Parse our arguments and split them across `rustc` and `miri`. let mut miri_config = miri::MiriConfig::default(); + miri_config.env = env_snapshot; + let mut rustc_args = vec![]; let mut after_dashdash = false; diff --git a/src/eval.rs b/src/eval.rs index cb24dea3a88..981776e3eeb 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -1,7 +1,7 @@ //! Main evaluator loop and setting up the initial stack frame. use std::collections::HashSet; -use std::ffi::OsStr; +use std::ffi::{OsStr, OsString}; use std::iter; use std::panic::{self, AssertUnwindSafe}; use std::thread; @@ -72,6 +72,9 @@ pub enum BacktraceStyle { /// Configuration needed to spawn a Miri instance. #[derive(Clone)] pub struct MiriConfig { + /// The host environment snapshot to use as basis for what is provided to the interpreted program. + /// (This is still subject to isolation as well as `excluded_env_vars` and `forwarded_env_vars`.) + pub env: Vec<(OsString, OsString)>, /// Determine if validity checking is enabled. pub validate: bool, /// Determines if Stacked Borrows is enabled. @@ -130,6 +133,7 @@ pub struct MiriConfig { impl Default for MiriConfig { fn default() -> MiriConfig { MiriConfig { + env: vec![], validate: true, stacked_borrows: true, check_alignment: AlignmentCheck::Int, diff --git a/src/shims/env.rs b/src/shims/env.rs index db1ddf6291f..07b9cf18192 100644 --- a/src/shims/env.rs +++ b/src/shims/env.rs @@ -49,11 +49,11 @@ pub(crate) fn init<'mir>( // Skip the loop entirely if we don't want to forward anything. if ecx.machine.communicate() || !config.forwarded_env_vars.is_empty() { - for (name, value) in env::vars_os() { + for (name, value) in &config.env { // Always forward what is in `forwarded_env_vars`; that list can take precedence over excluded_env_vars. - let forward = config.forwarded_env_vars.iter().any(|v| **v == name) + let forward = config.forwarded_env_vars.iter().any(|v| **v == *name) || (ecx.machine.communicate() - && !excluded_env_vars.iter().any(|v| **v == name)); + && !excluded_env_vars.iter().any(|v| **v == *name)); if forward { let var_ptr = match target_os { target if target_os_is_unix(target) => @@ -65,7 +65,7 @@ pub(crate) fn init<'mir>( unsupported ), }; - ecx.machine.env_vars.map.insert(name, var_ptr); + ecx.machine.env_vars.map.insert(name.clone(), var_ptr); } } }