Skip to content

Commit

Permalink
test both kinds of TLS
Browse files Browse the repository at this point in the history
  • Loading branch information
max-heller committed Jul 17, 2023
1 parent 81ea21b commit 6f688d5
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 31 deletions.
21 changes: 21 additions & 0 deletions tests/fail/leak_in_os_tls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//@error-in-other-file: memory leaked
//@normalize-stderr-test: ".*│.*" -> "$$stripped$$"

use std::cell::Cell;

pub fn main() {
thread_local! {
static TLS: Cell<Option<&'static i32>> = Cell::new(None);
}

std::thread::spawn(|| {
TLS.with(|cell| {
cell.set(Some(Box::leak(Box::new(123))));
});
})
.join()
.unwrap();

// Imagine the program running for a long time while the thread is gone
// and this memory still sits around, unused -- leaked.
}
32 changes: 32 additions & 0 deletions tests/fail/leak_in_os_tls.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here:
--> RUSTLIB/alloc/src/alloc.rs:LL:CC
|
LL | __rust_alloc(layout.size(), layout.align())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: inside `std::alloc::alloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
= note: inside `std::alloc::Global::alloc_impl` at RUSTLIB/alloc/src/alloc.rs:LL:CC
= note: inside `<std::alloc::Global as std::alloc::Allocator>::allocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC
= note: inside `alloc::alloc::exchange_malloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
= note: inside `std::boxed::Box::<i32>::new` at RUSTLIB/alloc/src/boxed.rs:LL:CC
note: inside closure
--> $DIR/leak_in_os_tls.rs:LL:CC
|
LL | cell.set(Some(Box::leak(Box::new(123))));
| ^^^^^^^^^^^^^
= note: inside `std::thread::LocalKey::<std::cell::Cell<std::option::Option<&i32>>>::try_with::<[closure@$DIR/leak_in_os_tls.rs:LL:CC], ()>` at RUSTLIB/std/src/thread/local.rs:LL:CC
= note: inside `std::thread::LocalKey::<std::cell::Cell<std::option::Option<&i32>>>::with::<[closure@$DIR/leak_in_os_tls.rs:LL:CC], ()>` at RUSTLIB/std/src/thread/local.rs:LL:CC
note: inside closure
--> $DIR/leak_in_os_tls.rs:LL:CC
|
LL | / TLS.with(|cell| {
LL | | cell.set(Some(Box::leak(Box::new(123))));
LL | | });
| |__________^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check

error: aborting due to previous error

14 changes: 5 additions & 9 deletions tests/fail/leak_in_tls.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
//@error-in-other-file: memory leaked
//@normalize-stderr-test: ".*│.*" -> "$$stripped$$"

#![feature(thread_local)]

use std::cell::Cell;

pub fn main() {
thread_local! {
static REF: Cell<Option<&'static i32>> = Cell::new(None);
}
#[thread_local]
static TLS: Cell<Option<&'static i32>> = Cell::new(None);

std::thread::spawn(|| {
REF.with(|cell| {
let a = 123;
let b = Box::new(a);
let r = Box::leak(b);
cell.set(Some(r));
})
TLS.set(Some(Box::leak(Box::new(123))));
})
.join()
.unwrap();
Expand Down
16 changes: 2 additions & 14 deletions tests/fail/leak_in_tls.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,8 @@ LL | __rust_alloc(layout.size(), layout.align())
note: inside closure
--> $DIR/leak_in_tls.rs:LL:CC
|
LL | let b = Box::new(a);
| ^^^^^^^^^^^
= note: inside `std::thread::LocalKey::<std::cell::Cell<std::option::Option<&i32>>>::try_with::<[closure@$DIR/leak_in_tls.rs:LL:CC], ()>` at RUSTLIB/std/src/thread/local.rs:LL:CC
= note: inside `std::thread::LocalKey::<std::cell::Cell<std::option::Option<&i32>>>::with::<[closure@$DIR/leak_in_tls.rs:LL:CC], ()>` at RUSTLIB/std/src/thread/local.rs:LL:CC
note: inside closure
--> $DIR/leak_in_tls.rs:LL:CC
|
LL | / REF.with(|cell| {
LL | | let a = 123;
LL | | let b = Box::new(a);
LL | | let r = Box::leak(b);
LL | | cell.set(Some(r));
LL | | })
| |__________^
LL | TLS.set(Some(Box::leak(Box::new(123))));
| ^^^^^^^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

Expand Down
19 changes: 11 additions & 8 deletions tests/pass/issues/issue-miri-2881.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
#![feature(thread_local)]

use std::cell::Cell;

pub fn main() {
let a = 123;
let b = Box::new(a);
let r = Box::leak(b);

thread_local! {
static REF: Cell<Option<&'static i32>> = Cell::new(None);
static TLS_KEY: Cell<Option<&'static i32>> = Cell::new(None);
}

REF.with(|cell| {
cell.set(Some(r));
})
TLS_KEY.with(|cell| {
cell.set(Some(Box::leak(Box::new(123))));
});

#[thread_local]
static TLS: Cell<Option<&'static i32>> = Cell::new(None);

TLS.set(Some(Box::leak(Box::new(123))));
}

0 comments on commit 6f688d5

Please sign in to comment.