【问题标题】:Starting a std::thread with static linking causes segmentation fault使用静态链接启动 std::thread 会导致分段错误
【发布时间】:2012-01-25 11:53:32
【问题描述】:

为了学习 c++11(和 boost),我正在使用 boost asio 和 c++11(用于线程和 lambdas)编写一个简单的 http-server。

我想测试新的 c++11 lambda 和 std::thread,所以我尝试在带有 lambda 的 std::thread 中像这样启动io_service.run()

#include <iostream>
#include <thread>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
using std::cout;
using std::endl;
using boost::asio::ip::tcp;

class HttpServer
{
public:
    HttpServer(std::size_t thread_pool_size)
    : io_service_(),
    endpoint_(boost::asio::ip::tcp::v4(), 8000),
    acceptor_(io_service_, endpoint_)
    { }

    void Start() {
        acceptor_.listen();
        cout << "Adr before " << &io_service_ << endl;
        std::thread io_thread([this](){
            cout << "Adr inside " << &io_service_ << endl;
            io_service_.run();
        });
        io_thread.join();
    }

private:
    boost::asio::io_service io_service_;
    tcp::endpoint endpoint_;
    tcp::acceptor acceptor_;
};

int main() {
    HttpServer server(2);
    server.Start();
}

这会因分段错误而终止。此外,有时它会在 lambda 中运行 cout,有时则不会(尽管 endl 应该刷新)。在任何情况下,它都会打印出正确的地址io_service_。但是,当我将 std::thread 替换为 boost::thread(没有其他更改!)时,一切正常。

如果有人知道问题出在哪里(可能是 asio、std::thread 或 std::lambda),我将不胜感激。

附加信息:

根据另一个post 在捕获this 时访问lambda 中的成员io_service_ 很好,就像我一样。

我在 Ubuntu 上运行 gcc 4.6.1 并提升 1.46。 G++ 参数:

g++ -std=c++0x -static -I/home/andre/DEV/boost_1_48_0/include/ -L/home/andre/DEV/boost_1_48_0/lib/ -o webserver main.cpp -lboost_system -lboost_thread -lpthread

更新:

删除 -static 解决了这个问题。我发现这个问题与 boost 或 lambdas 无关,并且可以在构建静态和使用std::thread 时重现。出于任何原因,这种组合不起作用。 我认为这个post 描述的几乎相同,但是我不太了解细节并且错误消息不同。

所以我想知道为什么std::thread 和静态链接似乎不能一起工作。这里不允许静态链接有什么原因吗?我更新了问题标题并删除了 boost 标签。

【问题讨论】:

  • 我知道上面的代码此时什么也没做。我只留下了与所描述问题相关的内容...
  • 您是否尝试在调试器中运行它以查看分段错误在哪里?
  • @JoachimPileborg 抱歉,错过了。段错误有时在 lambda 的第一行 (cout problems。
  • @andre.hacker 发布该评论作为答案

标签: c++ c++11


【解决方案1】:

将您的应用与-Wl,--whole-archive -lpthread -Wl,--no-whole-archive 关联 更多在这里https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52590 它对我有用。

【讨论】:

  • 令人遗憾的是,即使在 gcc 6.2 中,仅与 -static -pthread 链接的结果也会导致可执行文件损坏(即运行时错误)并且没有链接器错误甚至警告。我不得不花几个小时调试才发现这个问题自 gcc 4.7 以来就已知并被解决为RESOLVED INVALID。你的回答终于指出我做错了什么。
  • 你是救生员。谢谢!
  • 对于任何来到这里并想知道的人,是的,在 2020 年,GCC 10 仍然需要这样做。
【解决方案2】:

删除 -static 解决了这个问题。我发现它与 boost 或 lambdas 无关,但与静态链接和std::thread 无关,它们似乎因任何未知原因无法协同工作(另请参阅可能相关的post)。

我想他们为什么不一起工作的问题是 - 虽然很有趣 - 目前超出了范围,我很高兴得到答案,因此可以将其标记为已回答。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    相关资源
    最近更新 更多