gpt4 book ai didi

c++ - 链接 pthread 时启动时出现简单的可执行段错误

转载 作者:可可西里 更新时间:2023-11-01 16:42:11 24 4
gpt4 key购买 nike

花了一整天时间调查这个错误,我的同事说它看起来像一个链接器或库错误。我以前从未有过这样的事情,所以我在这里记录下来并寻求帮助!

在调用 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. 与线程链接
  5. 使用 g++-4.8(或 4.9)和 gold linker

就是这样。更改或省略任何要求,并且不会发生段错误。

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

// 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

感谢建议!

最佳答案

您似乎遇到了 this gold ticket 中描述的问题.根据对该票证的评论,以下解决方法为我解决了这个问题:更改链接器命令行以包含参数 -Wl,--no-as-needed。对于您的构建脚本,这将是:

$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=. -Wl,--no-as-needed

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

关于c++ - 链接 pthread 时启动时出现简单的可执行段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34806236/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com