5

我正在使用 64 位 gcc-4.8.2 生成 32 位目标,而我的机器是 64 位的。我正在使用 c++11 并发功能,例如线程、互斥锁、条件变量等。

链接器在尝试链接可执行文件时给出了上述错误消息。libMyLib 也是该项目的一部分。

libMyLib.so: undefined reference to '__gthrw___pthread_key_create(unsigned int*, void (*)(void*))

nm libMyLib.so | grep pthread_key_create 显示:

U _ZL28__gthrw___pthread_key_createPjPFvPvE
w __pthread_key_create@@GLIBC_2.0

符号“ghtrw___pthread_key_create”来自哪里?我尝试添加'-lpthread(-pthread)'作为编译器标志,但它没有帮助。

更多信息。nm libMyLib.so | grep pthread 显示其他符号如 _ZL20__gthread_mutex_lockP15pthread_mutex_t 已定义

4

2 回答 2

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.

于 2014-12-12T13:39:32.340 回答
1

我最近偶然发现了这个错误,而不是因为缺少-pthread.

这种情况发生在一个有点不寻常的设置中:我正在 Centos7 下编译一个用 C++14 编写的软件。由于 C++14 需要最新版本的 GCC,因此我依赖devtoolset 6

鉴于具体的设置,我在 Centos 邮件列表上打开了一个线程,所以我直接引用了相关线程。见https://lists.centos.org/pipermail/centos-devel/2018-May/016701.htmlhttps://lists.centos.org/pipermail/centos-devel/2018-June/016727.html

简而言之,它可能是由 glibc 或 libgcc 的预处理器宏中的一些错误引起的。它可以通过放置#include <thread>在源代码的开头来修复,一旦编译就会出现问题。是的,即使你不使用std::thread它。

我并不声称这对每个人都有效,但在某些特定情况下它可能会起作用。

于 2018-06-01T11:27:20.943 回答