Created attachment 6112 [details] reproducer There is a shared library that calls pthread_atfork() (at least one handler must be NOT NULL) during initialization. There is an application that loads this shared library with dlopen() and then unloads it with dlclose(). Then the application calls fork(). Segfault occurs. It looks like atfork handlers registered with pthread_atfork() were not removed during dlclose(). The problem can be reproduced with the attached test. Compile libfoo.c - "gcc -c -fPIC -o libfoo.o libfoo.c" Create the shared library - "gcc -shared -o libfoo.so libfoo.o" Compile fork_main.c - "gcc -o fork_main fork_main.c -ldl -lpthread" Run ./fork_main.
This problem cannot be solved without introducing new API. Problem here is lack of function that removes fork handler.
Moreover, there's nothing safe that can be done from pthread_atfork handlers anyway; the whole concept of pthread_atfork was a mistake, and this is largely acknowledged in the Rationale section for pthread_atfork in POSIX.
(In reply to Ondrej Bilka from comment #1) > This problem cannot be solved without introducing new API. > > Problem here is lack of function that removes fork handler. The removal of the handlers could be done automatically when the DSO is unloaded. Each dso has a unique __dso_handle inserted by the compiler which is used when registering the handlers via pthread_atfork. When the DSO is unloaded we could look through the registered handlers and remove those that belong to the DSO being unloaded. The only other robust alternatives are: * mark the DSOs as unloadable e.g. -z nodelete. * don't use pthread_atfork
The way this is expected to work is via the libc_nonshared.a version of pthread_atfork, which provides the caller's identity through the __dso_handle argument. (Previously, pthread_atfork wa in libpthread_nonshared.a.) This has been fixed since the bug was reported, maybe as a result of commit 825adeeed1e95990fd1efb70d9ac3eb7f1ea802a ("Mark __dso_handle as hidden [BZ #18822]"). Note that if you declare pthread_atfork on your own, as a weak symbol, you will get the compat symbol from libpthread at run time, which cannot arrange for unregistration. libcap-ng does that, and it needs to be fixed.