bug-glibc
[Top][All Lists]
Advanced

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

glibc dynamic symbol lookup crash


From: Dan Winship
Subject: glibc dynamic symbol lookup crash
Date: 19 Jun 2003 14:30:02 -0400

Dynamic symbol resolution in glibc seems to be not threadsafe with
respect to dynamic loading. The attached program segfaults 100% reliably
for me. (RedHat 9, glibc-2.3.2-27.9). It generally manages to open 20-30
libraries before crashing with:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1082383664 (LWP 1887)]
0x4000930e in do_lookup () from /lib/ld-linux.so.2
(gdb) where
#0  0x4000930e in do_lookup () from /lib/ld-linux.so.2
#1  0x40008073 in _dl_lookup_symbol_internal () from /lib/ld-linux.so.2
#2  0x42110c8c in _dl_sym () from /lib/tls/libc.so.6
#3  0x4002b108 in dlsym_doit () from /lib/libdl.so.2
#4  0x4000c816 in _dl_catch_error_internal () from /lib/ld-linux.so.2
#5  0x4002b416 in _dlerror_run () from /lib/libdl.so.2
#6  0x4002b0c4 in dlsym () from /lib/libdl.so.2
#7  0x08048523 in lookup_thread ()
#8  0x40032332 in start_thread () from /lib/tls/libpthread.so.0
(gdb)

This is a pathological test case for a problem that has started showing
up more and more frequently in Evolution; as various components are
dlopened at startup, a poorly-timed symbol resolution will cause a
random unreproducible crash. And it doesn't have to be an explicit
dlsym() call; the crashes we've had are all in _dl_runtime_resolve().

Many samples are linked from
http://bugzilla.ximian.com/show_bug.cgi?id=43160, although some of the
alleged-duplicates turn out to be unrelated problems.

-- Dan
#include <pthread.h>
#include <dlfcn.h>
#include <dirent.h>

void *
lookup_thread (void *handle)
{
        while (1)
                dlsym (handle, "main");

        return NULL;
}

int
main (int argc, char **argv)
{
        pthread_t loader;
        DIR *d;
        struct dirent *dent;
        char *so;

        pthread_create (&loader, NULL, lookup_thread, dlopen (NULL, RTLD_NOW));

        d = opendir ("/usr/lib");
        while ((dent = readdir (d))) {
                so = strstr (dent->d_name, ".so");
                if (!so || so[3])
                        continue;

                printf ("%s\n", dent->d_name);
                dlopen (dent->d_name, RTLD_NOW | RTLD_GLOBAL);
        }

        printf ("Oh well. Worse luck next time!\n");
        return 0;
}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]