2014-05-06 51 views
7

我遇到了一個我不確定如何解決的問題。我相信這是GCC和/或libstdC++的問題。在std :: thread :: id的std :: operator中出現分割錯誤==

我使用GCC 4.8.2-19ubuntu1,libstdC++ 3.4.19(我相信?How do you find what version of libstdc++ library is installed on your linux machine?)和boost 1.55運行Ubuntu 14.04 LTS。

下面的代碼:

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

問題: 使用命令行的頂部,我將建立與動態鏈接。一切似乎都很好。我看到明顯有效的輸出與線程ID和跟蹤信息。

但是,在我的項目中,我需要能夠使用靜態鏈接。因此,我將「-static」開關添加到g ++命令中,並將BOOST_ALL_DYN_LINK的#define註釋掉。它建立得很好。但是當我執行程序時,它會一直運行直到第一個線程被創建,然後段錯誤。回溯似乎永遠是相同的:

#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

「GCC和/或libstdC++中的問題」 - 雖然可能發生,但幾乎從未如此。首先在你自己的代碼中尋找問題。 –

+0

這就是我要求的幫助:) – inetknght

回答

5

libpthread靜態鏈接到您的應用程序中是really bad idea

不過,這裏是怎麼做到的。

我首先解決了編譯錯誤(我懷疑你沒有向我們展示實際編譯的代碼,或者提高了對命名空間的污染),然後刪除了不相關的提升內容,這隻會增加噪聲題。下面是代碼:

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

它運行很好,如果我動態鏈接而崩潰時靜態鏈接:

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

根據this e-maillibstdc++有適當地配置,如果你使用線程靜態鏈接。這裏有神奇的標誌,以使其與靜態鏈接工作:

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

正如我之前所說的,靜態鏈接libpthread到您的應用程序是自找麻煩。

+0

問題中的代碼實際上是從發送給同事的文件中完整複製/粘貼的,並且在這裏編譯得很好。儘管如此,我們很高興知道在整個歸檔中似乎已經完成了包裝 - 線程。您提到的鏈接--enable-tls;我認爲這需要重建GCC? – inetknght

+1

@inetknght是的,這意味着不幸的是重建GCC。 – Ali

+0

我想這也意味着如果我動態鏈接到pthreads,這個崩潰也會解決嗎? – inetknght

相關問題