Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: atexit(), dlclose() and more atexit() (with reproducer)



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



Home | Main Index | Thread Index | Old Index