1

为什么后面的程序可以写超出当前程序中断?

int main()
{
    sbrk(4095);

    void *addr = sbrk(0);
    printf("%p\n", addr);

    *(char*)(addr) = 'a';

    return 0;
}

如果将 4095 更改为 4096,则将按预期发生 seg fault。但是4095效果很好。我几乎可以肯定这与页面大小(在我的系统上为 4096)有关。我的猜测是,在 4095 的情况下,sbrk调用将整个页面设置为可映射,以便在写入发生在该页面的最后一个字节时成功映射该页面。

但是为什么允许写入(它超出了当前的程序中断)?有人可以给出更详细的解释吗?

4

1 回答 1

2

正如 Basile Starynkevitch 在第一条评论中指出的那样,这是一个硬件限制:“中断”以页面为单位移动。

即使在原始(基于交换的)PDP-11 Unix 系统上也是如此,其中硬件保护单元是 8192 字节的“页面”(不是按需分页的页面,而是仍然页面)。

尽管如此,该接口以字节为单位工作。如果您将中断调整到页面中间,然后一次将其向前移动一个字节,则系统调用基本上是一个昂贵的空操作,直到您进入下一页,此时它映射该页面。即使在最初的 PDP-11 系统上也是如此,今天没有特别的理由禁止它。

于 2013-09-03T08:26:55.027 回答