bug-gnulib
[Top][All Lists]
Advanced

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

Re: Undefined use of weak symbols in gnulib


From: Bruno Haible
Subject: Re: Undefined use of weak symbols in gnulib
Date: Wed, 28 Apr 2021 02:09:19 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-206-generic; KDE/5.18.0; x86_64; ; )

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]