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