我已经在谷歌上搜索了很长一段时间,我没有看到任何类似的东西,所以这里是。我正在尝试创建一个小的静态链接二进制文件,它可以很容易地分布在我家庭网络上的机器上。这是一个非常小的项目,所以我试图让事情变得简单。
当我在 ARM 32 位架构上静态链接 pthread 库时,我遇到了很大的困难。令人沮丧的是,完全相同的代码在 x86 的所有版本上都可以正常工作。这是我的 test.cpp 程序:
void threader( int num ) {
std::cout << "Child Thread Starting" << std::endl;
try {
throw 20;
} catch (int e) {
std::cout << "Child Thread Success" << std::endl;
}
int x = 0;
do {
x++;
} while (true);
}
int main(int argc, char *argv[]) {
std::cout << "Main Thread Starting" << std::endl;
new std::thread(&threader, 0);
try {
throw 20;
} catch (int e) {
std::cout << "Main Thread Success" << std::endl;
}
int y = 0;
do {
y++;
} while (true);
}
Run Code Online (Sandbox Code Playgroud)
这个想法是主线程启动一个子线程,然后测试主线程是否可以抛出异常,然后旋转。同时,子线程也测试是否可以抛出异常,然后自旋。原始代码抛出 boost-brand 异常,导致崩溃。这个最小的例子具有相同的行为。
在 x86 上的成功结果如下:
# g++ -m32 -std=c++11 -c -g test.cpp
# g++ -static -m32 *.o -o test -lrt -pthread
# ./test
Main Thread Starting
Child Thread Starting
Main Thread Success
Child Thread Success
Run Code Online (Sandbox Code Playgroud)
但是,在 ARM 上,根据我如何准确链接事物,我会收到各种错误。作为参考,我从简单的开始:
$ g++ -std=c++11 -c -g test.cpp
$ g++ -static *.o -o test -lrt -pthread
$ ./test
Main Thread Starting
Child Thread Starting
Main Thread Success
Segmentation fault
Run Code Online (Sandbox Code Playgroud)
分段错误不是很有帮助:
(gdb) bt
#0 0x00012be8 in __cxa_throw ()
#1 0x000108d0 in threader (num=0) at test.cpp:11
#2 0x00011a26 in std::_Bind_simple<void (*(int))(int)>::_M_invoke<0u>(std::_Index_tuple<0u>) (this=0xda50c) at /usr/include/c++/4.8/functional:1732
#3 0x00011950 in std::_Bind_simple<void (*(int))(int)>::operator()() (this=0xda50c) at /usr/include/c++/4.8/functional:1720
#4 0x0001190a in std::thread::_Impl<std::_Bind_simple<void (*(int))(int)> >::_M_run() (this=0xda500) at /usr/include/c++/4.8/thread:115
#5 0x0001befc in execute_native_thread_routine ()
#6 0x0004bcc2 in start_thread (arg=0x0) at pthread_create.c:335
#7 0x00071b4c in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
Run Code Online (Sandbox Code Playgroud)
当 throw() 导致分段错误时,您会遇到问题。当我删除“-static”标志时,一切都会完美地执行,就像在 x86 的情况下一样。
经过大量的谷歌搜索后,我发现这个问题显然很常见。其他答案包括:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52590
g++静态链接pthread时,导致Segmentation fault,为什么?
以及许多其他类似的。关键建议似乎是与“-Wl,--whole-archive -lpthread -Wl,--no-whole-archive”短语链接。好的,让我们试一试:
$ g++ -std=c++11 -c -g test.cpp
$ g++ -static *.o -o test -lrt -pthread -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
$ ./test
Main Thread Starting
Child Thread Starting
terminate called after throwing an instance of 'Segmentation fault
Run Code Online (Sandbox Code Playgroud)
好吧,它因与众不同而获得积分。GDB:
(gdb) r
Starting program: ./test
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
Main Thread Starting
[New Thread 0x76ffc2d0 (LWP 30844)]
Child Thread Starting
terminate called after throwing an instance of 'int'
terminate called recursively
Thread 1 "test" received signal SIGABRT, Aborted.
0x00055266 in __libc_do_syscall ()
(gdb) bt
#0 0x00055266 in __libc_do_syscall ()
#1 0x0001ab66 in raise (sig=6) at ../sysdeps/unix/sysv/linux/pt-raise.c:35
#2 0x0005a85a in abort ()
#3 0x0004bd3c in __gnu_cxx::__verbose_terminate_handler() ()
#4 0x00026d34 in __cxxabiv1::__terminate(void (*)()) ()
#5 0x00026d50 in std::terminate() ()
#6 0x0001ca3c in __cxa_rethrow ()
#7 0x0004bd1c in __gnu_cxx::__verbose_terminate_handler() ()
#8 0x00026d34 in __cxxabiv1::__terminate(void (*)()) ()
#9 0x00026d50 in std::terminate() ()
#10 0x0001c9fc in __cxa_throw ()
#11 0x0001098e in main (argc=1, argv=0x7efff704) at test.cpp:28
(gdb) frame 11
#11 0x0001098e in main (argc=1, argv=0x7efff704) at test.cpp:28
28 throw 20;
(gdb)
Run Code Online (Sandbox Code Playgroud)
有两件事要注意:一,它现在是父线程崩溃了,二,它显然是一个“int”,它是段错误。好吧……那很特别。
SO 上还有另一个答案,似乎注意到与此类似的内容:
GCC:用于静态链接到 pthread 的 --whole-archive 配方在最近的 gcc 版本中停止工作
但是此解决方案建议围绕 -lrt 和 -lpthread 标志的顺序和频率进行调整。我已经尝试过......这些的很多组合。它总是导致上述行为。
我还将注意到,上述问题中的示例程序在问题 ARM32 系统上运行得非常好。但是,如果我将“throw 20”测试块添加到线程函数中,它会立即中断。
作为记录,我还尝试了很多与 boost::thread 的组合,也尝试过使用 clang 进行编译,结果都是一样的。
在这一点上,我完全不知所措,并投身于互联网的怜悯。有谁知道这里发生了什么,或者我如何进行更多调查?
归档时间: |
|
查看次数: |
130 次 |
最近记录: |