boost::thread:运行优化版本时出现段错误

发布于 2024-07-14 03:43:52 字数 1605 浏览 6 评论 0原文

我无法让 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;
}

PS:我在 ubuntu linux 上使用 boost 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;
}

谢谢你的帮助!

I have trouble getting boost:thread to work. It runs fine when compiling without optimization:

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

But a version that's compiled with optimizations crashes

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

Does anyone know what might be the reason?

Here is the code I am using:

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

P.S.: I am using boost 1.32 on ubuntu linux.

UPDATE:

Here is where it crashes in the debugger (where line 37 is the one with thread_2.join(); in my original code):

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

Here are my actual two functions:

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

Thanks for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情感失落者 2024-07-21 03:43:52

我发现了这个错误! 我链接了错误版本的库。 我一直在使用 boost_thread-gcc-mt-s,但它可以与 boost_thread-gcc-mt 配合使用:

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

我查看了 boost 文档,但找不到有关这些库版本之间差异的任何信息。 还有一个 boost_thread-gcc-mt-d,我认为它是调试版本,但链接到该版本总是会导致出现段错误的二进制文件,即使使用 -g 进行编译也是如此代码>. 但至少我现在可以运行线程了。

I found the bug! I had linked against the wrong version of the library. I had been using boost_thread-gcc-mt-s, but it works with boost_thread-gcc-mt instead:

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

I looked into the boost documentation, but I couldn't find any information about what the differences between those library versions are. There is also a boost_thread-gcc-mt-d, which I assume is the debug version, but linking against that one always results in binaries that segfault, even when compiling with -g. But at least I can run the threads now.

无尽的现实 2024-07-21 03:43:52

您能否确保核心转储处于活动状态(ulimit -c unlimited)、使用符号编译(-O2 -g)、运行并在 gdb 中打开堆栈跟踪? (gdb test-thread core,然后在 gdb 提示符下键入 backtracequit 退出)

更新

根据回溯,
分段错误发生在
boost::thread::join。 您可以...吗
重新打开核心并:

  • 获取 boost::thread::join 方法的反汇编代码:
    • 反汇编 boost::thread::join
    • 反汇编
  • 获取寄存器转储:
    • 信息寄存器

实施
boost::thread::join(提升 1.32
官方来源)很漂亮
直接了当,所以除非 Ubuntu
二进制文件与
官方代码(我们希望能从反汇编中找到),只有两个
分割的可能原因
错误。

您能否确认两个线程在出现分段错误之前的打印输出有多远?

void 线程::join() 
  { 
      整数分辨率 = 0; 
  #如果已定义(BOOST_HAS_WINTHREADS) 
      res = WaitForSingleObject(reinterpret_cast(m_thread), INFINITE); 
      断言(res == WAIT_OBJECT_0); 
      res = CloseHandle(reinterpret_cast(m_thread)); 
      断言(res); 
  #elif 定义(BOOST_HAS_PTHREADS) 
      res = pthread_join(m_thread, 0); 
      断言(res == 0); 
  #elif 定义(BOOST_HAS_MPTASKS) 
      OSStatus lStatus = 线程::mac::detail::safe_wait_on_queue( 
          m_pJoinQueueID, NULL, NULL, NULL, kDurationForever); 
      断言(lStatus == noErr); 
  #万一 
      // 这不是竞争条件,因为任何可能发生的竞争都会发生 
      // 无论如何让我们处于未定义的行为领域。 
      m_joinable = false; 
  } 
  

此类问题的常见原因:

  • 未初始化的变量
  • 未标记为 易失性 的两个线程都访问了未初始化的变量内
  • 联调用和/或展开循环(其堆栈帧大小是所有内联方法实例堆栈帧的总和)被递归调用,并且比非内联版本更快地溢出堆栈

Could you make sure that core dumps are active (ulimit -c unlimited), compile with symbols (-O2 -g), run, and open the stack trace in gdb? (gdb test-thread core, then type backtrace at the gdb prompt, quit to quit)

UPDATE

Based on the backtrace, the
segmentation fault occurs in
boost::thread::join. Could you
re-open the core and:

  • obtain a disassembly of the boost::thread::join method:
    • disassemble boost::thread::join
    • disassemble
  • obtain a dump of the registers:
    • info registers

The implementation of
boost::thread::join (boost 1.32
official source) is pretty
straight-forward, so unless the Ubuntu
binaries grossly diverge from the
official code (which we'll hopefully find out from the disassembly), there are only two
possible causes for the segmentation
fault.

Can you also confirm how far in their printouts the two threads got before the segmentation fault?

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

Usual causes for these kinds of problems:

  • uninitialized variables
  • variables that are accessed by both threads that were not marked volatile
  • inlined calls and/or unrolled loops (whose stack frame size is the sum of all inlined method instances' stack frames) being called recursively and overflowing the stack much faster than the non-inlined versions
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文