[gnutls-devel] Deconstructor deadlock

Ludovic Courtès ludo at gnu.org
Wed Jul 27 22:32:06 CEST 2016


Hello,

Loading libgnutls.so can fail, as in this case (output of ld.so with
LD_DEBUG=files):

--8<---------------cut here---------------start------------->8---
      4478:	calling init: /gnu/store/vy5yzixfp3lz587rp52qdynisrnqgmiy-profile/lib/libnettle.so.6
      4478:	
      4478:	
      4478:	calling init: /gnu/store/vy5yzixfp3lz587rp52qdynisrnqgmiy-profile/lib/libhogweed.so.4
      4478:	
      4478:	
      4478:	calling init: /gnu/store/r9swffa651bgq4cvjgh81h6aqqzgwkjf-libtasn1-4.7/lib/libtasn1.so.6
      4478:	
      4478:	
      4478:	calling init: /gnu/store/pnax3d98xn5j7phj577v6sk9p9kfcs6m-libidn-1.32/lib/libidn.so.11
      4478:	
      4478:	
      4478:	calling init: /gnu/store/vy5yzixfp3lz587rp52qdynisrnqgmiy-profile/lib/libz.so.1
      4478:	
      4478:	
      4478:	calling init: /home/ludo/src/gnutls/+build/lib/.libs/libgnutls.so.30
      4478:	
      4478:	/home/ludo/src/gnutls/+build/lib/.libs/libgnutls.so.30: error: symbol lookup error: undefined symbol: getrandom (fatal)
      4478:	
      4478:	calling fini: /home/ludo/src/gnutls/+build/lib/.libs/libgnutls.so.30 [0]
--8<---------------cut here---------------end--------------->8---

However, at this stage, the program that loads libgnutls never returns
because the library’s destructor is stuck trying to acquire
‘global_init_mutex’:

--8<---------------cut here---------------start------------->8---
(gdb) bt
#0  0x00007f4b339edd1c in __lll_lock_wait () from target:/gnu/store/8m00x5x8ykmar27s9248cmhnkdb2n54a-glibc-2.22/lib/libpthread.so.0
#1  0x00007f4b339e7b15 in pthread_mutex_lock () from target:/gnu/store/8m00x5x8ykmar27s9248cmhnkdb2n54a-glibc-2.22/lib/libpthread.so.0
#2  0x00007f4b302938dd in _gnutls_global_deinit (destructor=<optimized out>) at ../../lib/global.c:388
#3  0x00007f4b3420e167 in _dl_close_worker () from target:/gnu/store/8m00x5x8ykmar27s9248cmhnkdb2n54a-glibc-2.22/lib/ld-linux-x86-64.so.2
#4  0x00007f4b3420ce40 in _dl_open () from target:/gnu/store/8m00x5x8ykmar27s9248cmhnkdb2n54a-glibc-2.22/lib/ld-linux-x86-64.so.2
#5  0x00007f4b32dc7fb9 in dlopen_doit () from target:/gnu/store/8m00x5x8ykmar27s9248cmhnkdb2n54a-glibc-2.22/lib/libdl.so.2
#6  0x00007f4b34208f34 in _dl_catch_error () from target:/gnu/store/8m00x5x8ykmar27s9248cmhnkdb2n54a-glibc-2.22/lib/ld-linux-x86-64.so.2
#7  0x00007f4b32dc8589 in _dlerror_run () from target:/gnu/store/8m00x5x8ykmar27s9248cmhnkdb2n54a-glibc-2.22/lib/libdl.so.2
#8  0x00007f4b32dc8051 in dlopen@@GLIBC_2.2.5 () from target:/gnu/store/8m00x5x8ykmar27s9248cmhnkdb2n54a-glibc-2.22/lib/libdl.so.2
--8<---------------cut here---------------end--------------->8---

This happens due to lazy loading in ld.so under which the symbol lookup
error can happen in the middle of ‘gnutls_global_init’, and thus trigger
the call to ‘_gnutls_global_deinit’ while ‘global_init_mutex’ is still
held.

Using LD_BIND_NOW=yes works around the problem: we get the error right
away, instead of having a program that never returns.

Ludo’.



More information about the Gnutls-devel mailing list