Skip to content

Commit

Permalink
Auto merge of rust-lang#3501 - RalfJung:tls-many-seeds, r=RalfJung
Browse files Browse the repository at this point in the history
add a test for the TLS memory leak

This is a regression test for rust-lang#123583.
  • Loading branch information
bors committed Apr 25, 2024
2 parents e22a73c + 247e82c commit 9713294
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 12 deletions.
18 changes: 11 additions & 7 deletions src/tools/miri/ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,18 @@ function run_tests_minimal {
## Main Testing Logic ##

# In particular, fully cover all tier 1 targets.
# We also want to run the many-seeds tests on all tier 1 targets.
case $HOST_TARGET in
x86_64-unknown-linux-gnu)
# Host
GC_STRESS=1 MIR_OPT=1 MANY_SEEDS=64 TEST_BENCH=1 CARGO_MIRI_ENV=1 run_tests
# Extra tier 1
MIRI_TEST_TARGET=i686-unknown-linux-gnu run_tests
MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
MIRI_TEST_TARGET=x86_64-apple-darwin run_tests
MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
MIRI_TEST_TARGET=x86_64-pc-windows-gnu run_tests
# With reduced many-seed count to avoid spending too much time on that.
# (All OSes are run with 64 seeds at least once though via the macOS runner.)
MANY_SEEDS=16 MIRI_TEST_TARGET=i686-unknown-linux-gnu run_tests
MANY_SEEDS=16 MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
MANY_SEEDS=16 MIRI_TEST_TARGET=x86_64-apple-darwin run_tests
MANY_SEEDS=16 MIRI_TEST_TARGET=x86_64-pc-windows-gnu run_tests
# Extra tier 2
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
MIRI_TEST_TARGET=arm-unknown-linux-gnueabi run_tests
Expand All @@ -155,13 +157,15 @@ case $HOST_TARGET in
# Host (tier 2)
GC_STRESS=1 MIR_OPT=1 MANY_SEEDS=64 TEST_BENCH=1 CARGO_MIRI_ENV=1 run_tests
# Extra tier 1
MIRI_TEST_TARGET=x86_64-pc-windows-msvc CARGO_MIRI_ENV=1 run_tests
MANY_SEEDS=64 MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
MANY_SEEDS=64 MIRI_TEST_TARGET=x86_64-pc-windows-msvc CARGO_MIRI_ENV=1 run_tests
# Extra tier 2
MIRI_TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture
;;
i686-pc-windows-msvc)
# Host
# Only smoke-test `many-seeds`; 64 runs take 15min here!
# Only smoke-test `many-seeds`; 64 runs of just the scoped-thread-leak test take 15min here!
# See <https://github.com/rust-lang/miri/issues/3509>.
GC_STRESS=1 MIR_OPT=1 MANY_SEEDS=1 TEST_BENCH=1 run_tests
# Extra tier 1
# We really want to ensure a Linux target works on a Windows host,
Expand Down
4 changes: 3 additions & 1 deletion src/tools/miri/src/concurrency/weak_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,9 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
validate,
)?;
if global.track_outdated_loads && recency == LoadRecency::Outdated {
this.emit_diagnostic(NonHaltingDiagnostic::WeakMemoryOutdatedLoad);
this.emit_diagnostic(NonHaltingDiagnostic::WeakMemoryOutdatedLoad {
ptr: place.ptr(),
});
}

return Ok(loaded);
Expand Down
11 changes: 7 additions & 4 deletions src/tools/miri/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ pub enum NonHaltingDiagnostic {
Int2Ptr {
details: bool,
},
WeakMemoryOutdatedLoad,
WeakMemoryOutdatedLoad {
ptr: Pointer<Option<Provenance>>,
},
}

/// Level of Miri specific diagnostics
Expand Down Expand Up @@ -583,7 +585,8 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
| AccessedAlloc(..)
| FreedAlloc(..)
| ProgressReport { .. }
| WeakMemoryOutdatedLoad => ("tracking was triggered".to_string(), DiagLevel::Note),
| WeakMemoryOutdatedLoad { .. } =>
("tracking was triggered".to_string(), DiagLevel::Note),
};

let msg = match &e {
Expand All @@ -610,8 +613,8 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
ProgressReport { .. } =>
format!("progress report: current operation being executed is here"),
Int2Ptr { .. } => format!("integer-to-pointer cast"),
WeakMemoryOutdatedLoad =>
format!("weak memory emulation: outdated value returned from load"),
WeakMemoryOutdatedLoad { ptr } =>
format!("weak memory emulation: outdated value returned from load at {ptr}"),
};

let notes = match &e {
Expand Down
26 changes: 26 additions & 0 deletions src/tools/miri/tests/many-seeds/tls-leak.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//! Regression test for <https://github.com/rust-lang/rust/issues/123583>.
use std::thread;

fn with_thread_local1() {
thread_local! { static X: Box<u8> = Box::new(0); }
X.with(|_x| {})
}

fn with_thread_local2() {
thread_local! { static Y: Box<u8> = Box::new(0); }
Y.with(|_y| {})
}

fn main() {
// Here we have two threads racing on initializing the thread-local and adding it to the global
// dtor list (on targets that have such a list, i.e., targets without target_thread_local).
let t = thread::spawn(with_thread_local1);
with_thread_local1();
t.join().unwrap();

// Here we have one thread running the destructors racing with another thread initializing a
// thread-local. The second thread adds a destructor that could be picked up by the first.
let t = thread::spawn(|| { /* immediately just run destructors */ });
with_thread_local2(); // initialize thread-local
t.join().unwrap();
}

0 comments on commit 9713294

Please sign in to comment.