I made a small program reproducing the problem, also with a base system library. I randomly chose /usr/lib/libtermcap.so as default, but I think everything that turns up by grep _fini /usr/lib/*.so will do. Actual output: $ ./dl main thread 0x706e490a2800: calling exit() main thread 0x706e490a2800: telling thread to exit main thread 0x706e490a2800: calling pthread_join() worker thread 0x706e4909f000: calling dlclose() (deadlock) Expected output: $ ./dl main thread 0x706d25e35800: calling exit() main thread 0x706d25e35800: telling thread to exit main thread 0x706d25e35800: calling pthread_join() worker thread 0x706d25e32000: calling dlclose() worker thread 0x706d25e32000: dlclose() returned worker thread 0x706d25e32000: exiting main thread 0x706d25e35800: pthread_join() returned $ dl.c: (compile with "sh dl.c") ----------><>---cut here---<><------ # /* cc dl.c -o dl -pthread -ggdb exit $? */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <dlfcn.h> void *library_handle; pthread_t worker_thread = 0; int worker_thread_should_exit = 0; void cleanup_from_main_thread() { printf("main thread %p: telling thread to exit\n", pthread_self()); worker_thread_should_exit = 1; printf("main thread %p: calling pthread_join()\n", pthread_self()); pthread_join(worker_thread, NULL); printf("main thread %p: pthread_join() returned\n", pthread_self()); } void *worker_thread_main(void *arg) { /* Do useful work */ while (!worker_thread_should_exit) { sleep(1); } printf("worker thread %p: calling dlclose()\n", pthread_self()); dlclose(library_handle); printf("worker thread %p: dlclose() returned\n", pthread_self()); printf("worker thread %p: exiting\n", pthread_self()); pthread_exit(NULL); } int main(int argc, char **argv) { char *library = "/usr/lib/libtermcap.so"; if (argc > 1) { library = argv[1]; } library_handle = dlopen(library, RTLD_LAZY|RTLD_LOCAL); pthread_create(&worker_thread, NULL, worker_thread_main, NULL); atexit(cleanup_from_main_thread); /* Do useful work */ sleep(1); printf("main thread %p: calling exit()\n", pthread_self()); exit(0); } ----------><>---cut here---<><------ -Olaf. -- Olaf 'Rhialto' Seibert -- rhialto at falu dot nl ___ Anyone who is capable of getting themselves made President should on \X/ no account be allowed to do the job. --Douglas Adams, "THGTTG"
Attachment:
signature.asc
Description: PGP signature