Skip to content

Commit 2a566fa

Browse files
authored
Merge pull request #121 from mplegendre/bugfix/locale_thrd_fix
Fixes for glibc bug around locale and TLS crashes
2 parents 4e46998 + 01a94da commit 2a566fa

27 files changed

+654
-31
lines changed

config.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@
8585
*/
8686
#undef LT_OBJDIR
8787

88+
/* Defined if GLIBC has locale TLS bug */
89+
#undef NEWTHREAD_LOCALE_BUG
90+
8891
/* Exclusions for numa optimization */
8992
#undef NUMA_EXCLUDES
9093

configure

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16747,7 +16747,7 @@ fi
1674716747

1674816748
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for glibc dtv allocation bug" >&5
1674916749
$as_echo_n "checking for glibc dtv allocation bug... " >&6; }
16750-
if test "x`${SPINDLE_SOURCE_ROOT}/scripts/dtvtest/run_dtvtest.sh ${SPINDLE_SOURCE_ROOT}/scripts/dtvtest ${SPINDLE_BUILD_ROOT}/dtvtest '$CC' '$CFLAGS'`" == "x0"; then
16750+
if ${SPINDLE_SOURCE_ROOT}/scripts/dtvtest/run_dtvtest.sh ${SPINDLE_SOURCE_ROOT}/scripts/dtvtest ${SPINDLE_BUILD_ROOT}/dtvtest '$CC' '$CFLAGS'; then
1675116751
DTV_ALLOC_BUG=0
1675216752
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
1675316753
$as_echo "no" >&6; }
@@ -16762,6 +16762,24 @@ cat >>confdefs.h <<_ACEOF
1676216762
_ACEOF
1676316763

1676416764

16765+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for locale tls fault glibc bug" >&5
16766+
$as_echo_n "checking for locale tls fault glibc bug... " >&6; }
16767+
if ${SPINDLE_SOURCE_ROOT}/scripts/locale_tls_fault/tls_locale_fault.sh ${SPINDLE_SOURCE_ROOT}/scripts/locale_tls_fault ${SPINDLE_BUILD_ROOT}/locale_tls_fault $CC; then
16768+
LOCALE_FAULT_BUG=0
16769+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
16770+
$as_echo "no" >&6; }
16771+
else
16772+
LOCALE_FAULT_BUG=1
16773+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
16774+
$as_echo "yes" >&6; }
16775+
fi
16776+
16777+
cat >>confdefs.h <<_ACEOF
16778+
#define NEWTHREAD_LOCALE_BUG $LOCALE_FAULT_BUG
16779+
_ACEOF
16780+
16781+
16782+
1676516783
#OS Detection
1676616784
# Check whether --enable-bluegene was given.
1676716785
if test "${enable_bluegene+set}" = set; then :

configure.common.ac

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ fi
8787
AM_CONDITIONAL([BLD_FLUXPLUGIN], [test "x$ENABLE_FLUX_PLUGIN" = "xtrue"])
8888

8989
AC_MSG_CHECKING([for glibc dtv allocation bug])
90-
if test "x`${SPINDLE_SOURCE_ROOT}/scripts/dtvtest/run_dtvtest.sh ${SPINDLE_SOURCE_ROOT}/scripts/dtvtest ${SPINDLE_BUILD_ROOT}/dtvtest '$CC' '$CFLAGS'`" == "x0"; then
90+
if ${SPINDLE_SOURCE_ROOT}/scripts/dtvtest/run_dtvtest.sh ${SPINDLE_SOURCE_ROOT}/scripts/dtvtest ${SPINDLE_BUILD_ROOT}/dtvtest '$CC' '$CFLAGS'; then
9191
DTV_ALLOC_BUG=0
9292
AC_MSG_RESULT([no])
9393
else
@@ -96,6 +96,17 @@ else
9696
fi
9797
AC_DEFINE_UNQUOTED([DTV_ALLOCATION_BUG],[$DTV_ALLOC_BUG],[Defined if GLIBC has an allocation bug])
9898

