std :: thread :: id的std :: operator ==中的分段错误 [英] Segmentation fault in std::thread::id's std::operator==

查看:493
本文介绍了std :: thread :: id的std :: operator ==中的分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个我不知道如何解决的问题。我相信这是一个问题在GCC和/或libstdc ++。



我正在运行Ubuntu 14.04 LTS与GCC 4.8.2-19ubuntu1,libstdc ++ 3.4.19 ?如何你找到什么版本的libstdc ++库安装在你的linux机器上吗?)和boost 1.55。



这里的代码:

  // http://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/log/tutorial.html 
//稍作修改,以确保我们正在测试线程
// g ++ -g -O0 --std = c ++ 11 staticlinktest.cpp -lboost_log_setup -lboost_log -lboost_system -lboost_filesystem -lboost_thread -lpthread

#define BOOST_ALL_DYN_LINK 1

#include< boost / log / trivial.hpp>

#include< thread>
#include< atomic>
#include< vector>

int main(int,char * [])
{
BOOST_LOG_TRIVIAL(trace)< 跟踪严重性消息;
BOOST_LOG_TRIVIAL(debug)<< 调试严重性消息;
BOOST_LOG_TRIVIAL(info)<< 信息严重性消息;
BOOST_LOG_TRIVIAL(warning)<< 警告严重性消息;
BOOST_LOG_TRIVIAL(error)<< 错误严重性消息;
BOOST_LOG_TRIVIAL(fatal)<< 致命的严重性信息;

std :: atomic< bool>退出(false);
std :: vector< std :: thread>线程;
for(int i = 0; i <8; ++ i){
threads.push_back(std :: thread([& exiting](){
while )
BOOST_LOG_TRIVIAL(trace)<thread<< std :: this_thread :: get_id()<trace;
}))
}

usleep(1000000);
exiting = true;
std :: for_each(threads.begin(),threads.end(),[](std :: thread& t){
t.join();
}

return 0;
}

问题:
使用顶部的命令行将建立与动态链接。一切似乎工作伟大。我看到明显有效的输出完成了线程ID和跟踪信息。



但是,在我的项目中,我需要能够使用静态链接。所以我在-static开关中添加了g ++命令,并注释掉了#define for BOOST_ALL_DYN_LINK。它建立只是罚款。但是当我执行程序,它运行,直到第一个线程被创建,然后segfaults。回溯似乎总是相同的:

 #0 0x0000000000000000 in? ()
#1 0x0000000000402805在__gthread_equal(__t1 = 140737354118912,__t2 = 0)at /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h:680
# 2 0x0000000000404116 in std :: operator ==(__x = ...,__y = ...)at /usr/include/c++/4.8/thread:84
#3 0x0000000000404c03 in std :: operator< < char,std :: char_traits< char> > (__out = ...,__id = ...)在boost :: log :: v2s_mt_posix :: operator中的/usr/include/c++/4.8/thread:234
#4 0x6000000040467e :: operator< < char,std :: char_traits< char>,std :: allocator< char>,std :: thread :: id> (__closure())中的/usr/include/boost/log/utility/formatting_ostream.hpp:710
#5 0x0000000000402939(strm = ...,
value = ...) = 0x7bb5e0)at staticlinktest.cpp:27
#6 0x0000000000403ea8 in std :: _ Bind_simple< main(int,char **):: __ lambda0()> :: _ M_invoke<>(std :: _ Index_tuple& ;)(this = 0x7bb5e0)
at /usr/include/c++/4.8/functional:1732
#7 0x0000000000403dff in std :: _ Bind_simple< main(int,char **):: __ lambda0 > :: operator()(void)(this = 0x7bb5e0)
at /usr/include/c++/4.8/functional:1720
#8 0x0000000000403d98 in std :: thread :: _Impl< std: :_Bind_simple< main(int,char **):: __ lambda0()> > :: _ M_run(void)(this = 0x7bb5c8)
at /usr/include/c++/4.8/thread:115
#9 0x000000000047ce60 in execute_native_thread_routine()
#10 0x000000000042a962 in start_thread (arg = 0x7ffff7ffb700)at pthread_create.c:312
#11 0x00000000004e5ba9在clone()

它看起来像我一样,试图调用一个空函数指针,只有静态链接。有什么想法吗?

静态链接 libpthread

p>



我首先修复了编译错误(我怀疑你没有向我们展示你实际编译的代码,或者boost会污染命名空间那么多),然后删除不相关的boost东西,只有添加噪声的问题。下面是代码:

  #include< atomic> 
#include< chrono>
#include< iostream>
#include< thread>
#include< vector>

int main(int,char * [])
{
std :: atomic< bool>退出(false);

std :: vector< std :: thread>线程;
for(int i = 0; i <8; ++ i){
threads.push_back(std :: thread([& exiting](){
while )
std :: cout<<thread<< std :: this_thread :: get_id()<<trace\\\
;
}))
}

std :: this_thread :: sleep_for(std :: chrono :: milliseconds(1));

exiting = true;

for(auto& t:threads){
t.join();
};

return 0;
}

如果我动态链接,运行良好,但静态链接时崩溃:

 在抛出'std :: system_error'的实例后调用terminate 
what():不允许操作
中止(核心转储)

