g ++不解析stdlibc ++

时间:2016-05-27 21:23:02

标签: c++ gcc linker

我使用gtest,stdlibc ++和pthread静态链接程序,链接命令如下

g ++ -static -L / usr / local / lib -o test run_test.o -lgtest -lstdc ++ -lgcc -lgcc_eh -lpthread -lc

它可以生成二进制文件,但每次跟踪核心转储时都会崩溃


    #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()中找到的二进制文件生成的二进制callq 0,而不是调用pthread_once的地址。


      48bf0c:   e8 ef 40 b7 ff          callq  0 

使用objdump转储符号表并找到


    0000000000000000  w      *UND*  0000000000000000 pthread_once
    0000000000000000  w      *UND*  0000000000000000 __pthread_once

它显示链接器知道pthread_once是未定义的弱符号并拒绝解析它。我必须添加链接器选项-Wl, - undefined = pthread_once以强制链接器解析pthread_once以避免崩溃。

有谁知道为什么链接器无法解析pthread_once?

1 个答案:

答案 0 :(得分:0)

检查-Wl, - 整个存档-lpthread -Wl, - no-whole-archive as n.m.提到,它的工作原理。可以在https://gcc.gnu.org/ml/gcc/2014-11/msg00246.html

中找到更相关的参考

崩溃来自于libstdc ++如何使用weakref属性在pthread之上实现一个名为gthread的包装器。总之,崩溃发生是因为

  1. libstdc ++假设如果定义了__pthread_key_create,则定义pthread_once,而静态链接则不然。
  2. pthread_once未在用户代码中的任何其他位置引用或定义。
  3. gnu链接器不解析未定义的弱符号pthread_once,没有链接错误,pthread_once的地址设置为0.
  4. 调用pthread_once。
  5. 我同意--whole-archive链接选项可能是stdlibc ++和pthread的静态链接最简单的解决方法。