diff options
| author | Ralf Jung <post@ralfj.de> | 2025-07-02 10:40:11 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-02 10:40:11 +0000 |
| commit | 5ce7a04910ccb5d5a053b11d1d87d9f8b7fceee5 (patch) | |
| tree | f0741bf98dc342e39afebf9b895bde343e24e518 | |
| parent | 0d43e2fe2b8d4ef0d0601180ed36958397b641d3 (diff) | |
| parent | 510040fb4447fdb2c40082222e1b8128018a123b (diff) | |
| download | rust-5ce7a04910ccb5d5a053b11d1d87d9f8b7fceee5.tar.gz rust-5ce7a04910ccb5d5a053b11d1d87d9f8b7fceee5.zip | |
Merge pull request #4437 from RalfJung/env-cleanup
skip env var memory for leak check
| -rw-r--r-- | src/tools/miri/src/concurrency/data_race.rs | 8 | ||||
| -rw-r--r-- | src/tools/miri/src/eval.rs | 10 | ||||
| -rw-r--r-- | src/tools/miri/src/machine.rs | 6 | ||||
| -rw-r--r-- | src/tools/miri/src/shims/env.rs | 9 | ||||
| -rw-r--r-- | src/tools/miri/src/shims/unix/env.rs | 26 |
5 files changed, 9 insertions, 50 deletions
diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index 714eb1fba91..b5e7e9d0ac0 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -971,14 +971,6 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> { } } - /// After all threads are done running, this allows data races to occur for subsequent - /// 'administrative' machine accesses (that logically happen outside of the Abstract Machine). - fn allow_data_races_all_threads_done(&mut self) { - let this = self.eval_context_ref(); - assert!(this.have_all_terminated()); - this.machine.data_race.set_ongoing_action_data_race_free(true); - } - /// Calls the callback with the "release" clock of the current thread. /// Other threads can acquire this clock in the future to establish synchronization /// with this program point. diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 44612dae1ee..63578912c24 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -283,16 +283,6 @@ impl<'tcx> MainThreadState<'tcx> { // to be like a global `static`, so that all memory reached by it is considered to "not leak". this.terminate_active_thread(TlsAllocAction::Leak)?; - // Machine cleanup. Only do this if all threads have terminated; threads that are still running - // might cause Stacked Borrows errors (https://github.com/rust-lang/miri/issues/2396). - if this.have_all_terminated() { - // Even if all threads have terminated, we have to beware of data races since some threads - // might not have joined the main thread (https://github.com/rust-lang/miri/issues/2020, - // https://github.com/rust-lang/miri/issues/2508). - this.allow_data_races_all_threads_done(); - EnvVars::cleanup(this).expect("error during env var cleanup"); - } - // Stop interpreter loop. throw_machine_stop!(TerminationInfo::Exit { code: exit_code, leak_check: true }); } diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index ebf04c4f049..4f3dc485325 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -130,11 +130,11 @@ pub enum MiriMemoryKind { WinHeap, /// Windows "local" memory (to be freed with `LocalFree`) WinLocal, - /// Memory for args, errno, and other parts of the machine-managed environment. + /// Memory for args, errno, env vars, and other parts of the machine-managed environment. /// This memory may leak. Machine, - /// Memory allocated by the runtime (e.g. env vars). Separate from `Machine` - /// because we clean it up and leak-check it. + /// Memory allocated by the runtime, e.g. for readdir. Separate from `Machine` because we clean + /// it up (or expect the user to invoke operations that clean it up) and leak-check it. Runtime, /// Globals copied from `tcx`. /// This memory may leak. diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index 9dfb1ebb90a..689cd3a7269 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -59,15 +59,6 @@ impl<'tcx> EnvVars<'tcx> { interp_ok(()) } - pub(crate) fn cleanup(ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>) -> InterpResult<'tcx> { - let this = ecx.eval_context_mut(); - match this.machine.env_vars { - EnvVars::Unix(_) => UnixEnvVars::cleanup(this), - EnvVars::Windows(_) => interp_ok(()), // no cleanup needed - EnvVars::Uninit => interp_ok(()), - } - } - pub(crate) fn unix(&self) -> &UnixEnvVars<'tcx> { match self { EnvVars::Unix(env) => env, diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index a0e5d3f0127..eb4365e2004 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -1,6 +1,6 @@ +use std::env; use std::ffi::{OsStr, OsString}; use std::io::ErrorKind; -use std::{env, mem}; use rustc_abi::{FieldIdx, Size}; use rustc_data_structures::fx::FxHashMap; @@ -50,20 +50,6 @@ impl<'tcx> UnixEnvVars<'tcx> { interp_ok(UnixEnvVars { map: env_vars_machine, environ }) } - pub(crate) fn cleanup(ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>) -> InterpResult<'tcx> { - // Deallocate individual env vars. - let env_vars = mem::take(&mut ecx.machine.env_vars.unix_mut().map); - for (_name, ptr) in env_vars { - ecx.deallocate_ptr(ptr, None, MiriMemoryKind::Runtime.into())?; - } - // Deallocate environ var list. - let environ = &ecx.machine.env_vars.unix().environ; - let old_vars_ptr = ecx.read_pointer(environ)?; - ecx.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?; - - interp_ok(()) - } - pub(crate) fn environ(&self) -> Pointer { self.environ.ptr() } @@ -112,7 +98,7 @@ fn alloc_env_var<'tcx>( let mut name_osstring = name.to_os_string(); name_osstring.push("="); name_osstring.push(value); - ecx.alloc_os_str_as_c_str(name_osstring.as_os_str(), MiriMemoryKind::Runtime.into()) + ecx.alloc_os_str_as_c_str(name_osstring.as_os_str(), MiriMemoryKind::Machine.into()) } /// Allocates an `environ` block with the given list of pointers. @@ -128,7 +114,7 @@ fn alloc_environ_block<'tcx>( ecx.machine.layouts.mut_raw_ptr.ty, u64::try_from(vars.len()).unwrap(), ))?; - let vars_place = ecx.allocate(vars_layout, MiriMemoryKind::Runtime.into())?; + let vars_place = ecx.allocate(vars_layout, MiriMemoryKind::Machine.into())?; for (idx, var) in vars.into_iter_enumerated() { let place = ecx.project_field(&vars_place, idx)?; ecx.write_pointer(var, &place)?; @@ -171,7 +157,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if let Some((name, value)) = new { let var_ptr = alloc_env_var(this, &name, &value)?; if let Some(var) = this.machine.env_vars.unix_mut().map.insert(name, var_ptr) { - this.deallocate_ptr(var, None, MiriMemoryKind::Runtime.into())?; + this.deallocate_ptr(var, None, MiriMemoryKind::Machine.into())?; } this.update_environ()?; interp_ok(Scalar::from_i32(0)) // return zero on success @@ -195,7 +181,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } if let Some(old) = success { if let Some(var) = old { - this.deallocate_ptr(var, None, MiriMemoryKind::Runtime.into())?; + this.deallocate_ptr(var, None, MiriMemoryKind::Machine.into())?; } this.update_environ()?; interp_ok(Scalar::from_i32(0)) @@ -253,7 +239,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Deallocate the old environ list. let environ = this.machine.env_vars.unix().environ.clone(); let old_vars_ptr = this.read_pointer(&environ)?; - this.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Runtime.into())?; + this.deallocate_ptr(old_vars_ptr, None, MiriMemoryKind::Machine.into())?; // Write the new list. let vals = this.machine.env_vars.unix().map.values().copied().collect(); |
