Package: src:fakechroot
Version: 2.19-3
Severity: serious

Hi again,

So jemalloc 5.1.0-2 was recently uploaded to unstable. The build
currently fails due to the explicit dependency on libjemalloc1 (cf.
#918741), but as soon as this gets fixed, another issue is uncovered:

While building this package, the jemalloc test deadlocks, and the build
hangs. This can be easily reproduced as follows:
  apt install libfakechroot libjemalloc2
  LD_PRELOAD="libjemalloc.so.2 libfakechroot.so" /bin/true
  <hangs>

The test isn't spurious but an actual issue. One could do:
  fakechroot <binary compiled with -ljemalloc>
...and still hit this bug.

The bug is effectively the same as #872669, which I had previously
resolved by disabling jemalloc's --enable-prof. This option was
re-enabled in 5.x (I forgot about that bug :/) and...  I'd like to keep
it that way, so I tried to troubleshoot this further.

It looks like there's a preloading loop between those libraries that
results in deadlocking. Effectively, during its initialization
(malloc_init) jemalloc tries to initialize libgcc's unwind code
(_Unwind_Backtrace), which in turn calls dl_iterate_phdr, which is
captured by libfakechroot, which calls dlsym()/dlerror(), which tries to
allocate memory back again, which deadlocks jemalloc.

The backtrace is (note how #6 and #20 are the same):
#0  __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:103
#1  0x00007fd764008704 in __GI___pthread_mutex_lock (mutex=0x7fd7647a0500 
<init_lock+64>) at ../nptl/pthread_mutex_lock.c:80
#2  0x00007fd76475f0dc in malloc_mutex_lock_final (mutex=0x7fd7647a04c0 
<init_lock>) at include/jemalloc/internal/mutex.h:141
#3  je_malloc_mutex_lock_slow (mutex=mutex@entry=0x7fd7647a04c0 <init_lock>) at 
src/mutex.c:84
#4  0x00007fd76470e244 in malloc_mutex_lock (mutex=0x7fd7647a04c0 <init_lock>, 
tsdn=0x0) at include/jemalloc/internal/mutex.h:205
#5  malloc_init_hard () at src/jemalloc.c:1506
#6  0x00007fd76471524d in malloc_init () at src/jemalloc.c:217
#7  imalloc (dopts=<synthetic pointer>, sopts=<synthetic pointer>) at 
src/jemalloc.c:1986
#8  calloc (num=num@entry=1, size=size@entry=32) at src/jemalloc.c:2138
#9  0x00007fd763ff8a25 in _dlerror_run (operate=operate@entry=0x7fd763ff8390 
<dlsym_doit>, args=args@entry=0x7ffdd14ddfa0) at dlerror.c:141
#10 0x00007fd763ff840f in __dlsym (handle=<optimized out>, name=<optimized 
out>) at dlsym.c:70
#11 0x00007fd7644f49b4 in ?? () from 
/usr/lib/x86_64-linux-gnu/fakechroot/libfakechroot.so
#12 0x00007fd7644edffc in dl_iterate_phdr () from 
/usr/lib/x86_64-linux-gnu/fakechroot/libfakechroot.so
#13 0x00007fd763ff02a1 in _Unwind_Find_FDE (pc=0x7fd763fee867 
<_Unwind_Backtrace+55>, bases=bases@entry=0x7ffdd14de368) at 
../../../src/libgcc/unwind-dw2-fde-dip.c:469
#14 0x00007fd763fec983 in uw_frame_state_for 
(context=context@entry=0x7ffdd14de2c0, fs=fs@entry=0x7ffdd14de110) at 
../../../src/libgcc/unwind-dw2.c:1257
#15 0x00007fd763fedb60 in uw_init_context_1 (context=0x7ffdd14de2c0, 
outer_cfa=0x7ffdd14de570, outer_ra=0x7fd76476a878 <je_prof_boot2+56>)
    at ../../../src/libgcc/unwind-dw2.c:1586
#16 0x00007fd763fee868 in _Unwind_Backtrace (trace=trace@entry=0x7fd76475fdb0 
<prof_unwind_init_callback>, trace_argument=trace_argument@entry=0x0)
    at ../../../src/libgcc/unwind.inc:295
#17 0x00007fd76476a878 in je_prof_boot2 (tsd=tsd@entry=0x7fd763fd7740) at 
src/prof.c:2392
#18 0x00007fd76470e308 in malloc_init_hard () at src/jemalloc.c:1538
#19 malloc_init_hard () at src/jemalloc.c:1500
#20 0x00007fd764710a85 in malloc_init () at src/jemalloc.c:217

I don't think it's a bug on either library per se. I was wondering if
you had any insight on how we could address this in fakechroot somehow
rather than in jemalloc, as that doesn't look to be easy without
disabling the profiling feature.

Regards,
Faidon

Reply via email to