Hi The patch for thread-specific data key related functions is attached. As discussed on IRC, the modifications were extended to __libc_setspecific and __libc_getspecific.
It has been generated with quilt against debian source package. On Sun, Feb 28, 2016 at 07:57:43PM +0100, Samuel Thibault wrote: > > extern void *(*_cthread_init_routine) (void) __attribute__ ((weak)); > #define __libc_key_create(KEY,DEST) > (_cthread_init_routine?cthread_keycreate(KEY):1) > A slight variation of the conditional was used: #define __libc_ctf_call(FUNC, ARGS, ELSE) \ (&_cthread_init_routine && _cthread_init_routine \ ? FUNC ARGS : ELSE) I had to add the first condition because otherwise a segmentation fault was triggered. Apparently, for an unbound weak symbol to be present in a program/library and evaluate to NULL, you have to take its address at least once (the crash was in libdl, libc access its address during startup). I'd really like to remove that condition. I'll accept any suggestions :) Finally, while this fixes the case where pthread is not present, there are still some issues when linking pthread in. For instance, if I launch gdb, add a breakpoint in '__libc_getspecific' and run the program until that point then the code I see using the list command is the one from the weak functions; as if pthread were not overriding those symbols. My attempts at inspecting how the symbols were bound, using 'LD_DEBUG=all', have failed. glibc's loader prints some output but is eventually killed. This also happens on the rescue shell (from netinst.iso). Below, the last few messages printed before the program being killed: $ LD_DEBUG=all ls 0: symbol=realloc; lookup in file=ls [0] 0: symbol=realloc; lookup in file=/home/diego/src/debian/glibc/glibc-2.21/build-tree/hurd-i386-libc/libc.so.0.3 [0] 0: binding file /lib/ld.so [0] to /home/diego/src/debian/glibc/glibc-2.21/build-tree/hurd-i386-libc/libc.so.0.3 [0]: normal symbol `realloc' [GLIBC_2.2.6] 0: symbol=_hurd_intr_rpc_mach_msg; lookup in file=ls [0] 0: symbol=_hurd_intr_rpc_mach_msg; lookup in file=/home/diego/src/debian/glibc/glibc-2.21/build-tree/hurd-i386-libc/libc.so.0.3 [0] 0: binding file /lib/ld.so [0] to /home/diego/src/debian/glibc/glibc-2.21/build-tree/hurd-i386-libc/libc.so.0.3 [0]: normal symbol `_hurd_intr_rpc_mach_msg' [GLIBC_2.2.6] Killed That's all I could research for now. Regards, Diego
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 @@ -200,8 +200,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 @@ -55,14 +55,11 @@ cthread_setspecific (key, val) return -1; } -/* Call cthread_getspecific which gets a pointer to the return value instead - of just returning it. */ +/* Follow NPTL, return NULL when pthread is not available. */ void * weak_function __libc_getspecific (key) cthread_key_t key; { - void *val; - cthread_getspecific (key, &val); - return val; + return NULL; }