链接pthreads

时间:2016-01-15 07:33:22

标签: c++

花了一整天调查这个bug,我的同事们说它看起来像链接器或库bug。我之前从来没有这样的事情,所以我来这里记录并寻求帮助!

在main之前我的可执行段错误被称为

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00007ffff7b47901 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x00007ffff7b47943 in std::locale::locale() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff7b44724 in std::ios_base::Init::Init() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x0000000000400c1c in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535)
    at /usr/include/c++/4.8/iostream:74
#5  0x0000000000400c45 in _GLOBAL__sub_I__ZN9CrashTestC2Ev () at crash_test.cc:8
#6  0x0000000000400c9d in __libc_csu_init ()
#7  0x00007ffff7512e55 in __libc_start_main (main=0x400bea <main()>, argc=1, argv=0x7fffffffdca8, 
    init=0x400c50 <__libc_csu_init>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdc98)
    at libc-start.c:246
#8  0x0000000000400ad9 in _start ()
(gdb) 

由此导致的崩溃与this question类似,导致this bug report,但我的代码不同且对更改非常敏感。我将问题缩小到5个要求:

  1. 在共享库中实现一个类。
  2. 在另一个实例中声明该类的实例,紧跟在std :: string成员声明之后。
  3. 包括iostream
  4. 与pthreads链接
  5. 使用g ++ - 4.8(或4.9)和gold linker
  6. 那就是它。更改或省略任何要求,并且不会发生段错误。

    我创建了一个最小的测试用例。这是可执行文件头

    // crash_test.h
    #pragma once
    #include <string>
    #include "crash.h"
    
    class CrashTest {
      CrashTest();  // must have a constructor
    
      std::string first_;  // must be a string declared before Crash object
      Crash crash_;  // must be a value, not pointer
    };
    

    主要功能是空的。我甚至没有构建我定义的课程!

    #include "crash_test.h"
    #include <iostream>  // required
    
    CrashTest::CrashTest() { }  // must be here, not header
    
    int main() {
      return 0;
    }
    

    Crash类不会更简单

    // crash.h
    #pragma once
    struct Crash {
      Crash();
    };
    

    但它确实需要一个实现来创建共享库。

    #include "crash.h"
    Crash::Crash() {}  // must be here, not header
    

    我还在全新安装的Ubuntu 14.04上的Docker容器中对此进行了测试,并通过apt-get安装了g ++ - 4.8。

    这是构建脚本。

    #! /bin/sh
    COMPILE="/usr/bin/x86_64-linux-gnu-g++-4.8 -Wall -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers -Werror -std=c++11 -O0 -g "
    
    # Segfault only occurs using the gold linker.
    LINKER="-fuse-ld=gold"
    
    # Compile a shared library and then an executable.
    # If the latter is linked with pthread, it segfaults when run.
    # If the shared library is removed, there is no segfault.
    $COMPILE -fPIC -o crash.o -c crash.cc \
    && $COMPILE -o crash_test.o -c crash_test.cc \
    && $COMPILE -fPIC $LINKER -shared -Wl,-soname,libcrash.so -o libcrash.so crash.o -Wl,-rpath=. \
    && $COMPILE $LINKER crash_test.o -o crash_test -rdynamic libcrash.so -pthread -Wl,-rpath=. \
    && echo "Compiled and linked..." \
    && ./crash_test \
    && echo "Did not crash!"
    

    我已将所有代码放入github仓库:crash_test

    建议赞赏!

1 个答案:

答案 0 :(得分:3)

您似乎遇到了this gold ticket中描述的问题。根据对该票证的评论,以下解决方法为我解决了问题:更改链接器命令行以包含参数$('.selectpicker').selectpicker({ // your custom styles}); 。对于您的构建脚本,那将是:

-Wl,--no-as-needed

但正如我所说,这只是一种解决方法,而且我不确定这是否适合您。如果您需要一个合适的解决方案,您可能应该恢复该票并在那里发布您的发现。