On Tue, Apr 27, 2021 at 6:57 PM Bruno Haible <bruno@clisp.org> wrote:
>
> Hi Florian,
>
> > Here's a fairly representative test case, I think.
> >
> > #include <pthread.h>
> > #include <stdio.h>
> >
> > extern __typeof (pthread_key_create) __pthread_key_create __attribute__
((weak));
> > extern __typeof (pthread_once) pthread_once __attribute__ ((weak));
> >
> > void
> > f1 (void)
> > {
> > puts ("f1 called");
> > }
> >
> > pthread_once_t once_var;
> >
> > void __attribute__ ((weak))
> > f2 (void)
> > {
> > if (__pthread_key_create != NULL)
> > pthread_once (&once_var, f1);
> > }
> >
> > int
> > main (void)
> > {
> > f2 ();
> > }
> >
> > Building it with “gcc -O2 -fpie -pie” and linking with binutils 2.30
> > does not result in a crash with LD_PRELOAD=libpthread.so.0.
>
> Thank you for the test case. It helps the understanding.
>
> But I don't understand
> - why anyone would redeclare 'pthread_once', when it's a standard POSIX
> function,
> - why f2 is declared weak,
> - why the program skips its initializations in single-threaded mode,
> - why libpthread would be loaded through LD_PRELOAD or dlopen, given
> that the long-term statement has been that declaring a symbol weak
> has no effect on the dynamic linker [1][2][3][4]?
>
> How about the following test case instead?
>
> =====================================================================
> #include <pthread.h>
> #include <stdio.h>
>
> #pragma weak pthread_key_create
> #pragma weak pthread_once
>
> void
> do_init (void)
> {
> puts ("initialization code");
> }
>
> pthread_once_t once_var;
>
> void
> init (void)
> {
> if (pthread_key_create != NULL)
> {
> puts ("multi-threaded initialization");
> pthread_once (&once_var, do_init);
> }
> else
> do_init ();
> }
>
> int
> main (void)
> {
> init ();
> }
> =====================================================================
>
> $ gcc -Wall -fpie -pie foo.c ; ./a.out
> initialization code
>
> $ gcc -Wall -fpie -pie foo.c -Wl,--no-as-needed -lpthread ; ./a.out
> multi-threaded initialization
> initialization code
>
> What will change for this program with glibc 2.34?
>
> Bruno
>
> [1] https://sourceware.org/legacy-ml/libc-hacker/2000-06/msg00029.html
> [2] https://www.akkadia.org/drepper/dsohowto.pdf page 6
> [3]
https://stackoverflow.com/questions/21092601/is-pthread-in-glibc-so-implemented-by-weak-symbol-to-provide-pthread-stub-functi/21103255
> [4]
https://stackoverflow.com/questions/20658809/dynamic-loading-and-weak-symbol-resolution
>
Does x86 show the same issue? I fixed several undefined weak symbol
bugs on x86:
https://sourceware.org/bugzilla/show_bug.cgi?id=19636
https://sourceware.org/bugzilla/show_bug.cgi?id=19704
https://sourceware.org/bugzilla/show_bug.cgi?id=19719