【发布时间】:2022-01-10 18:08:57
【问题描述】:
我很好奇内核如何防止堆栈变得太大,我发现this Q/A:
问:Linux 内核如何强制堆栈大小限制?
A:由于虚拟内存,内核可以控制这一点。虚拟的 内存(也称为内存映射),基本上是一个虚拟列表 内存区域(基数 + 大小)和目标物理内存区域 内核可以操作每个程序所独有的。当一个 程序尝试访问不在此列表中的地址, 发生异常。此异常将导致上下文切换到 内核模式。内核可以查找故障。如果记忆是 生效,它将在程序可以之前就位 继续(例如,尚未从磁盘读取交换和 mmap)或 可以生成 SEGFAULT。
为了决定堆栈大小限制,内核简单地操作 虚拟内存映射。 - Stian Skjelstad
但我对这个答案不太满意。 “当程序试图访问不在此列表中的地址时,就会发生异常。” - 但是程序的文本部分(指令)不是虚拟内存映射的一部分吗?
【问题讨论】:
-
作为一个关于术语的小问题:当我说“文本部分”时,它的字面意思是“来自基本程序指令的机器代码”,对吧?这是否包括来自共享内存(库)的代码,因为它们是由运行时链接器映射的?
-
.text部分在普通用户空间进程中被映射为只读。并且在虚拟地址空间的另一端,因此在发生堆栈冲突之前有很多未使用的页面。 (其中一些页面故意未映射为堆栈增长区域下方的保护页面)。有关堆栈增长限制和其他内容的更多信息,请参阅 Linux process stack overrun by local variables (stack guarding)。 -
问题是关于内核(例如中断堆栈)还是关于用户程序?在任何情况下,内核都可以设置堆栈的限制(堆栈在 SS 段中,因此您可以设置不同的限制)。如果你超出限制,你会得到一个错误(或双重错误)
-
你标记了这个 [linux-kernel];您是在谈论内核自己的堆栈吗? (实际上它使用每个任务的内核堆栈,至少用一个保护页分隔)。
-
@GiacomoCatenazzi:x86 Linux 不使用 SS 段限制,它使用分页。在长模式下,SS 段限制是硬连线到无限制,因为操作系统没有使用它,所以没有必要找到将其扩展到 64 位的方法。
标签: linux-kernel x86 stack-overflow stack-memory