2014-05-06 13 views
7

मुझे एक समस्या का सामना करना पड़ा है जो मुझे यकीन नहीं है कि कैसे हल किया जाए। मेरा मानना ​​है कि यह जीसीसी और/या libstdC++ में एक मुद्दा है।std :: thread :: सेगमेंटेशन गलती :: आईडी के std :: ऑपरेटर ==

मैं जीसीसी 4.8.2-19ubuntu1, libstdC++ 3.4.19 (मुझे विश्वास है? How do you find what version of libstdc++ library is installed on your linux machine?) के साथ उबंटू 14.04 एलटीएस चला रहा है, और 1.55 को बढ़ावा देता है।

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

मुद्दा:

कोड यह शीर्ष पर कमांड लाइन का उपयोग करना, मैं गतिशील जोड़ने के साथ का निर्माण होगा। सबकुछ बढ़िया लगता है। मैं स्पष्ट रूप से मान्य आउटपुट थ्रेड आईडी और ट्रेसिंग जानकारी के साथ पूरा देखता हूं।

हालांकि, मेरी परियोजना में मुझे स्थिर लिंकिंग का उपयोग करने में सक्षम होना चाहिए। तो मैं g ++ कमांड में "-स्टैटिक" स्विच में जोड़ता हूं, और BOOST_ALL_DYN_LINK के लिए #define पर टिप्पणी करता हूं। यह ठीक बनाता है। लेकिन जब मैं प्रोग्राम निष्पादित करता हूं, तब तक यह तब तक चलता है जब तक पहला धागा बनता है, फिर segfaults। पश्व-अनुरेखन हमेशा एक ही प्रतीत हो रहा है:

#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() 

यह जैसे कि यह एक अशक्त समारोह सूचक कॉल करने के लिए कोशिश कर रहा है और केवल जब स्थिर जुड़ा हुआ मेरे लिए लग रहा है। कोई विचार? क्या मुझसे कुछ गलत हो रही है?

+1

"जीसीसी और/या libstdC++ में समस्या" - जबकि यह हो सकता है, यह लगभग कभी मामला नहीं है। हमेशा अपने कोड में समस्या को हमेशा देखें। –

+0

यही वह है जो मैं मदद के लिए पूछ रहा हूं :) – inetknght

उत्तर

5

आपके अनुप्रयोगों में libpthread को स्थिर रूप से लिंक करना really bad idea है।

फिर भी, यह कैसे करना है।

मैंने पहली बार संकलन त्रुटियों को ठीक किया है (मुझे संदेह है कि आप हमें वह कोड नहीं दिखा रहे हैं जिसे आप वास्तव में संकलित कर रहे हैं, या नामस्थान को प्रदूषित करते हैं), फिर अप्रासंगिक बूस्ट सामग्री को हटा दिया, जो केवल शोर को जोड़ता है सवाल।

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

अनुसार this e-mail को libstdc++ अगर आप धागे और स्थिर का उपयोग उचित रूप से कॉन्फ़िगर करने के लिए है:

#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; 
} 

यह अगर मैं गतिशील लिंक लेकिन क्रैश स्थिर जुड़ा हुआ ठीक चलाता है: यहाँ कोड है संपर्क। यहाँ जादू झंडे यह स्थिर जोड़ने के साथ काम करने के लिए कर रहे हैं:

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

जैसा कि मैंने पहले कहा, स्थिर अपने आवेदन में libpthread लिंक करने में परेशानी के लिए पूछ रहा है।

+0

प्रश्न में कोड वास्तव में एक प्रतिलिपि में एक प्रतिलिपि/पेस्ट है जिसे मैंने एक सहकर्मी को भेजा है और यहां पर ठीक है। फिर भी, यह जानना अच्छा लगता है कि - लपेटने में -प्थ्रेड -होल-आर्काइव ने चाल की है। आपके लिंक का उल्लेख --enable-tls; मैं इसे लेता हूं जिसके लिए जीसीसी का पुनर्निर्माण करने की आवश्यकता होगी? – inetknght

+1

@inetknght हां, इसका मतलब है दुर्भाग्यवश जीसीसी का पुनर्निर्माण करना। – Ali

+0

मुझे लगता है कि इसका मतलब यह भी है कि यदि मैं गतिशील रूप से pthreads से जुड़ा हुआ है तो यह क्रैश भी हल हो जाएगा? – inetknght

संबंधित मुद्दे