5

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

user11869
  • 1,083
  • 2
  • 14
  • 29
  • `I tried adding '-lpthread' as compiler flag` - are you aware about [correct options sequence](http://stackoverflow.com/questions/18388710/what-is-the-proper-sequence-of-options-for-gcc-the-importance-of-that-sequence)? – Gluttton Dec 02 '14 at 19:53
  • 3
    Use the `-pthread` compiler flag instead. – Kerrek SB Dec 02 '14 at 19:56
  • Adding '-pthread' does not fix my problem. Still the question, where does missing symbol come from? – user11869 Dec 03 '14 at 18:28
  • 2
    what is the target and does it have weak support? might be unrelated but gthr.h sets _GLIBCXX_GTHREAD_USE_WEAK to 0 for mingw32 – Come Raczy Dec 05 '14 at 20:59
  • 1
    Did you pass any `-I` flags during the compilation? – Marc Glisse Dec 06 '14 at 08:56
  • 1
    you need to copy/paste the exact compilation line of your *executable*, the fact that mylib.so has undefined symbols is meaningless (use ldd / readelf to check mylib points to pthread). – malat Dec 12 '14 at 13:34
  • @malat it's a big project which uses cmake. I'll try to reproduce it with a minimal example – user11869 Dec 16 '14 at 20:00
  • @user11869 just type `make VERBOSE=1` and copy/paste the compilation line for your exe. – malat Dec 17 '14 at 08:10

2 Answers2

5

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.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • 1
    Last time I saw this error was with another compiler (oracle) that does not define `__GNUC__`, so sys/cdefs defines `__attribute__(X)` as nothing (sunCC provides its own sys/cdefs to avoid this). – Marc Glisse Dec 12 '14 at 17:54
  • I checked that __GNUC__ is defined – user11869 Dec 16 '14 at 19:45
  • @Jonathan Wakely, I found this from gcc documentation "If the target symbol is only referenced through weak references, then the becomes a weak undefined symbol." I don't quite understand the meaning of this sentence. But could this be the reason? – user11869 Dec 16 '14 at 19:57
  • Yes, it could be, but I would expect `-lpthread` to resolve the reference. Is it possible you don't have a 32-bit libpthread.so installed on your system, so `-lpthread` gets ignored, and the weak reference is left unresolved? – Jonathan Wakely Dec 17 '14 at 01:49
2

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.

Dacav
  • 13,590
  • 11
  • 60
  • 87