I'm using 64-bit gcc-4.8.2 to generate a 32-bit target, and my machine is 64-bit. I'm using c++11 concurrency features such as thread, mutex, conditiona_variables and etc.
The linker gave the above error message when trying to link the executable. libMyLib is also part of the project.
libMyLib.so: undefined reference to '__gthrw___pthread_key_create(unsigned int*, void (*)(void*))
nm libMyLib.so | grep pthread_key_create shows:
U _ZL28__gthrw___pthread_key_createPjPFvPvE
w __pthread_key_create@@GLIBC_2.0
where is the symbol 'ghtrw___pthread_key_create' from? I tried adding '-lpthread(-pthread)' as compiler flag, but it does not help.
More information. nm libMyLib.so | grep pthread shows other symbols such as _ZL20__gthread_mutex_lockP15pthread_mutex_t is defined
where is the symbol 'ghtrw___pthread_key_create' from?
It is defined in GCC's "gthreads" abstraction layer for thread primitives, in the gthr-posix.h
header.
#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
# ifndef __gthrw_pragma
# define __gthrw_pragma(pragma)
# endif
# define __gthrw2(name,name2,type) \
static __typeof(type) name __attribute__ ((__weakref__(#name2))); \
__gthrw_pragma(weak type)
# define __gthrw_(name) __gthrw_ ## name
#else
# define __gthrw2(name,name2,type)
# define __gthrw_(name) name
#endif
/* Typically, __gthrw_foo is a weak reference to symbol foo. */
#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
...
#ifdef __GLIBC__
__gthrw2(__gthrw_(__pthread_key_create),
__pthread_key_create,
pthread_key_create)
After preprocessing that expands to:
static __typeof(pthread_key_create) __gthrw___pthread_key_create __attribute__ ((__weakref__("__pthread_key_create")));
It is supposed to be a weak reference to __pthread_key_create
, so it should never have a definition, because it is just a reference to glibc's internal __pthread_key_create
symbol.
So it looks like something has gone wrong with how you build you library. You should not have an undefined weak symbol.
I recently stumbled into this error, and not because of a missing -pthread
.
The situation happened in a somewhat unusual setup: I was compiling a software written in C++14 under Centos7. Since C++14 requires a recent version of GCC, I relied on devtoolset 6 for it.
Given the specific setup, I opened a thread on the Centos mailing list, so I'm directly referencing the relevant thread. See https://lists.centos.org/pipermail/centos-devel/2018-May/016701.html and https://lists.centos.org/pipermail/centos-devel/2018-June/016727.html
In short, it might be caused by some bug in the preprocessor macros, either of glibc or libgcc. It can be fixed by placing #include <thread>
in the beginning of the source code which gives problems once compiled. Yes, even if you don't use std::thread
in it.
I don't claim this will work for everyone, but it might do the job in some particular situations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With