g ++无法解析stdlibc ++中使用的pthread_once [英] g++ doesn't resolve pthread_once used in stdlibc++
问题描述
我正在使用gtest,stdlibc ++和pthread静态链接程序,链接命令如下
I was static linking a program using gtest, stdlibc++ and pthread, the link command is as follows
g ++ -static -L/usr/local/lib -o测试run_test.o -lgtest -lstdc ++ -lgcc -lgcc_eh -lpthread -lc
g++ -static -L/usr/local/lib -o test run_test.o -lgtest -lstdc++ -lgcc -lgcc_eh -lpthread -lc
它可以生成二进制文件,但是每次我跟踪核心转储时都会崩溃
it can produce the binary but it crashes every time, when I trace the core dump
#0 0x0000000000000000 in ?? ()
#1 0x000000000048bf11 in __gthread_once (__func=0x48beb0 ,
__once=)
at /home/abuild/rpmbuild/BUILD/gcc-4.8.5/obj-x86_64-suse-linux/x86_64-suse-linux/libstdc++-v3/include/x86_64-suse-linux/bits/gthr-default.h:699
#2 std::locale::_S_initialize () at ../../../../../libstdc++-v3/src/c++98/locale_init.cc:276
#3 0x000000000048bf53 in std::locale::locale (this=0x7e3a98 )
at ../../../../../libstdc++-v3/src/c++98/locale_init.cc:210
#4 0x000000000045798c in basic_streambuf (this=)
at /home/abuild/rpmbuild/BUILD/gcc-4.8.5/obj-x86_64-suse-linux/x86_64-suse-linux/libstdc++-v3/include/streambuf:466
#5 stdio_sync_filebuf (__f=0x7dd580 , this=)
at /home/abuild/rpmbuild/BUILD/gcc-4.8.5/obj-x86_64-suse-linux/x86_64-suse-linux/libstdc++-v3/include/ext/stdio_sync_filebuf.h:77
#6 std::ios_base::Init::Init (this=) at ../../../../../libstdc++-v3/src/c++98/ios_init.cc:85
#7 0x00000000004028fe in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535)
at /usr/include/c++/4.8/iostream:74
#8 0x0000000000402927 in _GLOBAL__sub_I_main () at run_test.cpp:7
#9 0x00000000004ac017 in __libc_csu_init (argc=argc@entry=1, argv=argv@entry=0x7ffcdf8db6d8, envp=0x7ffcdf8db6e8)
at elf-init.c:88
#10 0x00000000004ababd in __libc_start_main (main=0x4028ae , argc=1, argv=0x7ffcdf8db6d8,
init=0x4abfa0 , fini=0x4ac030 , rtld_fini=0x0, stack_end=0x7ffcdf8db6c8)
at libc-start.c:244
#11 0x00000000004027c7 in _start () at ../sysdeps/x86_64/start.S:122
并反汇编std :: locale :: __ S_initialize()中找到的二进制文件,而不是调用pthread_once的地址来生成生成的二进制callq 0.
and disassembled the binary found in std::locale::_S_initialize () the generated binary callq 0 instead of invoke the address of pthread_once.
48bf0c: e8 ef 40 b7 ff callq 0
使用objdump转储符号表并找到
used objdump to dump the symbol table and found
0000000000000000 w *UND* 0000000000000000 pthread_once
0000000000000000 w *UND* 0000000000000000 __pthread_once
它表明链接器知道pthread_once是未定义的弱符号,并拒绝对其进行解析.我必须添加链接器选项-Wl,-undefined = pthread_once,以强制链接器解析pthread_once以避免崩溃.
It shows that linker know pthread_once is undefined weak symbol and refuse to resolve it. I have to add linker option -Wl,--undefined=pthread_once to force linker to resolve pthread_once to avoid crash.
有人知道为什么链接程序无法解析pthread_once吗?
Does anyone know why linker doesn't resolve pthread_once ?
推荐答案
已将-Wl,-整个存档-lpthread -Wl,-否整个存档作为n.m进行了检查.提到,它有效.可以在 https://gcc.gnu.org中找到更多相关参考. /ml/gcc/2014-11/msg00246.html
Checked -Wl,--whole-archive -lpthread -Wl,--no-whole-archive as n.m. mentioned, it works. A more related reference can be found in https://gcc.gnu.org/ml/gcc/2014-11/msg00246.html
崩溃源于libstdc ++如何使用weakref属性在pthread之上实现称为gthread的包装器.总而言之,发生崩溃是因为
The crash comes from how libstdc++ uses weakref attribute to implement a wrapper called gthread on top of pthread. In summary, crash happens because
- libstdc ++假定,如果定义了__pthread_key_create,则定义了pthread_once,而对于静态链接则不是这样. 在用户代码中的任何其他地方均未引用或定义
- pthread_once.
- gnu链接器无法解析未定义的弱符号pthread_once,没有链接错误,并且pthread_once的地址设置为0.
- pthread_once被调用.
- libstdc++ assumes that if __pthread_key_create is defined, then pthread_once is defined, while this is not true for static linking.
- pthread_once is not referenced or defined any where else in user's code.
- gnu linker doesn't resolve undefined weak symbol pthread_once, there is no link error and the address of pthread_once is set to 0.
- pthread_once is called.
我同意--whole-archive link选项对于stdlibc ++和pthread的静态链接可能是最简单的解决方法.
I agree that --whole-archive link option might be the easiest work around for static linking of stdlibc++ and pthread.
这篇关于g ++无法解析stdlibc ++中使用的pthread_once的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!