multithreading बढ़ावा:: धागा: अनुकूलित संस्करण चल रहा है जब Segfault




segmentation-fault boost-thread (2)

मुझे परेशान करने में परेशानी हो रही है boost:thread काम करने के लिए boost:thread अनुकूलन के बिना संकलन करते समय यह ठीक चलता है:

g++ -o test-thread test-thread.cpp -lboost_thread-gcc-mt-s -lpthread
./test-thread

लेकिन एक संस्करण जो ऑप्टिमाइज़ेशन क्रैश के साथ संकलित है

g++ -O2 -o test-thread test-thread.cpp -lboost_thread-gcc-mt-s -lpthread
./test-thread
Segmentation fault

क्या किसी को पता है कि कारण क्या हो सकता है?

यह कोड मैं उपयोग कर रहा हूं:

#include <boost/thread.hpp>
#include <boost/function.hpp>

void task1() {
  // do something
}
void task2() {
  // do something
}

int main (int argc, char ** argv) {
  using namespace boost;

  function0<void> f1(&task1);
  function0<void> f2(&task2);

  thread thread_1(f1);
  thread thread_2(f2);

  // do other stuff 
  thread_2.join();
  thread_1.join();
  return 0;
}

पुनश्च: मैं उबंटू लिनक्स पर 1.32 को बढ़ावा देने का उपयोग कर रहा हूं।

अद्यतन करें:

यह वह जगह है जहां यह डिबगर में क्रैश हो जाता है (जहां पंक्ति 37 है thread_2.join(); मेरे मूल कोड में):

(gdb) bt
#0  0x080499e0 in boost::thread::join ()
#1  0x080496b8 in main (argc=1, argv=0xbfea3eb4) at ../src/test-thread.cpp:37

ये मेरे वास्तविक दो कार्य हैं:

void task1() {
  std::cerr << "THREAD 1 START" << std::endl;
  for(double i=0; i<999999; ++i){
    std::cout << i << std::endl;
  }
  std::cerr << "THREAD 1 END" << std::endl;
}

void task2() {
  std::cerr << "THREAD 2 START" << std::endl;
  for(double i=0; i<999999; ++i){
    std::cout << i << std::endl;
  }
  std::cerr << "THREAD 2 END" << std::endl;
}

किसी भी मदद के लिए धन्यवाद!


क्या आप सुनिश्चित कर सकते हैं कि कोर डंप सक्रिय हैं ( ulimit -c unlimited ), प्रतीकों (-ओ 2-जी) के साथ संकलित करें, चलाएं, और जीडीबी में स्टैक ट्रेस खोलें? ( gdb test-thread core , फिर gdb प्रॉम्प्ट पर gdb टाइप करें, quit लिए छोड़ें)

अद्यतन करें

बैकट्र्रेस के आधार पर, विभाजन गलती को boost::thread::join होता है क्या आप फिर से कोर खोल सकते हैं और:

  • को boost::thread::join एक disassembly प्राप्त boost::thread::join विधि:
    • disassemble boost::thread::join
    • disassemble
  • रजिस्टरों के डंप प्राप्त करें:
    • info registers

boost::thread::join (1.32 आधिकारिक स्रोत को बढ़ावा देना) का कार्यान्वयन काफी आसान है, इसलिए जब तक कि उबंटू बायनेरिज़ आधिकारिक कोड से अलग न हो जाएं (जो हम उम्मीद करते हैं कि disassembly से पता चल जाएगा), केवल दो विभाजन गलती के संभावित कारण

क्या आप यह भी पुष्टि कर सकते हैं कि उनके प्रिंटआउट्स में दो धागे से विभाजन की गलती से पहले कितनी दूर हो?

void thread::join()
{
    int res = 0;
#if defined(BOOST_HAS_WINTHREADS)
    res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_thread), INFINITE);
    assert(res == WAIT_OBJECT_0);
    res = CloseHandle(reinterpret_cast<HANDLE>(m_thread));
    assert(res);
#elif defined(BOOST_HAS_PTHREADS)
    res = pthread_join(m_thread, 0);
    assert(res == 0);
#elif defined(BOOST_HAS_MPTASKS)
    OSStatus lStatus = threads::mac::detail::safe_wait_on_queue(
        m_pJoinQueueID, NULL, NULL, NULL, kDurationForever);
    assert(lStatus == noErr);
#endif
    // This isn't a race condition since any race that could occur would
    // have us in undefined behavior territory any way.
    m_joinable = false;
}

इन प्रकार की समस्याओं के लिए सामान्य कारण:

  • प्रारंभिक चर
  • वेरिएबल जो दोनों थ्रेड्स द्वारा अभिगम किए गए हैं जिन्हें volatile रूप से चिह्नित नहीं किया गया था
  • इनलाइन किए गए कॉल और / या अनारोल किए गए छोरों (जिनकी स्टैक फ्रेम आकार सभी इनलाइन किए गए विधि के उदाहरणों की स्टैक फ़्रेमों का योग है) जिन्हें पुनरावृत्त कहा जाता है और गैर-इनलाइन किए गए संस्करणों की तुलना में अधिक तेजी से ढेर

मुझे बग मिला! मैंने पुस्तकालय के गलत संस्करण के खिलाफ जुड़ा था मैं boost_thread-gcc-mt-s का उपयोग कर रहा था, लेकिन इसके बजाय boost_thread-gcc-mt साथ काम करता है:

g++ -O2 -o test-thread test-thread.cpp -lboost_thread-gcc-mt -lpthread

मैं प्रलेखन प्रलेखन में देखा, लेकिन मुझे उन पुस्तकालय संस्करणों के बीच के मतभेदों के बारे में कोई जानकारी नहीं मिली। वहाँ भी एक boost_thread-gcc-mt-d , जो मुझे लगता है कि यह डीबग संस्करण है, लेकिन उस के खिलाफ लिंक हमेशा boost_thread-gcc-mt-d में परिणाम देता है, जो कि -g साथ संकलित होने पर भी। लेकिन कम से कम अब मैं धागे चला सकता हूं।





boost-thread