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