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.

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