Skip to content

Infinite recursion when glibc uses malloc in __tls_get_addr #131

@arvid-norlander

Description

@arvid-norlander

I'm seeing infinite recursion between thread locals in bytehound and glibc trying to allocate more memory for threadlocals. This predictably results in a crash:

(gdb) bt
#0  0x00007fe521441a2a in thread_local_reentrant::Key::access::{closure#0}<bytehound::global::TLS, core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, bytehound::global::{impl#5}::acquire::{closure_env#0}> (slot=<error reading variable: Cannot access memory at address 0x0>)
    at /home/USER/.cargo/git/checkouts/not-perf-af1a46759dd83df9/911723c/thread-local-reentrant/src/lib.rs:120
#1  bytehound::global::{impl#14}::access_raw::{closure#0}<core::result::Result<core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, thread_local_reentrant::AccessError>, thread_local_reentrant::Key::access::{closure_env#0}<bytehound::global::TLS, core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, bytehound::global::{impl#5}::acquire::{closure_env#0}>> (slot=<error reading variable: Cannot access memory at address 0x0>)
    at /home/USER/.cargo/git/checkouts/not-perf-af1a46759dd83df9/911723c/thread-local-reentrant/src/lib.rs:161
#2  std::thread::local::LocalKey<thread_local_reentrant::Slot<bytehound::global::ThreadSentinel>>::try_with<thread_local_reentrant::Slot<bytehound::global::ThreadSentinel>, bytehound::global::{impl#14}::access_raw::{closure_env#0}<core::result::Result<core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, thread_local_reentrant::AccessError>, thread_local_reentrant::Key::access::{closure_env#0}<bytehound::global::TLS, core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, bytehound::global::{impl#5}::acquire::{closure_env#0}>>, core::result::Result<core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, thread_local_reentrant::AccessError>> (self=<optimised out>, f=...)
    at /rustc/c0983a9aac889d16722a12602ac678051e62c3fb/library/std/src/thread/local.rs:446
#3  std::thread::local::LocalKey<thread_local_reentrant::Slot<bytehound::global::ThreadSentinel>>::with<thread_local_reentrant::Slot<bytehound::global::ThreadSentinel>, bytehound::global::{impl#14}::access_raw::{closure_env#0}<core::result::Result<core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, thread_local_reentrant::AccessError>, thread_local_reentrant::Key::access::{closure_env#0}<bytehound::global::TLS, core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, bytehound::global::{impl#5}::acquire::{closure_env#0}>>, core::result::Result<core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, thread_local_reentrant::AccessError>> (self=<optimised out>, f=...)
    at /rustc/c0983a9aac889d16722a12602ac678051e62c3fb/library/std/src/thread/local.rs:422
#4  bytehound::global::{impl#14}::access_raw<core::result::Result<core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, thread_local_reentrant::AccessError>, thread_local_reentrant::Key::access::{closure_env#0}<bytehound::global::TLS, core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, bytehound::global::{impl#5}::acquire::{closure_env#0}>> () at preload/src/api.rs:294
#5  thread_local_reentrant::Key::access<bytehound::global::TLS, core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, bytehound::global::{impl#5}::acquire::{closure_env#0}> () at /home/USER/.cargo/git/checkouts/not-perf-af1a46759dd83df9/911723c/thread-local-reentrant/src/lib.rs:119
#6  bytehound::global::TLS::try_with<core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, bytehound::global::{impl#5}::acquire::{closure_env#0}> ()
    at /home/USER/.cargo/git/checkouts/not-perf-af1a46759dd83df9/911723c/thread-local-reentrant/src/lib.rs:169
#7  bytehound::global::StrongThreadHandle::acquire () at preload/src/global.rs:809
#8  bytehound::api::allocate () at preload/src/api.rs:216
#9  bytehound::api::malloc (size=960) at preload/src/api.rs:294
#10 0x00007fe52188bd01 in malloc (size=<optimised out>) at ../include/rtld-malloc.h:56
#11 _dl_resize_dtv (dtv=dtv@entry=0x7fe4ee8b7c60, max_modid=max_modid@entry=44) at ../elf/dl-tls.c:493
#12 0x00007fe52188c9b4 in _dl_update_slotinfo (req_modid=1, new_gen=8) at ../elf/dl-tls.c:809
#13 0x00007fe52188cac4 in update_get_addr (ti=0x7fe5215a3b00, gen=<optimised out>) at ../elf/dl-tls.c:916
#14 0x00007fe52188f85c in __tls_get_addr () at ../sysdeps/x86_64/tls_get_addr.S:55
#15 0x00007fe521441a2f in thread_local_reentrant::Key::access::{closure#0}<bytehound::global::TLS, core::option::Option<bytehound::arc_lite::ArcLite<bytehound::global::ThreadData>>, bytehound::global::{impl#5}::acquire::{closure_env#0}> (slot=<error reading variable: Cannot access memory at address 0x0>)
[... thousands of repeats of the above frames...]

Unfortunately this is on a proprietary application, so I cannot share the source. We seem to have had 21 threads running when the crash happens (very early during execution) but this varies a bit from run to run. I don't know how many thread locals we had.

  • Kubuntu 24.04
  • GNU C Library (Ubuntu GLIBC 2.39-0ubuntu8.4) stable release version 2.39.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions