| /* gcc -o dlopen-race dlopen-race.c -lpthread -ldl */ | |
| /* use "dlopen_test /lib/libwrap.so.0.7.6" */ | |
| /* dlopen_test.c */ | |
| /* Take from | |
| http://sources.redhat.com/bugzilla/show_bug.cgi?id=4578 | |
| and slightly modified. | |
| Added usleep() to trigger "Inconsistency detected by ld.so.." | |
| Error is encountered only in ~12% of the tries on Celeron M 440 with usleep(10). | |
| The error should not happen as fork() resets the locks | |
| http://www.eglibc.org/cgi-bin/viewvc.cgi/branches/eglibc-2_11/libc/nptl/sysdeps/unix/sysv/linux/fork.c?annotate=9235 line 164 | |
| Commit message: | |
| http://sourceware.org/git/?p=glibc.git;a=commit;f=nptl/sysdeps/unix/sysv/linux/fork.c;h=1d9d0b80d1412f8a272e0881d34538a041e56b4b | |
| */ | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <dlfcn.h> | |
| #include <pthread.h> | |
| #include <sys/types.h> | |
| #include <unistd.h> | |
| #include <sys/wait.h> | |
| #define NTHREAD 4 | |
| void * th_fn(void *arg) | |
| { | |
| char *dso_name = (char *)arg; | |
| void * handle = dlopen (dso_name, RTLD_NOW | RTLD_GLOBAL); | |
| if (handle == NULL) { | |
| fprintf(stderr, "Didn't open lib: %s: %s\n", | |
| dso_name, dlerror()); | |
| return (void *)-1; | |
| } | |
| dlclose(handle); | |
| return (void *)0; | |
| } | |
| int main(int argc, char *argv[]) | |
| { | |
| int i; | |
| char * dso_name; | |
| pthread_t child_th[NTHREAD]; | |
| if (argc == 1) { | |
| printf("dlopen_test DSO_TO_LOAD\n"); | |
| exit(-1); | |
| } | |
| dso_name = argv[1]; | |
| th_fn(dso_name); | |
| for (i = 0 ; i < NTHREAD ; i++) | |
| pthread_create(&child_th[i], NULL, th_fn, dso_name); | |
| /* try with and without a call to usleep() */ | |
| #if 1 | |
| /* | |
| adjust sleep time, if needed, to trigger | |
| Inconsistency detected by ld.so: dl-open.c: 221: dl_open_worker: Assertion `_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT' failed! | |
| */ | |
| usleep(10); | |
| #endif | |
| for (i = 0 ; i < NTHREAD ; i++) { | |
| if (fork() == 0) { | |
| th_fn(dso_name); | |
| exit(0); | |
| } | |
| } | |
| for (i = 0 ; i < NTHREAD ; i++) | |
| pthread_join(child_th[i], NULL); | |
| wait(NULL); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment