Skip to content

wasm32-wasip2 spins on pthread_key_delete #160828

Description

@Mark-Simulacrum

I'm working on the wasm proc macros (so it's possible I messed something up in wasmtime bindings or similar), and I'm encountering an infinite loop on some of the wasm executions with this stack:

__pthread_key_delete
<std::sys::thread_local::key::racy::LazyKey>::lazy_init
std::sys::thread_local::destructors::list::register
<std::sys::thread_local::native::lazy::Storage<core::cell::RefCell<proc_macro::bridge::symbol::Interner>, ()>>::get_or_init_slow::<proc_macro::bridge::symbol::INTERNER::__rust_std_internal>
<proc_macro::bridge::symbol::Symbol>::new

After inserting some dbg! into the std thread local implementation it looks like we're seeing this sequence:

  • lazy_init()
  • pthread_key_create() = 0
  • pthread_key_create() = 1, called because 0 is the sentinel value (
    const KEY_SENTVAL: usize = 0;
    )
  • pthread_key_delete(0), which appears to spin (~100% CPU in wasmtime, although I'm having trouble debugging why)

Unfortunately I can't seem to reproduce this outside of my proc macro setting... in a standalone program a thread local seems to register just fine. Maybe it has to do with the number of thread locals or something like that? The proc macro spinning appears fixed if I revert #159733, however, so I suspect there's some kind of bug here. At minimum, it seems like we might want to redefine SENTVAL since it looks like the wasi libc does return 0 -- that I can reproduce in and out of proc macro setting.

I think we are in this loop: https://github.com/WebAssembly/wasi-libc/blob/8d8348ec24253d0638a693b8af82445c13d92d32/libc-top-half/musl/src/thread/common/pthread_key_create.c#L69-L70, here is the assembly (generated by wasmtime at runtime) I've managed to collect by single-stepping in gdb (my gdb has a tendency to segfault though when trying to do anything too advanced in this code, but I think this is an accurate trace, and it seems to reproduce across multiple compilations):

=> 0x7f6d861f5e16 <__pthread_key_delete+86>:    mov    eax,esi
=> 0x7f6d861f5e18 <__pthread_key_delete+88>:    lea    rcx,[r12+rax*1]
=> 0x7f6d861f5e1c <__pthread_key_delete+92>:    mov    rdx,r13
=> 0x7f6d861f5e1f <__pthread_key_delete+95>:    add    edx,DWORD PTR [rcx+0x44]
=> 0x7f6d861f5e22 <__pthread_key_delete+98>:    mov    DWORD PTR [r12+rdx*1],0x0
=> 0x7f6d861f5e2a <__pthread_key_delete+106>:   mov    esi,DWORD PTR [r12+rax*1+0x8]
=> 0x7f6d861f5e2f <__pthread_key_delete+111>:   cmp    esi,0x104ae0
=> 0x7f6d861f5e35 <__pthread_key_delete+117>:   jne    0x7f6d861f5e16 <__pthread_key_delete+86>

cc @alexcrichton as you filed the PR seemingly introducing this in case you have any ideas. I think I'm building against wasi-sdk 33, which appears to be the same as the CI SDK.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-thread-localsArea: Thread local storage (TLS)O-wasiOperating system: Wasi, Webassembly System Interface

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions