【问题标题】:Unclear Segmentation fault of using Boost Coroutine(1.55)?使用 Boost Coroutine(1.55) 的分段错误不清楚?
【发布时间】:2015-03-16 09:37:34
【问题描述】:

我写了一段代码,它会得到一个Segmentation fault。我不确定这是 Boost Coroutine 的错误还是我下面的代码:

#include <string>
#include <functional>
#include <vector>
#include <fstream>
#include <boost/coroutine/coroutine.hpp>
using namespace std;

template <class T>
using C = boost::coroutines::coroutine<T()>;

string foo(C<string>::caller_type & yield,
           std::string fn, int cnt) {
  std::ifstream f(fn);
  // f.close();
  int local_cnt = 0;
  while(local_cnt < cnt) {
      string l;
      getline(f, l);
      local_cnt ++;
      yield(l);
  }
  f.close();
}

int main(int argc, char *argv[])
{
  vector<C<string> > result;
  for(int i = 0; i < 8192; ++i) {
    C<string> obj(bind(foo, std::placeholders::_1, "test.txt", 3)); // line I
    result.push_back(std::move(obj)); // line J
  }
  return 0;
}

test.txt 非常大,因此在发生段错误之前它永远不会得到 eof。我使用 1.55 的 Boost 并且有一些观察:

  1. line I 中出现段错误
  2. 如果我在 yield 子句之前删除或移动 f.close(),seg-error 就会消失。
  3. 如果我删除代码中的line J,seg-error 就会消失。
  4. 如果我使用较小的数字而不是 8192(比如 512),seg-error 就会消失。

这里有什么问题?

【问题讨论】:

  • 你检查过段错误发生在哪里吗?查看您的代码,您很可能会出现段错误,因为 f 在尝试关闭它时无效。很可能是因为当控制在协程实例和循环的下一次迭代之间传递时,它超出了范围。不过,这在调试器中应该很容易看到。
  • @tmruss 看到我的更新~“f is invalid when try to close it”为什么以及在哪里做这个关闭操作?段错误发生在line I
  • @xunzhang 在这种情况下你能发布堆栈跟踪吗?应该很容易从调试器中获取。
  • @tmruss strace 信息说 Too many open files,我不确定 move 是否会在实际从协程变量 result 获取行之前运行 foo 函数?
  • @xunzhang 不是 strace,崩溃时的堆栈跟踪。您应该能够从核心转储和/或调试器中获得它。

标签: c++ c++11 boost move boost-coroutine


【解决方案1】:

“打开的文件太多” - 您超过了打开文件描述符的最大数量

如果我使用较小的数字而不是 8192(比如 512),段错误就会消失。

seg 错误将发生在 ifstream 内部(不抛出) 检查 ulimit -n cat /proc/sys/fs/file-max sysctl

【讨论】:

    猜你喜欢
    • 2015-10-26
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2011-11-07
    • 1970-01-01
    • 2019-03-05
    • 2013-12-30
    • 2022-01-23
    相关资源
    最近更新 更多