这个 c 递归函数有啥原因会产生这个页面错误吗?

Posted

技术标签:

【中文标题】这个 c 递归函数有啥原因会产生这个页面错误吗?【英文标题】: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 以及谁是该进程的父进程 【参考方案1】:

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

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

【讨论】:

以上是关于这个 c 递归函数有啥原因会产生这个页面错误吗?的主要内容,如果未能解决你的问题,请参考以下文章

在JAVA中啥是递归?有啥用?

有啥经典的c语言算法书推荐一下吗

C语言 递归程序 求解

Python 函数进阶-递归函数

python_之递归函数

C语言中啥叫死循环?怎么避免?