[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#312488: libc0.3: Indirect linking to libpthread fails [patch]



Package: libc0.3
Severity: important
Tags: patch

Problem reported at
http://lists.gnu.org/archive/html/bug-hurd/2005-05/msg00029.html by Neal
Walfield:

-- begin quote --

We've encountered a rather strange linking problem.  gconftool-2 (part
of gconf) uses libxml which in turn uses libpthread.  gconftool-2 does
not directly need libpthread and hence does not need to link against
it.  When gconftool-2 is run, an assertion is triggered which
indicates that _cthread_init_routine is never called (which would be
because _cthread_init_routine is null in
sysdeps/mach/hurd/i386/init_first.c:init).  I've created the following
test program to demonstrate the problem:

  #include <stdio.h>
  #include <libxml/xmlversion.h>
  
  int
  main ()
  {
    xmlCheckVersion (0);
  }
  
  /*
     Local Variables:
     compile-command: "LDLIBS=-lxml2 CFLAGS=-I/usr/include/libxml2 make 
pthread-linking"
     End:
  */


Compiling it and running it indeed yields the same assertion as
gcontool-2:

  $ ./pthread-linking 
  pthread-linking:
  
/build/mbanck/hurd-20050119/build-tree/hurd/libpthread/sysdeps/generic/pt-mutex-timedlock.c:55:
  __pthread_mutex_timedlock_internal: Assertion `__pthread_threads'
  failed.
  Aborted

objdump reveals that it does not have a DT_NEEDED referencing
libpthread:

  $ objdump -x pthread-linking | grep NEEDED
    NEEDED      libxml2.so.2
    NEEDED      libc.so.0.3

while libxml2 does:

  $ objdump -x /lib/libxml2.so | grep NEEDED
    NEEDED      libpthread.so.0.3
    NEEDED      libz.so.1
    NEEDED      libm.so.6
    NEEDED      libc.so.0.3

When we recompile the test program and add -lpthread to LDLIBS (to get
a DT_NEEDED for libpthread in the pthread-linking itself),
_cthread_init_routine is correctly called.

-- end quote --

Roland McGrath provided a patch which works.  He has not applied it to
CVS yet, however, for reasons beyond my understanding.  As more and more
(at least GNOME) packages pass --as-needed to LDFLAGS, this problems
seriously starts to hog down the hurd-i386 port.  One can still cope by
passing LD_PRELOAD=/lib/libpthread.so.0.3, but this is but a hack and I
was not able to get sbuild to pass it on, making most GNOME packages
FTBFS currently.

Please apply.


Michael
#! /bin/sh -e

# DP: Description: Make libpthread load indirectly 
# DP: Related bugs: http://lists.gnu.org/archive/html/bug-hurd/2005-05/msg00029.html
# DP: Patch Author: Roland McGrath 
# DP: Dpatch author: Michael Banck <mbanck@debian.org>
# DP: Upstream status: Not applied
# DP: Date: 08 Jun 2005

if [ $# -ne 2 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch) patch -d "$2" -f --no-backup-if-mismatch -p1 < $0;;
    -unpatch) patch -d "$2" -f --no-backup-if-mismatch -R -p1 < $0;;
    *)
        echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
        exit 1
esac
exit 0

Index: sysdeps/mach/hurd/i386/init-first.c
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/mach/hurd/i386/init-first.c,v
retrieving revision 1.43
diff -B -b -p -u -r1.43 init-first.c
--- sysdeps/mach/hurd/i386/init-first.c 13 Sep 2004 00:42:46 -0000
    1.43
+++ sysdeps/mach/hurd/i386/init-first.c 3 May 2005 00:11:14 -0000
@@ -54,7 +55,7 @@ extern int __libc_argc attribute_hidden;
 extern char **__libc_argv attribute_hidden;
 extern char **_dl_argv;
 
-void *(*_cthread_init_routine) (void); /* Returns new SP to use.  */
+extern void *(*_cthread_init_routine) (void) __attribute__ ((weak));
 void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__));
 
 /* Things that want to be run before _hurd_init or much anything else.
@@ -203,7 +204,7 @@ init (int *data)
      code as the return address, and the argument data immediately above
      that on the stack.  */
 
-  if (_cthread_init_routine)
+  if (&_cthread_init_routine && _cthread_init_routine)
     {
       /* Initialize cthreads, which will allocate us a new stack to run on.  */
       int *newsp = (*_cthread_init_routine) ();


Reply to: