c++ 0x线程静态链接问题
C++0x thread static linking problem
我在尝试使用c++0x线程功能静态链接程序时遇到了一些问题。代码如下:(编译器是gcc 4.6.1在Debian x86_64测试)
#include <iostream>
#include <thread>
static void foo() {
std::cout << "FOO BARn";
}
int main() {
std::thread t(foo);
t.join();
return 0;
}
链接到:
g++ -static -pthread -o t-static t.cpp -std=c++0x
当我执行程序时,我有以下错误:
terminate called after throwing an instance of 'std::system_error'
what(): Operation not permitted
Aborted
GDB调试输出如下所示:
Debugger finished
Current directory is ~/testspace/thread/
GNU gdb (GDB) 7.2-debian
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/will/testspace/thread/t-static...done.
(gdb) list -
1 #include <iostream>
(gdb) b 1
Breakpoint 1 at 0x4007c8: file t.cpp, line 1.
(gdb) r
Starting program: /home/will/testspace/thread/t-static
terminate called after throwing an instance of 'std::system_error'
what(): Operation not permitted
Program received signal SIGABRT, Aborted.
0x00000000004a8e65 in raise ()
(gdb) bt
#0 0x00000000004a8e65 in raise ()
#1 0x000000000045df90 in abort ()
#2 0x000000000044570d in __gnu_cxx::__verbose_terminate_handler() ()
#3 0x0000000000442fb6 in __cxxabiv1::__terminate(void (*)()) ()
#4 0x0000000000442fe3 in std::terminate() ()
#5 0x0000000000443cbe in __cxa_throw ()
#6 0x0000000000401fe4 in std::__throw_system_error(int) ()
#7 0x00000000004057e7 in std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) ()
#8 0x0000000000400b18 in std::thread::thread<void (&)()> (this=0x7fffffffe540, __f=@0x4007c4) at /usr/include/c++/4.6/thread:135
#9 0x00000000004007f3 in main () at t.cpp:11
(gdb)
更新:与静态libstdc++链接可以(可能)使这个错误消失,并且编译的c++ 0x程序可以在没有gcc 4.6 lib的系统上运行:
g++ -static-libgcc -pthread -L.-o t thread.cpp -std=c++0x
但是首先,我们应该创建一个指向'libstdc++ '的符号链接。A ' at current directory:
ln -s `g++ -print-file-name=libstdc++.a`
(参考:http://www.trilithium.com/johan/2005/06/static-libstdc/)
你可以使用-u来解决这个问题(测试在gcc版本4.6.3/(Ubuntu EGLIBC 2.15-0ubuntu10.4) 2.15, gcc版本4.8.1/(Ubuntu EGLIBC 2.15-0ubuntu10.5~ppa1) 2.15)
- wl - u, pthread_cancel, - u, pthread_cond_broadcast, - u, pthread_cond_destroy, - u, pthread_cond_signal, - u, pthread_cond_wait, - u, pthread_create, - u, pthread_detach, - u, pthread_cond_signal, - u, pthread_equal, - u, pthread_join, - u, pthread_mutex_lock, - u, pthread_mutex_unlock, - u, pthread_once, - u, pthread_setcancelstate
1。重现bug
g++ -g -O0 -static -std=c++11 t.cpp -lpthread
./a.out
terminate called after throwing an instance of 'std::system_error'
what(): Enable multithreading to use std::thread: Operation not permitted
Aborted (core dumped)
nm a.out | egrep "bpthread_.*"
w pthread_cond_broadcast
w pthread_cond_destroy
w pthread_cond_signal
w pthread_cond_wait
w pthread_create
w pthread_detach
w pthread_equal
w pthread_join
w pthread_mutex_lock
w pthread_mutex_unlock
w pthread_once
w pthread_setcancelstate
2。修复
g++ -g -O0 -static -std=c++11 t.cpp -lpthread -Wl,-u,pthread_join,-u,pthread_equal
./a.out
FOO BAR
nm a.out | egrep "bpthread_.*"
0000000000406320 T pthread_cancel
w pthread_cond_broadcast
w pthread_cond_destroy
w pthread_cond_signal
w pthread_cond_wait
0000000000404970 W pthread_create
w pthread_detach
00000000004033e0 T pthread_equal
00000000004061a0 T pthread_getspecific
0000000000403270 T pthread_join
0000000000406100 T pthread_key_create
0000000000406160 T pthread_key_delete
00000000004057b0 T pthread_mutex_lock
00000000004059c0 T pthread_mutex_trylock
0000000000406020 T pthread_mutex_unlock
00000000004063b0 T pthread_once
w pthread_setcancelstate
0000000000406220 T pthread_setspecific
由于我完全不知道的原因(我认为这是一个bug),当静态链接时,您不能在gcc 4.6上使用std::thread,因为函数__ghtread_active_p()将被内联为返回false(查看_M_start_thread的程序集),导致抛出此异常。这可能是他们需要弱符号的pthread_create函数在那里,当静态链接他们不在那里,但为什么他们不这样做超出了我(注意,程序集后来包含像callq 0x0
,似乎有一些非常错误)。
现在我个人使用boost::threads,因为我正在使用boost…
你应该确保你链接到pthread库,否则你会得到"Operation not allowed "的消息
例如,要编译源代码,我会使用:
g++ -Wall -fexceptions -std=c++0x -g -c file.cpp -o file.o
然后链接到this:
g++ -o file file.o -lpthread
如果不使用目标文件,您可以尝试这样做:
g++ -Wall -fexceptions -std=c++0x -g main.cpp -o file -lpthread
记住把库放在最后,因为它们只会在链接过程中使用。
我删除了之前的答案,我写了详细的答案
在通常情况下,这个问题是由于libpthread的不完整链接而发生的。我在这里找到了相关信息https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52590
你可以尝试用以下标志链接你的应用:
-Wl,--whole-archive -lpthread -Wl,--no-whole-archive
你也可以用类似的问题来看待这个问题:在linux下的GCC中使用std::thread的正确链接选项是什么?使用静态链接启动std::线程会导致分段错误
- 使用jsoncpp库时出现链接问题
- Cmake 链接问题:未定义对 Button::mousePressEvent(QGraphicsSceneMouseE
- 如何将GTest与CMake一起使用?遵循谷歌指南时的链接问题
- 未解决的外部链接问题
- 'make check' GLIBC 运行时的链接问题
- 在树莓派上用libtorch构建程序时的链接问题
- 野牛弹性链接问题
- 与 AWS 开发工具包的链接问题
- Qt & Firebase C++ SDK 在 iOS 上的链接问题
- 链接问题 boost::p ython::numpy.
- 与 32 位共享对象的链接问题
- 在单元测试项目中包括 .c 文件,并从多个 cpp 文件访问它而不会出现链接问题
- 安卓链接问题
- LLVM 传递链接问题:未定义的符号
- Cmake Mac OSX库链接问题:在Linux上进行编译,但在Mac上进行了编译
- 用libclang解析源文件 - 链接问题包括文件
- C / C++链接问题与非常简单的设置
- Zbar 在 vs2015 链接问题
- Vulkan + GLFW + Cmake在Linux环境下的链接问题
- TFS构建由于链接问题而失败