【问题标题】:using clone(): segmentation fault使用克隆():分段错误
【发布时间】:2010-07-23 10:11:54
【问题描述】:

我想使用克隆来记录我的程序的当前状态。 它有很多循环,我想在不打印每个循环迭代中的状态的情况下跟踪该过程。

这就是我创建这个概念验证的原因:

#include <iostream>
#include <cstdlib>

unsigned int i;

int log(void*) {
  std::cout << "LOGGING START" << std::endl;
  while(true) {
    sleep(1);
    std::cout << i << std::endl;
  }
}

int main()  {
  void **child_stack = (void**)malloc(16384);
  i = 0;

  std::clog << "calling clone" << std::endl;
  clone(log, child_stack, CLONE_VM | CLONE_FILES, NULL);
  std::clog << "done" << std::endl;

  while(true) {
    ++i;
  }

  return 0;
}

当我在没有 gdb 的情况下运行它时,它会在 clone() 处出现分段错误而崩溃,但如果我使用 gdb,它可以正常工作。为什么?

你认为这是一个好习惯还是我迟早会遇到麻烦? 有没有更好的方法来实现这一点?

干杯,

曼努埃尔

【问题讨论】:

    标签: c++ segmentation-fault clone


    【解决方案1】:

    clone 的堆栈参数是一个简单的void*。此外,堆栈在大多数体系结构上会向下增长,因此堆栈指针应指向已分配内存的 end

    在任何情况下,您都不应该直接使用clone,除非您确实需要避免对外部库的任何依赖。请改用 pthreads 库。它提供了更简单(也更安全)的 API。

    【讨论】:

    • 好的,但是我必须创建一个互斥体并在 for 循环迭代开始时将其锁定并在最后解锁它?如果是这样,我认为这会损害性能。
    • 我试过用这个,但是性能真的很差。还有其他解决办法吗?
    • @Manuel:通常,您还需要与当前基于clone 的解决方案同步(例如,使用互斥锁),因为代码本身就有问题。在这个特定示例中,您实际上并不需要锁定,因为您只是在转储int。您的监控线程在每次迭代时都处于休眠状态,因此您实际上可能会错过一些整数(代码不一定会打印 1、2、3、4 - 它也可以打印 1、3、4)。
    • 我知道。它不应该打印 1, 2, 3...我只想跟踪是否有进程。实际的问题是:如果我在一个线程中读写,only 在另一个线程中读取是否安全?
    【解决方案2】:

    在英特尔处理器上,child_stack 参数应指向堆栈的顶部,而不是底部。

    无论如何,我认为使用clone 不是一个好主意。大约有三种调用clone 的方法,具体取决于架构,所有这些都没有记录。我建议使用 pthreads 库(或者,因为我们在 C++ 中,所以使用 Boost.Threads)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      • 1970-01-01
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 2017-07-28
      • 1970-01-01
      相关资源
      最近更新 更多