From drepper@redhat.com Mon Oct 6 16:47:00 2008 From: drepper@redhat.com (Ulrich Drepper) Date: Mon, 06 Oct 2008 16:47:00 -0000 Subject: [PATCH] endless loop in __libc_fork In-Reply-To: <1221144185.14064.1.camel@localhost> References: <1221144185.14064.1.camel@localhost> Message-ID: <48EA4111.6010908@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Applied. - -- ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA ??? -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkjqQREACgkQ2ijCOnn/RHRh4wCgyFcPjG+j/JpZyBnNkO0YOsbs Hq8AnR50/eXerZ3Oelvn0iM3UpCse8u9 =klU8 -----END PGP SIGNATURE----- From schwidefsky@de.ibm.com Mon Oct 6 18:17:00 2008 From: schwidefsky@de.ibm.com (Martin Schwidefsky) Date: Mon, 06 Oct 2008 18:17:00 -0000 Subject: [PATCH] s390: tls pointer extraction in __libc_start_main Message-ID: <1223316873.5245.2.camel@localhost> Greetings, a glibc compiled with the latest gcc crashes in __libc_start_main. The cause is that the compiler has decided to extract the tls pointer in __libc_start_main() from the access registers a0/a1 into a general register before the tls pointer has been set up by the call to __pthread_initialize_minimal(). The least invasive fix is to clobber the access registers before the first use in THREAD_SET_STACK_GUARD(). This makes the compiler to do the tls pointer extraction after __pthread_initialize_minimal(). -- blue skies, Martin. "Reality continues to ruin my life." - Calvin. -- 2008-10-06 Martin Schwidefsky * sysdeps/s390/tls.h (THREAD_SET_STACK_GUARD): Add empty inline assembly with a clobber list for access registers a0 and a1. diff -urpN libc/nptl/sysdeps/s390/tls.h libc-s390/nptl/sysdeps/s390/tls.h --- libc/nptl/sysdeps/s390/tls.h 2007-08-07 13:09:01.000000000 +0200 +++ libc-s390/nptl/sysdeps/s390/tls.h 2008-10-06 19:55:46.000000000 +0200 @@ -161,7 +161,12 @@ typedef struct /* Set the stack guard field in TCB head. */ #define THREAD_SET_STACK_GUARD(value) \ - THREAD_SETMEM (THREAD_SELF, header.stack_guard, value) + do \ + { \ + __asm __volatile ("" : : : "a0", "a1"); \ + THREAD_SETMEM (THREAD_SELF, header.stack_guard, value); \ + } \ + while (0) #define THREAD_COPY_STACK_GUARD(descr) \ ((descr)->header.stack_guard \ = THREAD_GETMEM (THREAD_SELF, header.stack_guard)) From jakub@redhat.com Fri Oct 17 10:44:00 2008 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 17 Oct 2008 10:44:00 -0000 Subject: [PATCH] Compile fixes Message-ID: <20081017104731.GD32107@sunsite.ms.mff.cuni.cz> Hi! ATM glibc doesn't build on x86_64-linux, here are the fixes I had to do to make things compile. The mpn stuff is caused by the updates to longlong.h, "=r" ((long) dummy) for int dummy is invalid on 64-bit arches, as it is not an lvalue. Eventhough have_paccept is defined to -1, the code fails to compile: paccept isn't prototyped and it dies with: connections.c:1827: warning: implicit declaration of function ??????paccept?????? connections.c:1831: error: lvalue required as left operand of assignment (obviously have_paccept = something which is -1 = something doesn't compile). Ok to commit? 2008-10-17 Jakub Jelinek * stdlib/divmod_1.c (mpn_divmod_1): Change dummy's type to mp_limb_t. * stdlib/mod_1.c (mpn_mod_1): Likewise. * nscd/connections.c (have_paccept): Remove. (main_loop_poll): Remove paccept code. --- libc/stdlib/divmod_1.c.jj 2008-10-17 10:40:04.000000000 +0200 +++ libc/stdlib/divmod_1.c 2008-10-17 11:04:16.000000000 +0200 @@ -6,7 +6,7 @@ QUOT_PTR and DIVIDEND_PTR might point to the same limb. -Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc. +Copyright (C) 1991, 1993, 1994, 1996, 2008 Free Software Foundation, Inc. This file is part of the GNU MP Library. @@ -55,7 +55,7 @@ mpn_divmod_1 (quot_ptr, dividend_ptr, di { mp_size_t i; mp_limb_t n1, n0, r; - int dummy; + mp_limb_t dummy; /* ??? Should this be handled at all? Rely on callers? */ if (dividend_size == 0) --- libc/stdlib/mod_1.c.jj 2005-12-14 10:45:09.000000000 +0100 +++ libc/stdlib/mod_1.c 2008-10-17 11:04:04.000000000 +0200 @@ -3,7 +3,7 @@ Return the single-limb remainder. There are no constraints on the value of the divisor. -Copyright (C) 1991, 1993, 1994, Free Software Foundation, Inc. +Copyright (C) 1991, 1993, 1994, 2008 Free Software Foundation, Inc. This file is part of the GNU MP Library. @@ -50,7 +50,7 @@ mpn_mod_1 (dividend_ptr, dividend_size, { mp_size_t i; mp_limb_t n1, n0, r; - int dummy; + mp_limb_t dummy; /* Botch: Should this be handled at all? Rely on callers? */ if (dividend_size == 0) --- libc/nscd/connections.c.jj 2008-10-11 10:43:36.000000000 +0200 +++ libc/nscd/connections.c 2008-10-17 11:26:55.000000000 +0200 @@ -238,8 +238,6 @@ static int resolv_conf_descr = -1; /* Negative if SOCK_CLOEXEC is not supported, positive if it is, zero before be know the result. */ static int have_sock_cloexec; -/* The paccept syscall was introduced at the same time as SOCK_CLOEXEC. */ -# define have_paccept -1 // XXX For the time being there is no such call #endif /* Number of times clients had to wait. */ @@ -1817,24 +1815,7 @@ main_loop_poll (void) if (conns[0].revents != 0) { /* We have a new incoming connection. Accept the connection. */ - int fd; - -#ifndef __ASSUME_PACCEPT - fd = -1; - if (have_paccept >= 0) -#endif - { - fd = TEMP_FAILURE_RETRY (paccept (sock, NULL, NULL, NULL, - SOCK_NONBLOCK)); -#ifndef __ASSUME_PACCEPT - if (have_paccept == 0) - have_paccept = fd != -1 || errno != ENOSYS ? 1 : -1; -#endif - } -#ifndef __ASSUME_PACCEPT - if (have_paccept < 0) - fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL)); -#endif + int fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL)); /* Use the descriptor if we have not reached the limit. */ if (fd >= 0) Jakub From jakub@redhat.com Fri Oct 17 10:45:00 2008 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 17 Oct 2008 10:45:00 -0000 Subject: [PATCH] Testcase for the recently fixed tls bug Message-ID: <20081017104832.GE32107@sunsite.ms.mff.cuni.cz> Hi! Here is a testcase which fails without yesterday's dl-tls.c fix and succeeds with it. Ok? 2008-10-17 Jakub Jelinek * elf/Makefile: Add rules to build and run tst-tls17. * elf/tst-tls17.c: New test. * elf/tst-tlsmod17a.c: New file. * elf/tst-tlsmod17b.c: Likewise. --- libc/elf/Makefile.jj 2008-10-11 10:43:35.000000000 +0200 +++ libc/elf/Makefile 2008-10-17 12:10:19.000000000 +0200 @@ -166,7 +166,7 @@ tests += loadtest restest1 preloadtest l restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \ circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \ tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \ - tst-tls16 tst-tls-dlinfo \ + tst-tls16 tst-tls17 tst-tls-dlinfo \ tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \ tst-dlmodcount tst-dlopenrpath tst-deep1 \ tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \ @@ -181,6 +181,7 @@ ifeq (yesyes,$(have-fpie)$(build-shared) tests: $(objpfx)tst-pie1.out endif tests: $(objpfx)tst-leaks1-mem +tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ testobj1_1 failobj constload2 constload3 unloadmod \ dep1 dep2 dep3 dep4 vismod1 vismod2 vismod3 \ @@ -200,6 +201,8 @@ modules-names = testobj1 testobj2 testob tst-tlsmod9 tst-tlsmod10 tst-tlsmod11 tst-tlsmod12 \ tst-tlsmod13 tst-tlsmod13a tst-tlsmod14a tst-tlsmod14b \ tst-tlsmod15a tst-tlsmod15b tst-tlsmod16a tst-tlsmod16b \ + $(patsubst %,tst-tlsmod17a%,$(tlsmod17a-suffixes)) \ + tst-tlsmod17b \ circlemod1 circlemod1a circlemod2 circlemod2a \ circlemod3 circlemod3a \ reldep8mod1 reldep8mod2 reldep8mod3 \ @@ -714,6 +717,13 @@ $(objpfx)tst-tls-dlinfo.out: $(objpfx)ts $(objpfx)tst-tls16: $(libdl) $(objpfx)tst-tls16.out: $(objpfx)tst-tlsmod16a.so $(objpfx)tst-tlsmod16b.so +$(objpfx)tst-tls17: $(libdl) +$(objpfx)tst-tls17.out: $(objpfx)tst-tlsmod17b.so +$(patsubst %,$(objpfx)tst-tlsmod17a%.os,$(tlsmod17a-suffixes)): $(objpfx)tst-tlsmod17a%.os : tst-tlsmod17a.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ -DN=$* -DNOT_IN_libc=1 $< +$(patsubst %,$(objpfx)tst-tlsmod17a%.so,$(tlsmod17a-suffixes)): $(objpfx)tst-tlsmod17a%.so: $(objpfx)ld.so +$(objpfx)tst-tlsmod17b.so: $(patsubst %,$(objpfx)tst-tlsmod17a%.so,$(tlsmod17a-suffixes)) + CFLAGS-tst-align.c = $(stack-align-test-flags) CFLAGS-tst-align2.c = $(stack-align-test-flags) CFLAGS-tst-alignmod.c = $(stack-align-test-flags) --- libc/elf/tst-tls17.c.jj 2008-10-17 11:09:46.000000000 +0200 +++ libc/elf/tst-tls17.c 2008-10-17 11:12:16.000000000 +0200 @@ -0,0 +1,28 @@ +#include +#include + +static int +do_test (void) +{ + void *h = dlopen ("tst-tlsmod17b.so", RTLD_LAZY); + if (h == NULL) + { + puts ("unexpectedly failed to open tst-tlsmod17b.so"); + exit (1); + } + + int (*fp) (void) = (int (*) (void)) dlsym (h, "tlsmod17b"); + if (fp == NULL) + { + puts ("cannot find tlsmod17b"); + exit (1); + } + + if (fp ()) + exit (1); + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" --- libc/elf/tst-tlsmod17a.c.jj 2008-10-17 11:09:19.000000000 +0200 +++ libc/elf/tst-tlsmod17a.c 2008-10-17 11:10:47.000000000 +0200 @@ -0,0 +1,23 @@ +#include + +#ifndef N +#define N 0 +#endif +#define CONCAT1(s, n) s##n +#define CONCAT(s, n) CONCAT1(s, n) + +__thread int CONCAT (v, N) = 4; + +int +CONCAT (tlsmod17a, N) (void) +{ + int *p = &CONCAT (v, N); + /* GCC assumes &var is never NULL, add optimization barrier. */ + asm volatile ("" : "+r" (p)); + if (p == NULL || *p != 4) + { + printf ("fail %d %p\n", N, p); + return 1; + } + return 0; +} --- libc/elf/tst-tlsmod17b.c.jj 2008-10-17 11:09:22.000000000 +0200 +++ libc/elf/tst-tlsmod17b.c 2008-10-17 11:11:10.000000000 +0200 @@ -0,0 +1,15 @@ +#define P(N) extern int tlsmod17a##N (void); +#define PS P(0) P(1) P(2) P(3) P(4) P(5) P(6) P(7) P(8) P(9) \ + P(10) P(12) P(13) P(14) P(15) P(16) P(17) P(18) P(19) +PS +#undef P + +int +tlsmod17b (void) +{ + int res = 0; +#define P(N) res |= tlsmod17a##N (); + PS +#undef P + return res; +} Jakub From drepper@redhat.com Wed Oct 22 21:45:00 2008 From: drepper@redhat.com (Ulrich Drepper) Date: Wed, 22 Oct 2008 21:45:00 -0000 Subject: [PATCH] s390: tls pointer extraction in __libc_start_main In-Reply-To: <1223316873.5245.2.camel@localhost> References: <1223316873.5245.2.camel@localhost> Message-ID: <48FF9EEE.6060405@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Applied. - -- ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA ??? -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkj/nu4ACgkQ2ijCOnn/RHTrrgCgrJ0dzo5Kbwc2Z6CMwHhHxrSC MBsAnA3kp4CWRCp8uDtSHWXDB6JgcJUM =/4dS -----END PGP SIGNATURE----- From jakub@redhat.com Fri Oct 31 20:11:00 2008 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 31 Oct 2008 20:11:00 -0000 Subject: [PATCH] Fix __tls_get_addr Message-ID: <20081031201601.GG32107@sunsite.ms.mff.cuni.cz> Hi! As can be seen on the attached testcase, _dl_update_slotinfo might change THREAD_DTV () (if it needs to reallocate it), but the caller (__tls_get_addr) doesn't refetch dtv from memory, it uses its cached copy. This may crash (if dtv[GET_ADDR_MODULE] is off the cliff, or might read uninitialized memory and return it. Typically dtv[GET_ADDR_MODULE].pointer.val is NULL and so __tls_get_addr returns NULL + offset_within_PT_TLS. The next time __tls_get_addr is called for the same library it will return correct address (as _dl_update_slotinfo won't need to be called). 2008-10-31 Jakub Jelinek * elf/dl-tls.c (__tls_get_addr): After calling _dl_update_slotinfo refetch dtv, as it might have changed. * elf/Makefile: Add rules to build and run tst-tls18. * elf/tst-tls18.c: New test. * elf/tst-tlsmod18a.c: New file. --- libc/elf/dl-tls.c.jj 2008-10-17 12:11:10.000000000 +0200 +++ libc/elf/dl-tls.c 2008-10-31 20:36:14.000000000 +0100 @@ -756,7 +756,10 @@ __tls_get_addr (GET_ADDR_ARGS) void *p; if (__builtin_expect (dtv[0].counter != GL(dl_tls_generation), 0)) - the_map = _dl_update_slotinfo (GET_ADDR_MODULE); + { + the_map = _dl_update_slotinfo (GET_ADDR_MODULE); + dtv = THREAD_DTV (); + } p = dtv[GET_ADDR_MODULE].pointer.val; --- libc/elf/Makefile.jj 2008-10-24 11:42:12.000000000 +0200 +++ libc/elf/Makefile 2008-10-31 20:46:09.000000000 +0100 @@ -166,7 +166,7 @@ tests += loadtest restest1 preloadtest l restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \ circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \ tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \ - tst-tls16 tst-tls17 tst-tls-dlinfo \ + tst-tls16 tst-tls17 tst-tls18 tst-tls-dlinfo \ tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \ tst-dlmodcount tst-dlopenrpath tst-deep1 \ tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \ @@ -182,6 +182,7 @@ tests: $(objpfx)tst-pie1.out endif tests: $(objpfx)tst-leaks1-mem tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 +tlsmod18a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ testobj1_1 failobj constload2 constload3 unloadmod \ dep1 dep2 dep3 dep4 vismod1 vismod2 vismod3 \ @@ -203,6 +204,7 @@ modules-names = testobj1 testobj2 testob tst-tlsmod15a tst-tlsmod15b tst-tlsmod16a tst-tlsmod16b \ $(patsubst %,tst-tlsmod17a%,$(tlsmod17a-suffixes)) \ tst-tlsmod17b \ + $(patsubst %,tst-tlsmod18a%,$(tlsmod18a-suffixes)) \ circlemod1 circlemod1a circlemod2 circlemod2a \ circlemod3 circlemod3a \ reldep8mod1 reldep8mod2 reldep8mod3 \ @@ -724,6 +726,12 @@ $(patsubst %,$(objpfx)tst-tlsmod17a%.os, $(patsubst %,$(objpfx)tst-tlsmod17a%.so,$(tlsmod17a-suffixes)): $(objpfx)tst-tlsmod17a%.so: $(objpfx)ld.so $(objpfx)tst-tlsmod17b.so: $(patsubst %,$(objpfx)tst-tlsmod17a%.so,$(tlsmod17a-suffixes)) +$(objpfx)tst-tls18: $(libdl) +$(objpfx)tst-tls18.out: $(patsubst %,$(objpfx)tst-tlsmod18a%.so,$(tlsmod18a-suffixes)) +$(patsubst %,$(objpfx)tst-tlsmod18a%.os,$(tlsmod18a-suffixes)): $(objpfx)tst-tlsmod18a%.os : tst-tlsmod18a.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ -DN=$* -DNOT_IN_libc=1 $< +$(patsubst %,$(objpfx)tst-tlsmod18a%.so,$(tlsmod18a-suffixes)): $(objpfx)tst-tlsmod18a%.so: $(objpfx)ld.so + CFLAGS-tst-align.c = $(stack-align-test-flags) CFLAGS-tst-align2.c = $(stack-align-test-flags) CFLAGS-tst-alignmod.c = $(stack-align-test-flags) --- libc/elf/tst-tls18.c.jj 2008-10-31 20:47:20.000000000 +0100 +++ libc/elf/tst-tls18.c 2008-10-31 20:51:50.000000000 +0100 @@ -0,0 +1,37 @@ +#include +#include + +static int +do_test (void) +{ + char modname[sizeof "tst-tlsmod18aXX.so"]; + void *h[20]; + for (int i = 0; i < 20; i++) + { + snprintf (modname, sizeof modname, "tst-tlsmod18a%d.so", i); + h[i] = dlopen (modname, RTLD_LAZY); + if (h[i] == NULL) + { + printf ("unexpectedly failed to open %s", modname); + exit (1); + } + } + + for (int i = 0; i < 20; i++) + { + int (*fp) (void) = (int (*) (void)) dlsym (h[i], "test"); + if (fp == NULL) + { + printf ("cannot find test in tst-tlsmod18a%d.so", i); + exit (1); + } + + if (fp ()) + exit (1); + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" --- libc/elf/tst-tlsmod18a.c.jj 2008-10-31 20:52:04.000000000 +0100 +++ libc/elf/tst-tlsmod18a.c 2008-10-31 20:53:01.000000000 +0100 @@ -0,0 +1,21 @@ +#include + +#ifndef N +# define N 0 +#endif + +static __thread int var = 4; + +int +test (void) +{ + int *p = &var; + /* GCC assumes &var is never NULL, add optimization barrier. */ + asm volatile ("" : "+r" (p)); + if (p == NULL || *p != 4) + { + printf ("fail %d %p\n", N, p); + return 1; + } + return 0; +} Jakub