【问题标题】:page fault,shortage of page or access violation?页面错误,页面不足或访问冲突?
【发布时间】:2012-04-03 07:19:07
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 在 CPU 级别,这些都是页面错误(#PF 异常)。当操作系统出现页面错误时,它会通过查看 MM 数据库来确定发生了什么并生成您提到的异常之一。访问冲突是 unix 称为 SIGSEGV 的 Windows 术语。与 x86 无关。
    【解决方案2】:

    在调用页面错误处理程序之前,您读取了 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 告诉你是读还是写不能完成。

    这在Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3: System Programming GuideInterrupt 14—Page-Fault Exception (#PF) 部分进行了描述。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2016-03-02
        • 1970-01-01
        • 2016-05-29
        • 1970-01-01
        • 1970-01-01
        • 2023-01-14
        • 1970-01-01
        • 1970-01-01
        • 2012-09-21
        相关资源
        最近更新 更多