aboutsummaryrefslogtreecommitdiff
path: root/stdlib/Makefile
diff options
context:
space:
mode:
authorPaul Pluzhnikov <ppluzhnikov@google.com>2017-09-21 12:14:41 -0700
committerPaul Pluzhnikov <ppluzhnikov@google.com>2017-09-21 12:14:41 -0700
commite5e4d7cc056ffae51fc55b66d9dd0abd99927486 (patch)
tree2290540b926efebc5936d984a773688247a5f736 /stdlib/Makefile
parentc10c5267a8c95ffea1fad70e2bf047c1dd3dfd48 (diff)
downloadglibc-e5e4d7cc056ffae51fc55b66d9dd0abd99927486.zip
glibc-e5e4d7cc056ffae51fc55b66d9dd0abd99927486.tar.gz
glibc-e5e4d7cc056ffae51fc55b66d9dd0abd99927486.tar.bz2
Fix BZ# 22180.
POSIX requires that dlclose() and exit() be thread safe, therefore you can have one thread in the middle of dlclose() and another thread executing exit() without causing any undefined behaviour on the part of the implementation. The existing implementation had a flaw that exit() exit handler processing did not consider a concurrent dlclose() and would not mark already run exit handlers using the ef_free flavour. The consequence of this is that a concurrent exit() with dlclose() will run all the exit handlers that dlclose() had not yet run, but then will block on the loader lock. The concurrent dlclose() will continue to run all the exit handlers again (twice) in violation of the Itanium C++ ABI requirements for __cxa_atexit(). This commit fixes this by having exit() mark all handlers with ef_free to ensure that concurrent dlclose() won't re-run registered exit handlers that have already run.
Diffstat (limited to 'stdlib/Makefile')
-rw-r--r--stdlib/Makefile10
1 files changed, 8 insertions, 2 deletions
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 2fb0834..0a51b7b 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -83,7 +83,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
tst-getrandom tst-atexit tst-at_quick_exit \
tst-cxa_atexit tst-on_exit test-atexit-race \
test-at_quick_exit-race test-cxa_atexit-race \
- test-on_exit-race
+ test-on_exit-race test-dlclose-exit-race
tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
tst-tls-atexit tst-tls-atexit-nodelete
@@ -98,6 +98,10 @@ LDLIBS-test-at_quick_exit-race = $(shared-thread-library)
LDLIBS-test-cxa_atexit-race = $(shared-thread-library)
LDLIBS-test-on_exit-race = $(shared-thread-library)
+LDLIBS-test-dlclose-exit-race = $(shared-thread-library) $(libdl)
+LDFLAGS-test-dlclose-exit-race = $(LDFLAGS-rdynamic)
+LDLIBS-test-dlclose-exit-race-helper.so = $(libsupport) $(shared-thread-library)
+
ifeq ($(have-cxx-thread_local),yes)
CFLAGS-tst-quick_exit.o = -std=c++11
LDLIBS-tst-quick_exit = -lstdc++
@@ -108,7 +112,7 @@ else
tests-unsupported += tst-quick_exit tst-thread-quick_exit
endif
-modules-names = tst-tls-atexit-lib
+modules-names = tst-tls-atexit-lib test-dlclose-exit-race-helper
extra-test-objs += $(addsuffix .os, $(modules-names))
ifeq ($(build-shared),yes)
@@ -177,6 +181,7 @@ $(objpfx)tst-strtod-nan-locale.out: $(gen-locales)
$(objpfx)tst-strfmon_l.out: $(gen-locales)
$(objpfx)tst-strfrom.out: $(gen-locales)
$(objpfx)tst-strfrom-locale.out: $(gen-locales)
+$(objpfx)test-dlclose-exit-race.out: $(objpfx)test-dlclose-exit-race-helper.so
endif
# Testdir has to be named stdlib and needs to be writable
@@ -215,6 +220,7 @@ $(objpfx)tst-strtod6: $(libm)
$(objpfx)tst-strtod-nan-locale: $(libm)
tst-tls-atexit-lib.so-no-z-defs = yes
+test-dlclose-exit-race-helper.so-no-z-defs = yes
$(objpfx)tst-tls-atexit: $(shared-thread-library) $(libdl)
$(objpfx)tst-tls-atexit.out: $(objpfx)tst-tls-atexit-lib.so