diff options
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/Makefile | 10 | ||||
-rw-r--r-- | nptl/tst-join7.c | 46 | ||||
-rw-r--r-- | nptl/tst-join7mod.c | 61 |
3 files changed, 115 insertions, 2 deletions
diff --git a/nptl/Makefile b/nptl/Makefile index 140f06318f..aaca0a4700 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -245,7 +245,7 @@ tests = tst-typesizes \ tst-basic7 \ tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \ tst-raise1 \ - tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 tst-join6 \ + tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 tst-join6 tst-join7 \ tst-detach1 \ tst-eintr1 tst-eintr2 tst-eintr3 tst-eintr4 tst-eintr5 \ tst-tsd1 tst-tsd2 tst-tsd3 tst-tsd4 tst-tsd5 tst-tsd6 \ @@ -327,7 +327,8 @@ endif modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \ tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \ tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \ - tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod + tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \ + tst-join7mod extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) tst-cleanup4aux.o test-extras += $(modules-names) tst-cleanup4aux test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names))) @@ -532,6 +533,11 @@ $(objpfx)tst-tls6.out: tst-tls6.sh $(objpfx)tst-tls5 \ $(evaluate-test) endif +$(objpfx)tst-join7: $(libdl) $(shared-thread-library) +$(objpfx)tst-join7.out: $(objpfx)tst-join7mod.so +$(objpfx)tst-join7mod.so: $(shared-thread-library) +LDFLAGS-tst-join7mod.so = -Wl,-soname,tst-join7mod.so + $(objpfx)tst-dlsym1: $(libdl) $(shared-thread-library) $(objpfx)tst-fini1: $(shared-thread-library) $(objpfx)tst-fini1mod.so diff --git a/nptl/tst-join7.c b/nptl/tst-join7.c new file mode 100644 index 0000000000..439d0fc9bb --- /dev/null +++ b/nptl/tst-join7.c @@ -0,0 +1,46 @@ +/* Verify that TLS access in separate thread in a dlopened library does not + deadlock. + Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dlfcn.h> + +/* When one dynamically loads a module, which spawns a thread to perform some + activities, it could be possible that TLS storage is accessed for the first + time in that thread. This results in an allocation request within the + thread, which could result in an attempt to take the rtld load_lock. This + is a problem because it would then deadlock with the dlopen (which owns the + lock), if the main thread is waiting for the spawned thread to exit. We can + at least ensure that this problem does not occur due to accesses within + libc.so, by marking TLS variables within libc.so as IE. The problem of an + arbitrary variable being accessed and constructed within such a thread still + exists but this test case does not verify that. */ + +int +do_test (void) +{ + void *f = dlopen ("tst-join7mod.so", RTLD_NOW | RTLD_GLOBAL); + if (f) + dlclose (f); + else + return 1; + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/nptl/tst-join7mod.c b/nptl/tst-join7mod.c new file mode 100644 index 0000000000..92bb381705 --- /dev/null +++ b/nptl/tst-join7mod.c @@ -0,0 +1,61 @@ +/* Verify that TLS access in separate thread in a dlopened library does not + deadlock - the module. + Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <pthread.h> +#include <atomic.h> + +static pthread_t th; +static int running = 1; + +static void * +test_run (void *p) +{ + while (atomic_load_relaxed (&running)) + printf ("Test running\n"); + printf ("Test finished\n"); + return NULL; +} + +static void __attribute__ ((constructor)) +do_init (void) +{ + int ret = pthread_create (&th, NULL, test_run, NULL); + + if (ret != 0) + { + printf ("failed to create thread: %s (%d)\n", strerror (ret), ret); + exit (1); + } +} + +static void __attribute__ ((destructor)) +do_end (void) +{ + atomic_store_relaxed (&running, 0); + int ret = pthread_join (th, NULL); + + if (ret != 0) + { + printf ("pthread_join: %s(%d)\n", strerror (ret), ret); + exit (1); + } + + printf ("Thread joined\n"); +} |