https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83074
--- Comment #6 from Stefan Vargyas <stvar at yahoo dot com> --- > > Don't use --export-dynamic. This causes __libc_csu_{init,fini} to be shared > between the objects instead of having a private copy in each object. > Thank you very much Andreas for your deep inside knowledge! Indeed, as I'll show below, '__libc_csu_{init,fini}' are the culprits for 'foo.so' blocking at exit after being loaded in by 'bar': (1) Build 'foo.so' exactly as before: $ make allclean $ make GCC=gcc-7.2.0 COVERAGE=yes foo.so (2) The ELF file obtained has its dynamic symbol table containing '__libc_csu_{init,fini}', with both symbols having their binding set to 'STB_GLOBAL' and visibility to 'STV_DEFAULT': $ readelf --dyn-syms foo.so|grep -E 'libc_csu_(init|fini)' 46: 0000000000003540 137 FUNC GLOBAL DEFAULT 14 __libc_csu_init 49: 0000000000003530 2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini (3) Do some manual patching of the ELF file for to set binding to 'STB_LOCAL' and visibility to 'STV_HIDDEN': $ ghex2 foo.so $ readelf --dyn-syms foo.so|grep -E 'libc_csu_(init|fini)' 46: 0000000000003540 137 FUNC LOCAL HIDDEN 14 __libc_csu_init 49: 0000000000003530 2 FUNC LOCAL HIDDEN 14 __libc_csu_fini Note that I couldn't avoid manually patching 'foo.so' since none of the linker options seems to be able to help (neither `--dynamic-list' nor `--version-script'). Couldn't find help using 'objcopy' either: this tool doesn't want to touch the dynamic symbol table at all! (4) Now build 'bar' using the patched 'foo.so': $ make GCC=gcc-7.2.0 COVERAGE=yes bar (5) Both 'foo.so' and 'bar' work nicely (not hanging anymore): $ ./foo.so foo.so: version: 0.1 $ ./bar bar: foo.so: version: 0.1 Only one final remark: `-pie' without `--export-dynamic' still causes '__libc_csu_{init,fini}' to be added to the dynamic symbol table: $ gcc-7.2.0 -I. -fPIC -fvisibility=hidden -c foo.c -o foo.o $ gcc-7.2.0 -Wl,-L. -pie foo.o -o foo.so $ readelf --dyn-syms foo.so|grep -P 'libc_csu_(init|fini)' 40: 00000000000033f0 137 FUNC GLOBAL DEFAULT 14 __libc_csu_init 42: 00000000000033e0 2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini