页面错误,页面短缺或访问冲突?

时间:2012-03-18 15:16:43

标签: exception exception-handling operating-system x86 kernel

众所周知,当访问内存中不存在的页面可能导致页面错误时,写入只读页面也会导致页面错误?如何在异常处理程序中识别两种类型的页面错误?

3 个答案:

答案 0 :(得分:7)

在调用页面错误处理程序之前,您会读取CPU在堆栈上放置的异常错误代码。此错误代码包含5位,您对这4位感兴趣:

  • P = 0:故障是由不存在的页面引起的 P = 1:故障是由页面级保护违规引起的。
  • W / R = 0:导致故障的访问是读取 W / R = 1:导致故障的访问是写入。
  • U / S = 0:导致故障的访问在处理器时产生 以管理员模式执行 U / S = 1:导致故障的访问源自处理器 正在以用户模式执行。
  • I / D = 0:故障不是由取指令引起的 I / D = 1:故障是由取指令引起的。

如果你得到P = 0,则该页面不存在。

如果您获得P = 1,则权限不足以访问该页面。 U / S告诉您它是否在内核或应用程序中。 I / D告诉您是否因为代码指令读取(读/写数据)。 W / R会告诉您是否正在读取或写入无法完成的操作。

Interrupt 14—Page-Fault Exception (#PF)的{​​{1}}部分对此进行了描述。

答案 1 :(得分:1)

Alex的答案是完全正确的,但是您还需要将这些信息与您自己的一些信息相结合(即通过查看内存管理器数据)。例如,某些操作系统在第一次引用内存之前不会分配备份内存页面,因此如果您对不存在的页面进行读取或写入,您可能会发现它不存在的原因是你还没有分配它,你应该分配它并继续从例外。类似地,对只读页面的写入可以作为写时复制机制的一部分发生(许多系统执行此操作,最常见的是执行fork()时的posix样式系统),因此您检测到对只读页面的写入,检查内存管理器表并查看应该复制的页面,复制页面,更新页面表并继续。

我发现通常Alex列表中提到的唯一一个有趣的标志就是说它是读还是写。除此之外,您还需要检查MM表格中的所有其他内容。

答案 2 :(得分:-2)

尝试写入只读通常会导致分段错误(SIGSEGV)。

http://en.wikipedia.org/wiki/Segmentation_fault

我认为它在x86用语中称为访问冲突异常(内存访问冲突)。