根据这个电子邮件如果你使用线程,必须适当地配置 libstdc ++ 和静态链接。下面是使用静态链接工作的魔法标志:

  g ++ -std = c ++ 11 -pedantic -pthread threads .cpp -static -Wl, -  whole-archive -lpthread -Wl, -  no-whole-archive 

正如我之前所说,将 libpthread 静态链接到您的应用程序中要求麻烦。


I have encountered an issue which I am not sure how to resolve. I believe it's an issue in GCC and/or libstdc++.

I am running Ubuntu 14.04 LTS with GCC 4.8.2-19ubuntu1, libstdc++3.4.19 (I believe? How do you find what version of libstdc++ library is installed on your linux machine?), and boost 1.55.

Here's the code:

// http://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/log/tutorial.html
// with a slight modification to ensure we're testing with threads too
// g++ -g -O0 --std=c++11 staticlinktest.cpp -lboost_log_setup -lboost_log -lboost_system -lboost_filesystem -lboost_thread -lpthread

#define BOOST_ALL_DYN_LINK 1

#include <boost/log/trivial.hpp>

#include <thread>
#include <atomic>
#include <vector>

int main(int, char*[])
{
    BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
    BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
    BOOST_LOG_TRIVIAL(info) << "An informational severity message";
    BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
    BOOST_LOG_TRIVIAL(error) << "An error severity message";
    BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";

    std::atomic<bool> exiting(false);
    std::vector<std::thread> threads;
    for ( int i = 0; i < 8; ++i ) {
        threads.push_back(std::thread([&exiting](){
            while (!exiting)
                BOOST_LOG_TRIVIAL(trace) << "thread " << std::this_thread::get_id() << " trace";
        }));
    }

    usleep(1000000);
    exiting = true;
    std::for_each(threads.begin(), threads.end(), [](std::thread& t){
        t.join();
    });

    return 0;
}

The issue: Using the command line at the top, I would build with dynamic linking. Everything seems to work great. I see apparently-valid output complete with thread IDs and tracing information.

However, in my project I need to be able to use static linking. So I add in the "-static" switch to the g++ command, and comment out the #define for BOOST_ALL_DYN_LINK. It builds just fine. But when I execute the program, it runs up until the first thread gets created, then segfaults. The backtrace seems to always be the same:

#0  0x0000000000000000 in ?? ()
#1  0x0000000000402805 in __gthread_equal (__t1=140737354118912, __t2=0) at /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h:680
#2  0x0000000000404116 in std::operator== (__x=..., __y=...) at /usr/include/c++/4.8/thread:84
#3  0x0000000000404c03 in std::operator<< <char, std::char_traits<char> > (__out=..., __id=...) at /usr/include/c++/4.8/thread:234
#4  0x000000000040467e in boost::log::v2s_mt_posix::operator<< <char, std::char_traits<char>, std::allocator<char>, std::thread::id> (strm=..., 
    value=...) at /usr/include/boost/log/utility/formatting_ostream.hpp:710
#5  0x0000000000402939 in __lambda0::operator() (__closure=0x7bb5e0) at staticlinktest.cpp:27
#6  0x0000000000403ea8 in std::_Bind_simple<main(int, char**)::__lambda0()>::_M_invoke<>(std::_Index_tuple<>) (this=0x7bb5e0)
    at /usr/include/c++/4.8/functional:1732
#7  0x0000000000403dff in std::_Bind_simple<main(int, char**)::__lambda0()>::operator()(void) (this=0x7bb5e0)
    at /usr/include/c++/4.8/functional:1720
#8  0x0000000000403d98 in std::thread::_Impl<std::_Bind_simple<main(int, char**)::__lambda0()> >::_M_run(void) (this=0x7bb5c8)
    at /usr/include/c++/4.8/thread:115
#9  0x000000000047ce60 in execute_native_thread_routine ()
#10 0x000000000042a962 in start_thread (arg=0x7ffff7ffb700) at pthread_create.c:312
#11 0x00000000004e5ba9 in clone ()

It looks to me as if it's trying to call a null function pointer and only when linked statically. Any thoughts? Am I doing something wrong?

解决方案

Statically linking libpthread into your applications is a really bad idea.

Nevertheless, here is how to do it.

I first fixed the compile errors (I suspect that you aren't showing us the code that you are actually compiling, or boost pollutes the namespace that much), then removed the irrelevant boost stuff, that only adds noise to the question. Here is the code:

#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
#include <vector>

int main(int, char*[])
{
    std::atomic<bool> exiting(false);

    std::vector<std::thread> threads;
    for ( int i = 0; i < 8; ++i ) {
        threads.push_back(std::thread([&exiting](){
            while (!exiting)
                std::cout << "thread " << std::this_thread::get_id() << " trace\n";
        }));
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(1));

    exiting = true;

    for(auto& t : threads){
        t.join();
    };

    return 0;
}

It runs fine if I dynamically link but crashes when statically linked:

terminate called after throwing an instance of 'std::system_error'
  what():  Operation not permitted
Aborted (core dumped)

According to this e-mail the libstdc++ has to be configured appropriately if you use threads and statically link. Here are the magic flags to make it work with static linking:

g++ -std=c++11 -pedantic -pthread threads.cpp -static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive

As I said before, statically linking libpthread into your application is asking for trouble.

这篇关于std :: thread :: id的std :: operator ==中的分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