<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/64512>64512</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[libunwind] Runtime lookup of `dl_find_object` deadlocks with jemalloc memory profiler when linked against glibc < 2.35
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
itrofimow
</td>
</tr>
</table>
<pre>
When `libunwind` is compiled with glibc2.35 headers and the executable is linked against glibc2.31 and jemalloc, [runtime lookup](https://github.com/llvm/llvm-project/blob/release/16.x/libunwind/src/AddressSpace.hpp#L591) of `dl_find_object` deadlocks, if jemalloc memory profiling is enabled:
```
(lldb) bt
* thread #1, name = 'jemalloc_libunw', stop reason = signal SIGSTOP
* frame #0: 0x00007ffff7f83170 libpthread.so.0`__lll_lock_wait(futex=0x0000000000546590, private=0) at lowlevellock.c:52:7
frame #1: 0x00007ffff7f7b0a3 libpthread.so.0`__GI___pthread_mutex_lock(mutex=0x0000000000546590) at pthread_mutex_lock.c:80:7
frame #2: 0x00000000004ea055 jemalloc_libunwind`je_malloc_mutex_lock_slow [inlined] malloc_mutex_lock_final(mutex=0x0000000000546550) at mutex.h:151:2
frame #3: 0x00000000004ea04d jemalloc_libunwind`je_malloc_mutex_lock_slow(mutex=0x0000000000546550) at mutex.c:90:2
frame #4: 0x00000000004b4086 jemalloc_libunwind`malloc_init_hard [inlined] malloc_mutex_lock(tsdn=0x0000000000000000, mutex=<unavailable>) at mutex.h:217:4
>>>> frame #5: 0x00000000004b4060 jemalloc_libunwind`malloc_init_hard at jemalloc.c:2118:2
frame #6: 0x000000000049e68d jemalloc_libunwind`calloc [inlined] malloc_init at jemalloc.c:298:41
frame #7: 0x000000000049e688 jemalloc_libunwind`calloc [inlined] imalloc_init_check(sopts=<unavailable>, dopts=<unavailable>) at jemalloc.c:2658:41
frame #8: 0x000000000049e688 jemalloc_libunwind`calloc [inlined] imalloc(sopts=<unavailable>, dopts=<unavailable>) at jemalloc.c:2689:32
frame #9: 0x000000000049df42 jemalloc_libunwind`calloc(num=1, size=32) at jemalloc.c:2852:2
frame #10: 0x00007ffff7f9ec05 libdl.so.2`_dlerror_run(operate=(libdl.so.2`dlsym_doit at dlsym.c:47:1), args=0x00007fffffffd700) at dlerror.c:148:41
frame #11: 0x00007ffff7f9e525 libdl.so.2`__dlsym(handle=0x0000000000000000, name="_dl_find_object") at dlsym.c:70:19
frame #12: 0x000000000038f53c jemalloc_libunwind`libunwind::LocalAddressSpace::findUnwindSections(this=0x0000000000536541, targetAddr=3746225, info=0x00007fffffffd838) at AddressSpace.hpp:599:9
frame #13: 0x000000000038d451 jemalloc_libunwind`libunwind::UnwindCursor<libunwind::LocalAddressSpace, libunwind::Registers_x86_64>::setInfoBasedOnIPRegister(this=0x00007fffffffdbb0, isReturnAddress=false) at UnwindCursor.hpp:1955:21
frame #14: 0x000000000038c671 jemalloc_libunwind`__unw_init_local(cursor=0x00007fffffffdbb0, context=<unavailable>) at libunwind.cpp:87:7
frame #15: 0x00000000003929c4 jemalloc_libunwind`_Unwind_Backtrace(callback=(jemalloc_libunwind`prof_unwind_init_callback at prof_sys.c:71:2), ref=0x0000000000000000) at UnwindLevel1-gcc-ext.c:103:3
frame #16: 0x00000000004ee34f jemalloc_libunwind`je_prof_boot2(tsd=0x00007ffff7c2a748, base=<unavailable>) at prof.c:693:3
>>>> frame #17: 0x00000000004b44ac jemalloc_libunwind`malloc_init_hard at jemalloc.c:2151:21
frame #18: 0x000000000049b03b jemalloc_libunwind`je_malloc_default [inlined] malloc_init at jemalloc.c:298:41
frame #19: 0x000000000049b036 jemalloc_libunwind`je_malloc_default [inlined] imalloc_init_check(sopts=<unavailable>, dopts=<unavailable>) at jemalloc.c:2658:41
frame #20: 0x000000000049b036 jemalloc_libunwind`je_malloc_default [inlined] imalloc(sopts=<unavailable>, dopts=<unavailable>) at jemalloc.c:2689:32
frame #21: 0x000000000049a916 jemalloc_libunwind`je_malloc_default(size=8) at jemalloc.c:2722:2
frame #22: 0x00000000003a8225 jemalloc_libunwind`operator new(size=8) at memory.cc:0
... some other frames
```
This happens because jemalloc profiling initialization [initializes backtracing machinery](https://github.com/jemalloc/jemalloc/blob/424dd61d57500712fad7371bfd921cb9e3caee22/src/prof_sys.c#L443) while holding a global init lock, and `dlsym` happens to allocate in glibc2.31; that allocation tries to acquire the same global init lock and thus deadlocks.
This doesn't seem to happen with glibc2.35+ due to changes in `dlsym`/`_dlerror_run`, not did it happen prior to llvm-16 (`dl_find_object` logic was merged in 16).
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEmN1u27gSgJ-GviFqUKR-L3zhxJtFgQK7aPfgXAoUObLY0KIPSdXJPv0BKf_VkpsU6GKNIIklkvPNDDkzHO6c2vYAK5Q9oGyz4IPvjF0pb02rduawaIx8Xf23gx6jnGjVDP1B9RLlBCuHhdntlQaJD8p3eKtVI-iSZbgDLsE6zHuJfQcYXkAMnjcawiyt-meQmG-56p0_T0vi8K-w41obgegjRtmDHXqvdoC1Mc_DHmUbRMvO-71DbI3oE6JPW-W7oVkKs0P0Setvpz8f9tZ8BeERfWq0aRB9sqCBO0D0KcmXL2HYWR365KxA9GktpQXnvuy5gGW33yPKPmVVgmiFTRssIHXdql7Wpolr5wRL4FIb8ewCsWrPCuAd7Ix9xftgSa36bVAd-mAEGeDJBpHT75wcf8avtNRaNkFo40-P1th3FrjEiLIkiOr5DjBiG4xocZJZjxohWoQRzps9tsCd6ePA4Gmu8ZePv3_5648_x4UxDku3Ni5GGUFsjckLIYQUbdu2RVuypCBYq2Y_yl86swyoda21roPi9YErj2jZDh5eENuM08dPluZZRQLM3qpv3EN4HxTjHmtz0PANAvfzUiC2zihi6-LEhS9UyYSqaAhns1S_f6zr-vi03gWkCIloufsBXwSazopYJbmDRS9Y4ycFTrIM33hjPC5foT4-vSxfO20OYZerXqseJMo2eDqoVT3XP-DPTvxxwLJDbJ1kwWT0yHwGZnPAqfxJ4PejBOtV5Irk2nrpBKZJSZnPwxwfqV75uuNWvmU0REvvZH-DOH7CbjwpgNjj0PNvXOlwLhH7bWJKmhSIrdPjMWS_nX--UyabUyYn71SG-_PAaDOaJOUdq-UTQRXk5R0XijEQzdoqSJ8KroLcNJkRXMwKLn9CsLrWW3QQveTM3rt5Rzxief9lNWXPs7vw5a-C_8XEZYXYmk3OaTXFlW1Kf4SLaNkPO8Q2MTc49XeItIzOii1joJ3bXck0_lcgSBYirdQhyNIQZKUGa42t7dAjWpo92DGyh8R1PVBq97qrpRl3WvwWCdKwmUJSDazcbt35nEahbdvKgpxCyVFYnJikd12cTJNEBRm9Ra8jRSgieC813A0QIbtGjWh9k_IpPYOd9CmC2ZJqjmqSI1jZZkzMu_LyP1sjtv5kBNfXFcn4OMD8Jw77AsIr07sQ7TrlbgMyy7M0bgfP7RZ8WClsiiLNKc1itdK3Zmr6kpVHDSfVEFtnVdic1e2OTSaphZUyzZJ36Tkq8zhYZyxij29agT7imzGfYaucB-vqlzKv8zRG6PDCgf_Yt-aBO5B_9B__PA28tdhZ-aaJ7lfuM_jB9ke5iG1arkPpGO1yDXy0S1JlWYzcc5tgkupYKfLijnHqeugPY5DUQXVES3E0zR1YYXoPL_4HYee8_lJE2rK4V2lNEhmraCXSO6ijIeoHLp69ja4pQzhquHgew8HstFAR1-O3YzI4zolFWHjpXt14sMYyZgwUFto7x_XKKZ9CRZl82ArxAV78GDRI2JxsTttpNgVgaXu3IIpwjTGejgXG9y4pBOVFWgbWJtwz7vsjrBPZ8uqK7W51kUyTb5Om_E4UeUd5MZaHs3t1JlU2hDVv1YgSWj5o_2tqjWQmATaE3akN34L4F-sOSv4BRf7RGuQ7-mRKz6vkvfSBc6xDylnJBb1XhtBp1uQlpXduVmP9YSzu4TCVOd7ClyKIJBdZy-USO7MDbHwHdhTt5m_j8fdfnXK44_s99A43IPjg4HLVv7rj98orrtXfPGTm0YHHJ-BwcwyUYeSOi071YF_fbGpcWiLX_x6bGilNpcwTmRUZIUVCWy4LViRNKyuaiKYCJjhAKFqOLY6rAEvZpzRlwVCHTmnAndEyoHG81abhOmqDx_vUY-zOnIo6lJOzNbzBkYl7wKq_tHMQe8C-4_70NtjDWwXjDPG_QVmI3SEX3H4r8dg7GtylwbKcOEQacD2ihccOYBfWHaFu-lGIPmA5QHgvOt5vwQXQK12C0W_q2nwsA43HUkms_GnlvVXGhpVijynJMaLlbF9Im60S-MAd3oHdggwikxzRarmQKyYrVvEFrJK8StKsKBK26FaUJqKgQFiTiorzgrQFpRkRCSdV2xbVQq0ooYyUpCQJTTK2zARtSpIkRSrSjKQpSgnsuNLLQLc0drtQzg2wytMsoQvNG9Autvoo7eGA48tQ0WabhV1FjZph61BKtHLeXVbxyuvYI7wcvGyDP3_XnHu7Qza6Zb5BBhYfOuhnm4MYsUccHLkYrF79dPsvaukQfYpW-H8AAAD__7xdds0">