lib/glthread/lock.h has this: | /* The way to test at runtime whether libpthread is present is to test | whether a function pointer's value, such as &pthread_mutex_init, is | non-NULL. However, some versions of GCC have a bug through which, in | PIC mode, &foo != NULL always evaluates to true if there is a direct | call to foo(...) in the same function. To avoid this, we test the | address of a function in libpthread that we don't use. */ | | # pragma weak pthread_mutex_init | # pragma weak pthread_mutex_lock | # pragma weak pthread_mutex_unlock | # pragma weak pthread_mutex_destroy | # pragma weak pthread_rwlock_init | # pragma weak pthread_rwlock_rdlock | # pragma weak pthread_rwlock_wrlock | # pragma weak pthread_rwlock_unlock | # pragma weak pthread_rwlock_destroy | # pragma weak pthread_once | […]
And: | # if !PTHREAD_IN_USE_DETECTION_HARD | # pragma weak pthread_mutexattr_gettype | # define pthread_in_use() \ | (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) | # endif As far as I can tell gnulib uses this macro definition to implement gl_once on glibc targets: | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | (pthread_in_use () \ | ? pthread_once (ONCE_CONTROL, INITFUNCTION) \ | : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) So the net effect is this: if (pthread_mutexattr_gettype != NULL) pthread_once (control, callback); Dynamic linking with weak symbols is not very well-defined. On x86-64, the link editor produces the expected dynamic symbol relocation for the pthread_once call. On other targets (notably POWER), no dynamic relocation is produced, and the code will crash if pthread_mutexattr_gettype is ever defined. There is an old thread here covering related issues: Specify how undefined weak symbol should be resolved in executable <https://sourceware.org/legacy-ml/gnu-gabi/2016-q1/msg00004.html> On glibc targets, there is another problem: weak references do not carry symbol versions, so they can bind to base versions unexpectedly. This will become an urgent issue with glibc 2.34, which defines pthread_mutexattr_gettype unconditionally. Certain gnulib modules will stop working until the binaries are relinked. I expect the issue is already visible with earlier glibc versions if libpthread is unexpectedly present at run time. I think we can provide an libBrokenGnulib.so preload module which defines pthread_mutexattr_gettype to zero (as an absolute address), so there is a kludge to keep old binaries working, but this is really something that must be fixed in gnulib. Thanks, Florian