99+
AC_MSG_CHECKING([for locale tls fault glibc bug])
100+
if ${SPINDLE_SOURCE_ROOT}/scripts/locale_tls_fault/tls_locale_fault.sh ${SPINDLE_SOURCE_ROOT}/scripts/locale_tls_fault ${SPINDLE_BUILD_ROOT}/locale_tls_fault $CC; then
101+
LOCALE_FAULT_BUG=0
102+
AC_MSG_RESULT([no])
103+
else
104+
LOCALE_FAULT_BUG=1
105+
AC_MSG_RESULT([yes])
106+
fi
107+
AC_DEFINE_UNQUOTED([NEWTHREAD_LOCALE_BUG],[$LOCALE_FAULT_BUG],[Defined if GLIBC has locale TLS bug])
108+
109+
99110
#OS Detection
100111
AC_ARG_ENABLE(bluegene,
101112
[AS_HELP_STRING([--enable-bluegene],[Build Spindle for BlueGene/Q])],

scripts/dtvtest/Makefile

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
DEP_NUMS = 01 02 03 04 05 06 07 08 09 10 11 12 13
2-
DLOPEN_NUMS = 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
1+
DEP_NUMS = 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
2+
DLOPEN_NUMS = 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
33

44
DEP_LIBS = $(DEP_NUMS:%=libdeptls%.so)
55
DEP_LINKS = $(DEP_NUMS:%=-ldeptls%)
@@ -23,9 +23,8 @@ libminaudit.so: $(SRCDIR)/minaudit.c
2323
gcc -shared -fPIC -o $@ $<
2424

2525
dtvtest: $(SRCDIR)/dtvtest.c $(DEP_LIBS)
26-
gcc -o $@ $(SRCDIR)/dtvtest.c -ldl -lpthread -g -Wl,-rpath,`pwd` -L`pwd` $(DEP_LINKS)
26+
gcc -o $@ $(SRCDIR)/dtvtest.c -ldl -lpthread -g -Wl,-rpath,`pwd` -L`pwd` -Wl,--no-as-needed -Wl,--disable-new-dtags $(DEP_LINKS)
2727

2828
run: dtvtest libminaudit.so $(DLOPEN_LIBS)
29-
echo LD_AUDIT=./libminaudit.so ./dtvtest $(DLOPEN_NUMS)
3029
LD_AUDIT=./libminaudit.so ./dtvtest $(DLOPEN_NUMS)
31-
echo $?
30+
@echo $$?

scripts/locale_tls_fault/app.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include <pthread.h>
2+
#include <stdio.h>
3+
#include <dlfcn.h>
4+
#include <stdlib.h>
5+
#include <signal.h>
6+
7+
void onsig(int sig)
8+
{
9+
exit(-1);
10+
}
11+
12+
void *thrdrun(void *arg)
13+
{
14+
void *result;
15+
16+
//Any audit-triggering operation will do
17+
result = dlopen("libm.so.6", RTLD_NOW);
18+
if (!result) {
19+
return NULL;
20+
}
21+
22+
return NULL;
23+
}
24+
25+
int main(int argc, char *argv[])
26+
{
27+
pthread_t thrd;
28+
int result;
29+
30+
signal(SIGSEGV, onsig);
31+
32+
result = pthread_create(&thrd, NULL, thrdrun, NULL);
33+
if (result != 0) {
34+
return -1;
35+
}
36+
37+
pthread_join(thrd, NULL);
38+
return 0;
39+
}

scripts/locale_tls_fault/auditor.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#define _GNU_SOURCE
2+
#include <link.h>
3+
#include <stdio.h>
4+
#include <string.h>
5+
6+
extern int isspace(int c);
7+
8+
unsigned int la_version(unsigned int v)
9+
{
10+
return LAV_CURRENT;
11+
}
12+
13+
unsigned int la_objopen(struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
14+
{
15+
//Need something that accesses TLS through R_X86_64_TPOFF64, which
16+
//isspace does by getting the locale
17+
int result;
18+
if (strstr(map->l_name, "libm.so")) {
19+
result = isspace(' ');
20+
}
21+
return 0;
22+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/sh
2+
3+
TEST_SRCDIR=$1
4+
TEST_BUILDDIR=$2
5+
COMPILE=$3
6+
7+
mkdir -p $TEST_BUILDDIR
8+
$COMPILE -o $TEST_BUILDDIR/localeapp $TEST_SRCDIR/app.c -ldl -lpthread
9+
$COMPILE -shared -fPIC -o $TEST_BUILDDIR/liblocaleaudit.so $TEST_SRCDIR/auditor.c
10+
LD_AUDIT=$TEST_BUILDDIR/liblocaleaudit.so $TEST_BUILDDIR/localeapp
11+

src/client/auditclient/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ AM_CFLAGS = -fvisibility=hidden
1414

1515
AM_CPPFLAGS = -I$(top_srcdir)/../logging -I$(top_srcdir)/../include -I$(top_srcdir)/client -I$(top_srcdir)/client_comlib
1616

17-
BASE_SRCS = auditclient.c auditclient_common.c patch_linkmap.c redirect.c bindgot.c writablegot.c patch_bad_dtv.c
17+
BASE_SRCS = auditclient.c auditclient_common.c patch_linkmap.c redirect.c bindgot.c writablegot.c patch_bad_dtv.c malloc_wrapper.c fixlocale.c
1818
if X86_64_BLD
1919
ARCH_SRCS = auditclient_x86_64.c
2020
endif

src/client/auditclient/Makefile.in

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,11 @@ libspindle_audit_biter_la_DEPENDENCIES = \
143143
$(top_builddir)/client/libspindlec_biter.la $(AUDITLIB)
144144
am__libspindle_audit_biter_la_SOURCES_DIST = auditclient.c \
145145
auditclient_common.c patch_linkmap.c redirect.c bindgot.c \
146-
writablegot.c patch_bad_dtv.c auditclient_aarch64.c \
147-
auditclient_ppc64.c auditclient_x86_64.c
146+
writablegot.c patch_bad_dtv.c malloc_wrapper.c fixlocale.c \
147+
auditclient_aarch64.c auditclient_ppc64.c auditclient_x86_64.c
148148
am__objects_1 = auditclient.lo auditclient_common.lo patch_linkmap.lo \
149-
redirect.lo bindgot.lo writablegot.lo patch_bad_dtv.lo
149+
redirect.lo bindgot.lo writablegot.lo patch_bad_dtv.lo \
150+
malloc_wrapper.lo fixlocale.lo
150151
@AARCH64_BLD_FALSE@@PPC64LE_BLD_FALSE@@PPC64_BLD_FALSE@@X86_64_BLD_TRUE@am__objects_2 = auditclient_x86_64.lo
151152
@AARCH64_BLD_FALSE@@PPC64LE_BLD_FALSE@@PPC64_BLD_TRUE@am__objects_2 = auditclient_ppc64.lo
152153
@AARCH64_BLD_FALSE@@PPC64LE_BLD_TRUE@am__objects_2 = \
@@ -169,8 +170,8 @@ libspindle_audit_pipe_la_DEPENDENCIES = \
169170
$(top_builddir)/client/libspindlec_pipe.la $(AUDITLIB)
170171
am__libspindle_audit_pipe_la_SOURCES_DIST = auditclient.c \
171172
auditclient_common.c patch_linkmap.c redirect.c bindgot.c \
172-
writablegot.c patch_bad_dtv.c auditclient_aarch64.c \
173-
auditclient_ppc64.c auditclient_x86_64.c
173+
writablegot.c patch_bad_dtv.c malloc_wrapper.c fixlocale.c \
174+
auditclient_aarch64.c auditclient_ppc64.c auditclient_x86_64.c
174175
am_libspindle_audit_pipe_la_OBJECTS = $(am__objects_1) \
175176
$(am__objects_2)
176177
libspindle_audit_pipe_la_OBJECTS = \
@@ -184,8 +185,8 @@ libspindle_audit_socket_la_DEPENDENCIES = \
184185
$(top_builddir)/client/libspindlec_socket.la $(AUDITLIB)
185186
am__libspindle_audit_socket_la_SOURCES_DIST = auditclient.c \
186187
auditclient_common.c patch_linkmap.c redirect.c bindgot.c \
187-
writablegot.c patch_bad_dtv.c auditclient_aarch64.c \
188-
auditclient_ppc64.c auditclient_x86_64.c
188+
writablegot.c patch_bad_dtv.c malloc_wrapper.c fixlocale.c \
189+
auditclient_aarch64.c auditclient_ppc64.c auditclient_x86_64.c
189190
am_libspindle_audit_socket_la_OBJECTS = $(am__objects_1) \
190191
$(am__objects_2)
191192
libspindle_audit_socket_la_OBJECTS = \
@@ -216,6 +217,7 @@ am__depfiles_remade = ./$(DEPDIR)/auditclient.Plo \
216217
./$(DEPDIR)/auditclient_common.Plo \
217218
./$(DEPDIR)/auditclient_ppc64.Plo \
218219
./$(DEPDIR)/auditclient_x86_64.Plo ./$(DEPDIR)/bindgot.Plo \
220+
./$(DEPDIR)/fixlocale.Plo ./$(DEPDIR)/malloc_wrapper.Plo \
219221
./$(DEPDIR)/patch_bad_dtv.Plo ./$(DEPDIR)/patch_linkmap.Plo \
220222
./$(DEPDIR)/redirect.Plo ./$(DEPDIR)/writablegot.Plo
221223
am__mv = mv -f
@@ -407,7 +409,7 @@ top_srcdir = @top_srcdir@
407409
pkglib_LTLIBRARIES = $(am__append_1) $(am__append_2) $(am__append_3)
408410
AM_CFLAGS = -fvisibility=hidden
409411
AM_CPPFLAGS = -I$(top_srcdir)/../logging -I$(top_srcdir)/../include -I$(top_srcdir)/client -I$(top_srcdir)/client_comlib
410-
BASE_SRCS = auditclient.c auditclient_common.c patch_linkmap.c redirect.c bindgot.c writablegot.c patch_bad_dtv.c
412+
BASE_SRCS = auditclient.c auditclient_common.c patch_linkmap.c redirect.c bindgot.c writablegot.c patch_bad_dtv.c malloc_wrapper.c fixlocale.c
411413
@AARCH64_BLD_TRUE@ARCH_SRCS = auditclient_aarch64.c
412414
@PPC64LE_BLD_TRUE@ARCH_SRCS = auditclient_ppc64.c
413415
@PPC64_BLD_TRUE@ARCH_SRCS = auditclient_ppc64.c
@@ -512,6 +514,8 @@ distclean-compile:
512514
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditclient_ppc64.Plo@am__quote@ # am--include-marker
513515
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditclient_x86_64.Plo@am__quote@ # am--include-marker
514516
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bindgot.Plo@am__quote@ # am--include-marker
517+
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixlocale.Plo@am__quote@ # am--include-marker
518+
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc_wrapper.Plo@am__quote@ # am--include-marker
515519
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patch_bad_dtv.Plo@am__quote@ # am--include-marker
516520
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patch_linkmap.Plo@am__quote@ # am--include-marker
517521
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/redirect.Plo@am__quote@ # am--include-marker
@@ -687,6 +691,8 @@ distclean: distclean-am
687691
-rm -f ./$(DEPDIR)/auditclient_ppc64.Plo
688692
-rm -f ./$(DEPDIR)/auditclient_x86_64.Plo
689693
-rm -f ./$(DEPDIR)/bindgot.Plo
694+
-rm -f ./$(DEPDIR)/fixlocale.Plo
695+
-rm -f ./$(DEPDIR)/malloc_wrapper.Plo
690696
-rm -f ./$(DEPDIR)/patch_bad_dtv.Plo
691697
-rm -f ./$(DEPDIR)/patch_linkmap.Plo
692698
-rm -f ./$(DEPDIR)/redirect.Plo
@@ -742,6 +748,8 @@ maintainer-clean: maintainer-clean-am
742748
-rm -f ./$(DEPDIR)/auditclient_ppc64.Plo
743749
-rm -f ./$(DEPDIR)/auditclient_x86_64.Plo
744750
-rm -f ./$(DEPDIR)/bindgot.Plo
751+
-rm -f ./$(DEPDIR)/fixlocale.Plo
752+
-rm -f ./$(DEPDIR)/malloc_wrapper.Plo
745753
-rm -f ./$(DEPDIR)/patch_bad_dtv.Plo
746754
-rm -f ./$(DEPDIR)/patch_linkmap.Plo
747755
-rm -f ./$(DEPDIR)/redirect.Plo

src/client/auditclient/fixlocale.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
This file is part of Spindle. For copyright information see the COPYRIGHT
3+
file in the top level directory, or at
4+
https://github.com/hpc/Spindle/blob/master/COPYRIGHT
5+
6+
This program is free software; you can redistribute it and/or modify it under
7+
the terms of the GNU Lesser General Public License (as published by the Free Software
8+
Foundation) version 2.1 dated February 1999. This program is distributed in the
9+
hope that it will be useful, but WITHOUT ANY WARRANTY; without even the IMPLIED
10+
WARRANTY OF MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms
11+
and conditions of the GNU Lesser General Public License for more details. You should
12+
have received a copy of the GNU Lesser General Public License along with this
13+
program; if not, write to the Free Software Foundation, Inc., 59 Temple
14+
Place, Suite 330, Boston, MA 02111-1307 USA
15+
*/
16+
17+
#include <locale.h>
18+
#include <unistd.h>
19+
20+
#include "spindle_debug.h"
21+
#include "config.h"
22+
23+
#if defined(NEWTHREAD_LOCALE_BUG)
24+
#include <sys/syscall.h>
25+
26+
static __thread int fixed_locale = 0;
27+
28+
static pid_t gettid()
29+
{
30+
return syscall(SYS_gettid);
31+
}
32+
33+
#endif
34+
35+
/**
36+
* This works around the LD_AUDIT bug documented at:
37+
* https://sourceware.org/bugzilla/show_bug.cgi?id=32483
38+
*
39+
* We need to set the locale for app-space created threads in the audit space.
40+
* Otherwise we see seg faults under malloc in spindle when malloc calls
41+
* get_nprocs.
42+
**/
43+
void check_for_new_thread()
44+
{
45+
#if defined(NEWTHREAD_LOCALE_BUG)
46+
locale_t l;
47+
if (fixed_locale)
48+
return;
49+
fixed_locale = 1;
50+
if (gettid() == getpid()) {
51+
debug_printf3("Primary thread. Not updating locale.\n");
52+
return;
53+
}
54+
55+
debug_printf2("Identified new thread. Fixing locale\n");
56+
l = uselocale((locale_t) 0);
57+
uselocale(l);
58+
#endif
59+
}

0 commit comments

Comments
 (0)