Hi

Here's another iteration of the patch. __libc_getspecific now
considers the case were pthread is not loaded except when the
containing file is being compiled for the loader.

The test case, when built without pthread, now works
approprietly:

    diego@hird:~/src/test-cases/dlopen-error$ ./main.nopthread
    0x1271b30
    shobj: (nil)
    dlerror: ./non-existent.so: cannot open shared object file: No such file or 
directory
    errno1: [40000002] No such file or directory
    errno2: [40000002] No such file or directory

However, when linked with it, dlerror still modifies the errno
variable:

    diego@hird:~/src/test-cases/dlopen-error$ ./main.pthread
    0x128d688
    shobj: (nil)
    dlerror: ./non-existent.so: cannot open shared object file: No such file or 
directory
    errno1: [40000002] No such file or directory
    errno2: [4000004e] Function not implemented

And breaking with gdb in cthread_getspecific I can confirm the
implementation provided by pthread is not being called:

    diego@hird:~/src/test-cases/dlopen-error$ gdb ./main.pthread
    GNU gdb (Debian 7.10-1+b1) 7.10
    ...
    Reading symbols from ./main.pthread...done.
    (gdb) break cthread_getspecific
    Function "cthread_getspecific" not defined.
    Make breakpoint pending on future shared library load? (y or [n]) y
    Breakpoint 1 (cthread_getspecific) pending.
    (gdb) run
    Starting program: /home/diego/src/test-cases/dlopen-error/main.pthread
    0x128d688
    [New Thread 17594.5]
    
    Breakpoint 1, cthread_getspecific (key=-1, pval=0x2003c9c)
        at ../sysdeps/mach/hurd/cthreads.c:42
    42        *pval = NULL;
    (gdb) bt
    #0  cthread_getspecific (key=-1, pval=0x2003c9c)
        at ../sysdeps/mach/hurd/cthreads.c:42
    #1  0x0109068a in __libc_getspecific (key=-1)
        at ../sysdeps/mach/hurd/cthreads.c:69
    #2  0x01034218 in __dlerror () at dlerror.c:74
    #3  0x080486ae in main (argc=1, argv=0x2003d84) at main.c:17
    (gdb)

I'm not sure what's going on. I've made some simple tests trying
to imitate the setup but weak symbols were correctly overriden.

Regards,
Diego
Default values for thread-specific key handling functions.

* sysdeps/mach/bits/libc-lock.h (__libc_ctf_call): New macro.
(__libc_key_create, __libc_setspecific): Use macro above.
* sysdeps/mach/hurd/bits/libc-lock.h: (__libc_ctf_call): New macro.
(__libc_key_create, __libc_setspecific): Use macro above.
* sysdeps/mach/hurd/cthreads.c (__libc_getspecific): Call
cthread_getspecific only if pthread is present.

---
 sysdeps/mach/bits/libc-lock.h      |   11 +++++++++--
 sysdeps/mach/hurd/bits/libc-lock.h |   11 +++++++++--
 sysdeps/mach/hurd/cthreads.c       |    8 +++++---
 3 files changed, 23 insertions(+), 7 deletions(-)

Index: glibc-2.21/sysdeps/mach/bits/libc-lock.h
===================================================================
--- glibc-2.21.orig/sysdeps/mach/bits/libc-lock.h
+++ glibc-2.21/sysdeps/mach/bits/libc-lock.h
@@ -124,8 +124,15 @@ struct __libc_once
 #define __libc_mutex_unlock __mutex_unlock
 #endif
 
-#define __libc_key_create(KEY,DEST) cthread_keycreate (KEY)
-#define __libc_setspecific(KEY,VAL) cthread_setspecific (KEY, VAL)
+#define __libc_ctf_call(FUNC, ARGS, ELSE) \
+  (&_cthread_init_routine && _cthread_init_routine \
+    ? FUNC ARGS : ELSE)
+
+extern void *(*_cthread_init_routine) (void) __attribute__ ((weak));
+#define __libc_key_create(KEY,DEST) \
+  __libc_ctf_call (cthread_keycreate, (KEY), 1)
+#define __libc_setspecific(KEY,VAL) \
+  __libc_ctf_call (cthread_setspecific, (KEY, VAL), 0)
 void *__libc_getspecific (__libc_key_t key);
 
 /* XXX until cthreads supports recursive locks */
Index: glibc-2.21/sysdeps/mach/hurd/bits/libc-lock.h
===================================================================
--- glibc-2.21.orig/sysdeps/mach/hurd/bits/libc-lock.h
+++ glibc-2.21/sysdeps/mach/hurd/bits/libc-lock.h
@@ -197,8 +197,15 @@ struct __libc_once
 /* Type for key of thread specific data.  */
 typedef cthread_key_t __libc_key_t;
 
-#define __libc_key_create(KEY,DEST) cthread_keycreate (KEY)
-#define __libc_setspecific(KEY,VAL) cthread_setspecific (KEY, VAL)
+#define __libc_ctf_call(FUNC, ARGS, ELSE) \
+  (&_cthread_init_routine && _cthread_init_routine \
+    ? FUNC ARGS : ELSE)
+
+extern void *(*_cthread_init_routine) (void) __attribute__ ((weak));
+#define __libc_key_create(KEY,DEST) \
+  __libc_ctf_call (cthread_keycreate, (KEY), 1)
+#define __libc_setspecific(KEY,VAL) \
+  __libc_ctf_call (cthread_setspecific, (KEY, VAL), 0)
 void *__libc_getspecific (__libc_key_t key);
 
 #endif /* _CTHREADS_ */
Index: glibc-2.21/sysdeps/mach/hurd/cthreads.c
===================================================================
--- glibc-2.21.orig/sysdeps/mach/hurd/cthreads.c
+++ glibc-2.21/sysdeps/mach/hurd/cthreads.c
@@ -54,12 +54,16 @@ cthread_setspecific (key, val)
 }
 
 /* Call cthread_getspecific which gets a pointer to the return value instead
-   of just returning it.  */
+   of just returning it.
+   Follow NPTL, return NULL when pthread is not loaded. */
 void *
 __libc_getspecific (key)
      cthread_key_t key;
 {
-  void *val;
-  cthread_getspecific (key, &val);
+  void *val = NULL;
+#if !IS_IN(rtld)
+  if (&_cthread_init_routine && _cthread_init_routine)
+    cthread_getspecific (key, &val);
+#endif
   return val;
 }

Reply via email to