Skip to content

Miri sometimes reports memory leak in thread-local storage on *-pc-windows-gnu #123583

@RalfJung

Description

@RalfJung

I've only seen this once, even though the test should be covered by miri-test-libstd every day:

  error: memory leaked: alloc26870878 (Rust heap, size: 8, align: 4), allocated here:
  Error:     --> /checkout/library/alloc/src/alloc.rs:100:9
       |
  100  |         __rust_alloc(layout.size(), layout.align())
       |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       |
       = note: BACKTRACE:
       = note: inside `realstd::alloc::alloc` at /checkout/library/alloc/src/alloc.rs:100:9: 100:52
       = note: inside `realstd::alloc::Global::alloc_impl` at /checkout/library/alloc/src/alloc.rs:183:73: 183:86
       = note: inside `<realstd::alloc::Global as core::alloc::Allocator>::allocate` at /checkout/library/alloc/src/alloc.rs:243:9: 243:39
       = note: inside `alloc_crate::alloc::exchange_malloc` at /checkout/library/alloc/src/alloc.rs:332:11: 332:34
       = note: inside `realstd::boxed::Box::<realstd::sys::thread_local::os_local::Value<u8>>::new` at /checkout/library/alloc/src/boxed.rs:218:9: 218:20
       = note: inside `realstd::thread::local_impl::Key::<u8>::try_initialize::<{closure@/checkout/library/std/src/sys/thread_local/os_local.rs:28:27: 28:34}>` at /checkout/library/std/src/sys/thread_local/os_local.rs:145:37: 145:94
       = note: inside `realstd::thread::local_impl::Key::<u8>::get::<{closure@/checkout/library/std/src/sys/thread_local/os_local.rs:28:27: 28:34}>` at /checkout/library/std/src/sys/thread_local/os_local.rs:127:18: 127:43
  note: inside `sync::reentrant_lock::current_thread_unique_ptr::X::__getit`
      --> /checkout/library/std/src/sys/thread_local/os_local.rs:28:17
       |
  11   |   pub macro thread_local_inner {
       |   ----------------------------
       |   |
       |   in this expansion of `$crate::thread::local_impl::thread_local_inner!` (#2)
       |   in this expansion of `$crate::thread::local_impl::thread_local_inner!` (#3)
  ...
  28   | /                 __KEY.get(move || {
  29   | |                     if let $crate::option::Option::Some(init) = _init {
  30   | |                         if let $crate::option::Option::Some(value) = init.take() {
  31   | |                             return value;
  ...    |
  36   | |                     __init()
  37   | |                 })
       | |__________________^
  ...
  82   |               $crate::thread::local_impl::thread_local_inner!(@key $t, $($init)*);
       |               ------------------------------------------------------------------- in this macro invocation (#3)
       |
      ::: library/std/src/sync/reentrant_lock.rs:318:5
       |
  318  |       thread_local! { static X: u8 = const { 0 } }
       |       -------------------------------------------- in this macro invocation (#1)
       |
      ::: library/std/src/thread/local.rs:183:1
       |
  183  | / macro_rules! thread_local {
  184  | |     // empty (base case for the recursion)
  185  | |     () => {};
  ...    |
  193  | |         $crate::thread::local_impl::thread_local_inner!($(#[$attr])* $vis $name, $t, const $init);
       | |         ----------------------------------------------------------------------------------------- in this macro invocation (#2)
  ...    |
  205  | |     );
  206  | | }
       | |_- in this expansion of `thread_local!` (#1)
       = note: inside `realstd::thread::LocalKey::<u8>::try_with::<{closure@library/std/src/sync/reentrant_lock.rs:319:12: 319:15}, usize>` at /checkout/library/std/src/thread/local.rs:283:32: 283:50
       = note: inside `realstd::thread::LocalKey::<u8>::with::<{closure@library/std/src/sync/reentrant_lock.rs:319:12: 319:15}, usize>` at /checkout/library/std/src/thread/local.rs:260:9: 260:25
  note: inside `sync::reentrant_lock::current_thread_unique_ptr`
      --> library/std/src/sync/reentrant_lock.rs:319:5
       |
  319  |     X.with(|x| <*const _>::addr(x))
       |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  note: inside `sync::reentrant_lock::ReentrantLock::<()>::lock`
      --> library/std/src/sync/reentrant_lock.rs:184:27
       |
  184  |         let this_thread = current_thread_unique_ptr();
       |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  note: inside `sync::reentrant_lock::tests::smoke`
      --> library/std/src/sync/reentrant_lock/tests.rs:10:17
       |
  10   |         let a = l.lock();
       |                 ^^^^^^^^
  note: inside closure
      --> library/std/src/sync/reentrant_lock/tests.rs:7:11
       |
  6    | #[test]
       | ------- in this procedural macro expansion
  7    | fn smoke() {
       |           ^
       |
      ::: /checkout/library/core/src/macros/mod.rs:1636:5
       |
  1636 |     pub macro test($item:item) {
       |     -------------- in this expansion of `#[test]`

Cc @joboet @m-ou-se @Amanieu

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-miriArea: The miri toolA-thread-localsArea: Thread local storage (TLS)C-bugCategory: This is a bug.O-windowsOperating system: Windows

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions