【问题标题】:Is there any reason this c recursive function generates this pagefault?这个 c 递归函数有什么原因会产生这个页面错误吗?
【发布时间】:2021-12-31 02:28:30
【问题描述】:

所以我想在 c 中编写递归系统调用,它从一个进程(孩子、孙子、..)中获取所有后代。我使用的系统是 Minix 3.2.1,但我认为它应该与大多数 UNIX 系统没有太大不同。但是我的函数抛出了非常丑陋的错误。 代码如下:

int do_whoMaxDescendants(void)
{
  int maxChildren = 0;
  pid_t found = -1;

  for (int proc_nr = 0; proc_nr < NR_PROCS; ++proc_nr)
  {
    if (mproc[proc_nr].mp_flags & IN_USE)
    {
      int children = kidCount(proc_nr);
      if (children > maxChildren)
      {
        maxChildren = children;
        found = mproc[proc_nr].mp_pid;
      }
    }
  }
  return found;
}

int kidCount(int currParent)
{
  int children = 0;
  for (int nextParent = 0; nextParent < NR_PROCS; ++nextParent)
  {
    if ((mproc[nextParent].mp_flags & IN_USE) && (mproc[nextParent].mp_parent == currParent))
    {
      children++;
      children = kidCount(nextParent) + children;
    }
  }
  return children;
}

错误看起来像这样:

【问题讨论】:

  • 很好奇,为什么是int do_whoMaxDescendants() 而不是pid_t do_whoMaxDescendants()?
  • 在我知道的系统中,在这个系统中,pid_t 基本上是有符号的 int,对于我的需要 int 就足够了
  • 如果您希望您的代码在许多系统上工作,请考虑this。
  • Edit 包含错误的问题作为文本,而不是图像。 mproc 是什么?
  • 不幸的是,我无法从我的虚拟机中复制错误,因此我复制了一个截图。 mproc 是一个花哨的结构,包含大量有关系统中进程的信息,但是对于这个 sn-p 的需要,它可以告诉我们是否正在使用 procces 以及谁是该进程的父进程

标签: c unix system-calls minix


【解决方案1】:

您正在编写 Minix 内核代码。 The Minix kernel stack is 4096 bytes. 任何重要的递归都可能溢出它,这可能是您的页面错误的原因。请注意,错误地址位于页面末尾附近,可能是堆栈页面下方的下一页,这可能是未映射的保护页面,因此堆栈溢出会在破坏其他数据之前发生恐慌。

所以你需要想出一个不使用递归的算法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多