c++11gccopensusegcc4.8

undefined reference to '__gthrw___pthread_key_create(unsigned int*, void (*)(void*))


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


Solution

  • 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.