View Bug Activity | Format For Printing
I'm trying to compile glibc 2.3.4, which I retrieved from cvs with the tag glibc-2_3-branch on and for an amd athlon XP 2000+. I used the following options: ../configure --prefix=/usr --enable-add-ons=linuxthreads --disable-static compiler: gcc 3.3.5 binutils: 2.15.94.0.2 kernel: 2.4.29rc2 I'm getting the following error in linuxthreads: make[2]: Entering directory `/opt/cd/libc/linuxthreads' gcc -shared -static-libgcc -Wl,-O1 -Wl,-z,defs -Wl,-dynamic-linker=/lib/ld-linux.so.2 -B/opt/cd/libc/compile/linuxthreads/ -B/opt/cd/libc/compile/csu/ -B/opt/cd/libc/compile/linuxthreads/ -Wl,--version-script=/opt/cd/libc/compile/libpthread.map -Wl,-soname=libpthread.so.0 -Wl,-z,combreloc -Wl,-z,relro -Wl,--enable-new-dtags,-z,nodelete -Wl,--enable-new-dtags,-z,initfirst -L/opt/cd/libc/compile -L/opt/cd/libc/compile/math-L/opt/cd/libc/compile/elf -L/opt/cd/libc/compile/dlfcn -L/opt/cd/libc/compile/nss -L/opt/cd/libc/compile/nis -L/opt/cd/libc/compile/rt -L/opt/cd/libc/compile/resolv -L/opt/cd/libc/compile/crypt -L/opt/cd/libc/compile/linuxthreads -Wl,-rpath-link=/opt/cd/libc/compile:/opt/cd/libc/compile/math:/opt/cd/libc/compile/elf:/opt/cd/libc/compile/dlfcn:/opt/cd/libc/compile/nss:/opt/cd/libc/compile/nis:/opt/cd/libc/compile/rt:/opt/cd/libc/compile/resolv:/opt/cd/libc/compile/crypt:/opt/cd/libc/compile/linuxthreads -o /opt/cd/libc/compile/linuxthreads/libpthread.so -T /opt/cd/libc/compile/shlib.lds /opt/cd/libc/compile/csu/abi-note.o -Wl,--whole-archive /opt/cd/libc/compile/linuxthreads/libpthread_pic.a -Wl,--no-whole-archive /opt/cd/libc/compile/elf/interp.os /opt/cd/libc/compile/libc.so /opt/cd/libc/compile/libc_nonshared.a /opt/cd/libc/compile/elf/ld.so /opt/cd/libc/compile/linuxthreads/libpthread_pic.a(pthread.os)(.text+0x1f6): In function `pthread_initialize': pthread.c: undefined reference to `_res' /opt/cd/libc/compile/linuxthreads/libpthread_pic.a(pthread.os)(.text+0xe72): In function `__pthread_reset_main_thread': pthread.c: undefined reference to `_errno' /opt/cd/libc/compile/linuxthreads/libpthread_pic.a(pthread.os)(.text+0xe84):pthread.c: undefined referenceto `_h_errno' /opt/cd/libc/compile/linuxthreads/libpthread_pic.a(pthread.os)(.text+0xe90):pthread.c: undefined referenceto `_res' /opt/cd/libc/compile/linuxthreads/libpthread_pic.a(pthread.os)(.data.rel+0x1b8): undefined reference to `_errno' /opt/cd/libc/compile/linuxthreads/libpthread_pic.a(pthread.os)(.data.rel+0x1c0): undefined reference to `_h_errno' /opt/cd/libc/compile/linuxthreads/libpthread_pic.a(pthread.os)(.data.rel+0x1c8): undefined reference to `_res' collect2: ld returned 1 exit status make[2]: *** [/opt/cd/libc/compile/linuxthreads/libpthread.so] Error 1 make[2]: Leaving directory `/opt/cd/libc/linuxthreads' There are no compile errors, if I'm using the additional configure option --enable-kernel=2.4.1.
A semi-confirmation here: I see identical symptoms. Notably, I see it on an i586-pc-linux-gnu no matter what --enable-kernel option I try (I've tried 2.4.1 and 2.4.28 so far); I haven't seen it on i686-pc-linux-gnu at all. I think you'll see it whenever you don't explicitly specify the --build or --host to be an i686 at configure time. The cause is that pthread.c states, in part #if !(USE_TLS && HAVE___THREAD) /* These variables are used by the setup code. */ extern int _errno; extern int _h_errno; [...] and on machines lower than i686, USE_TLS is not defined; it is protected by /* We can support TLS only if the floating-stack support is available. However, we want to compile in the support and test at runtime whether the running kernel can support it or not. To avoid bothering with the TLS support code at all, use configure --without-tls. We need USE_TLS to be consistently defined, for ldsodefs.h conditionals. But some of the code below can cause problems in building libpthread (e.g. useldt.h will defined FLOATING_STACKS when it shouldn't). */ #if defined HAVE_TLS_SUPPORT \ && (defined FLOATING_STACKS || !defined IS_IN_libpthread) /* Signal that TLS support is available. */ # define USE_TLS 1 [...] and on machines less than i686, FLOATING_STACKS support is not available (because useldt.h is only included by i686's pt-machine.h, not i386's.) You can `fix' this by configuring --without-tls when building a non-NPTL libc, but that'll lead to NPTL's rtld.c incorporating TLS support, and non-NPTL's not. I think that'd probably cause substantial problems. Alternatively, you can do what all the distributors have done, and re-export _errno and _h_errno, at least within the GLIBC_PRIVATE domain. I'm trying to make that work now, but private symbol exporting is somewhat black magic to me, and I haven't managed to do it yet.
(In reply to comment #1) (tls.h) > #if defined HAVE_TLS_SUPPORT \ > && (defined FLOATING_STACKS || !defined IS_IN_libpthread) > > /* Signal that TLS support is available. */ > # define USE_TLS 1 > [...] The problem is that _errno, _res, _h_errno and the other symbols causing such conniptions are declared in errno.c and herrno.c using a construct like this: #if USE___THREAD [defines e.g. herrno as alias for thread variable __libc_h_errno] #else [defines e.g. herrno and _h_errno, and compatibility symbols for them in GLIBC_2_0] #endif The problem is that because of that `!defined IS_IN_libpthread' in the tls.h included when the linuxthreads add-on is built, we end up with different values of USE_TLS, and thus of USE___THREAD, in the libc and in linuxthreads on a machine without floating stacks. (Specifically, it is true in libc and false in linuxthreads). Thus linuxthreads looks for exported variables which aren't just not exported from libc, but don't exist there. libc's decision is obviously correct: if __thread is available, you *should* use it for errno; this won't change merely because floating stacks happen to be available in one particular threading implementation. So something needs to change in linuxthreads. I'm still not sure what. That code is a bit of a maze, with HAVE___THREAD and USE_TLS interacting in ways that are still unclear to me.
> libc's decision is obviously correct: if __thread is available, you *should* use > it for errno; this won't change merely because floating stacks happen to be > available in one particular threading implementation. So something needs to > change in linuxthreads. > > I'm still not sure what. That code is a bit of a maze, with HAVE___THREAD and > USE_TLS interacting in ways that are still unclear to me. Well, there's code in the linuxthreads Makefile that tries to deal with this case, by pulling the errno.c and herrno.c files out of libc and forcibly linking against them, but that doesn't help because errno.c and herrno.c aren't declaring _errno, _h_errno or _res, because USE___THREAD was turned on when they were linked. Perhaps we'll have to use an rtld-Rules-like hack to recompile errno.c and herrno.c... I really would rather avoid that, though. All this mess just to point at the primary copy of errno.c in the main thread. Why was errno ever invented. Curses.
(In reply to comment #3) > > libc's decision is obviously correct: if __thread is available, you *should* use > > it for errno; this won't change merely because floating stacks happen to be > > available in one particular threading implementation. So something needs to > > change in linuxthreads. Yes it will: manager.c makes that quite clear. So it looks like the constraints we face are as follows: - if TLS is not available, __thread is not available, or the linuxthreads add-on is in use and FLOATING_STACKS are not supportable, then _errno and _h_errno must be compiled into libc, and a TLS cannot be used for errno. - TLS support must nonetheless be compiled into rtld, because otherwise that rtld couldn't successfully interoperate with an NPTL-enabled glibc (as I understand it: that's definitely a goal or almost every distributor will scream). The hard part is how we determine from errno.c, during libc compilation, whether the linuxthreads add-on is in use and whether floating stacks are supported... ... I really don't like mentioning linuxthreads or floating stacks in errno.c. There must be a better way.
LinuxThreads support is gone. Every remaining problem is a feature.
http://sourceware.org/ml/libc-ports/2006-04/msg00035.html
More relevant for the original report: http://sourceware.org/ml/libc-ports/2006-04/msg00039.html I won't fix it, but someone else is welcome to. You don't want to export _errno in this case. Rather, you want to separate the TLS bits that make LinuxThreads use floating stacks from the TLS bits that say to get errno from libc.so using TLS. The pointer/stack guard stuff should also be conditioned on "really have TLS" rather than "using floating stacks".