如何在虚拟内存中发生seg故障?

时间:2015-07-15 18:49:06

标签: segmentation-fault virtual-memory

我很困惑,当使用虚拟内存时,进程可能会出现故障。据我所知,“虚拟”内存允许进程访问所有可用内存,然后映射到“实际”硬件内存。通过这种转换,进程如何尝试访问不允许的内存部分?

5 个答案:

答案 0 :(得分:2)

听起来你可能会因混淆Unix的使用而感到困惑。在Unix上,您可以获得SIGSEG(无效内存引用)信号。即使底层硬件中没有“段”,也可以将该信号发送到进程。 SIGBUS是您可以获得的另一个内存错误。多年来,我没有在各种unix实现上找到很多一致性,因为在什么条件下导致哪个信号。

这些是您可以在虚拟内存访问中获得的编程错误:

  1. 地址没有页表条目(进程很少有地址空间中每个可能页面的页表条目 - 尽管许多人在这里提出了无用的操作系统书籍问题。)

  2. 地址有一个页表条目但没有映射内存(例如,通常不映射第一页)。

  3. 内存映射到地址但页面不在内存中(页面错误)。

  4. 内存已映射,但访问受处理器模式保护。 (例如,尝试从用户模式访问仅内核页面)。

  5. 内存已映射,但不允许对页面进行访问。 E.g。

    • 尝试执行不可执行的页面。
    • 尝试写入只读页面
  6. (其他人会指出我是否错过了任何一个。)

    这些事件(#3除外 - 由OS处理)通常会触发SIGBUS或SIGSEG信号。但是,正如我所说,上述哪个事件将触发哪些信号几乎没有一致性。

答案 1 :(得分:1)

分段错误,是指您尝试访问未分配给您的变量的位置。常见情况超出了数组边界或尝试访问未分配的动态变量。您必须区分此方案和虚拟内存。系统强制执行此操作以防止程序破坏自己的数据或系统上运行的其他程序的数据;甚至更糟糕的是破坏了系统本身的数据。想一想。

虚拟内存只是意味着可以为物理RAM分配更多内存。这并不意味着您可以在不首先请求它的情况下访问这样的空间。

答案 2 :(得分:1)

分段错误通常是由于进程尝试访问为另一个进程分配的内存而引起的。 每个进程都分配“虚拟空间”映射到一个物理地址,使用TLB / Page表等进行翻译。

现在,如果应用程序级别程序尝试使用未分配给它的内存,由于程序中的错误,则会一直指向地址转换。

例如:想象一下堆栈已被编码。现在,如果堆栈溢出条件未经测试,则执行此代码,地址转换指的是程序地址空间之外的地址,这会导致分段错误。

答案 3 :(得分:0)

在使用硬件内存分段提供虚拟内存的系统上,当硬件检测到尝试引用不存在的段,或引用段的边界之外的位置或引用时,会发生分段错误以该方式授予的权限不允许的位置。在仅使用分页的系统上,无效页面故障通常会导致分段故障,分段故障和页面故障都是虚拟内存管理系统引发的故障。分段错误也可以独立于页面错误发生:非法访问有效页面是一个分段错误,但不是无效的页面错误,并且分页错误可能发生在页面中间(因此没有页面错误),例如在缓冲区溢出停留在页面内但非法覆盖内存。来自https://en.wikipedia.org/wiki/Segmentation_fault

答案 4 :(得分:0)

好吧,您拥有整个地址空间,这意味着您可以拥有尽可能多的内存。但是,您必须先要求它。也许您可以分配自己的整个地址空间,然后尝试访问所有内存,但不会出现段错误。但是,当您尝试访问尚未请求的内存之外时,就会遇到分段错误。