【问题标题】:What happens after segmentation fault in linux kernel?linux内核中的分段错误后会发生什么?
【发布时间】:2013-08-11 07:27:55
【问题描述】:

当我正在考虑进行网络分页(从远程节点请求错误页面)时,我得到了这个问题:

首先,让我们考虑以下步骤:

1) 用户空间程序尝试访问内存 X。

2) MMU 遍历页表找到 X 的物理地址。

3) 遍历页表时,发现页表项无效。

4) CPU 陷阱并被 Linux 陷阱向量捕获。 (在ARM的情况下,但我认为x86也是一样的,对吧?)

5)此时,我可以从远程节点检索适当的数据,复制到某个物理地址并映射到页表中。

6) 问题来了:在这一点之后,在 X 处发生缺页的程序会安全地读取数据吗?那么,这是否意味着 MMU 或 CPU 以某种方式记住了缺页页表条目并返回到该条目并恢复页表的行走?

如果有哪一步不对,请赐教。

【问题讨论】:

  • 应用级用户程序和内核不是一回事。内核确实处理来自用户程序的页面错误和 SIGSEGV。阅读virtual memoryvirtual address spaceMMULinux kernel 维基页面。内核代码不应出现页面错误。
  • 糟糕透了。内核代码不应出现页面错误。我的意思是用户空间应用程序。问题已解决。
  • 内核做了正确的工作,要么向应用程序进程发送SIGSEGV,要么让数据在 RAM 中可用。
  • 问题是当内核在做这项工作时,应用程序在读取变量 x 时停止。内核完成这项工作后,应用程序的 PC 是否从“读取变量 x”开始(例如 asm ld r0, [x])?还是某种内部指令状态存储在某处并从 MMU 页表遍历开始?
  • 它可能是特定于架构的。在 x86 上,相同的机器指令会重新启动。特别是,SIGSEGV 处理程序不会更改地址空间或错误地址将无限重复。

标签: linux segmentation-fault page-fault


【解决方案1】:

数据中止处理程序只是为pc分配与数据中止处理开始之前相同的值,然后再次执行指令,正确的数据就位,因此数据中止不会再次发生。

【讨论】:

    【解决方案2】:

    解决方案很棘手且不便携。

    当发生分段错误时,您可以从信号处理程序(链接:http://man7.org/linux/man-pages/man2/sigaction.2.html)获取 CPU 寄存器的值。你需要分析这些来决定你是否可以解决这个问题。首先,您需要检查指令指针是否有效。然后,您需要检查错误地址是否在有效范围内。然后,您需要使用 mmap() 系统调用为不存在的页面映射内存。然后,您需要将所需的数据复制到这些页面。信号处理程序返回后,进程将从发生分段错误的位置恢复。

    【讨论】:

      猜你喜欢
      • 2021-12-04
      • 2016-01-23
      • 1970-01-01
      • 2014-11-19
      • 1970-01-01
      • 1970-01-01
      • 2016-03-18
      • 2014-02-07
      • 1970-01-01
      相关资源
      最近更新 更多