操作系统如何检测堆栈溢出?

在许多操作系统上,堆栈和堆开始于进程的虚拟地址空间的相反侧,并朝向彼此增长。 这样可以在不碰堆的情况下尽可能扩展堆栈。

假设我有一个导致堆栈溢出的程序。 我目前的理解是,这会导致堆栈无法控制地朝着堆堆增长并最终击中它。 它是否正确? 如果是,那么操作系统如何检测堆栈溢出? 似乎操作系统无法检测到程序试图使用分配给堆的虚拟内存作为堆栈的一部分,因为它们将处于连续的内存区域中。

我知道这是特定于操作系统的,但是对于在任何操作系统中发生这种情况的机制的洞察肯定会有所帮助。 这一直困扰我一段时间,我似乎无法找到任何好的解释。


OS为堆栈分配一些空间。 当进程访问堆栈的未分配部分时,处理器会引发页面错误,并被操作系统捕获。 如果操作系统认为堆栈增长仍然合理,它只需为其分配新的空间并将控制权返回给进程。 如果不合理,则会引发堆栈溢出异常。


这只是直觉,但要确保堆栈不会干扰堆的声音,就像JVM的工作。 我没有看到为什么我无法制作自己可怕的编程语言,因为我让堆栈开始覆盖堆(在崩溃之前)。


堆栈溢出在堆栈中倒退 - 它们通过覆盖已经初始化的堆栈中的数据来工作,这可能正是因为堆栈向下增长。

因此,操作系统无法检测到这种情况,因为该进程可以随时修改其堆栈的初始化部分。

使用堆栈空间扩展堆栈工作,而操作系统陷入页面错误处理程序,因为没有设置页面。 一些操作系统允许这些访问仅在“保护页面”上进行,即紧接在当前堆栈触发重新分配之前的页面,其他操作系统则在故障发生时查看堆栈指针寄存器的内容,以查看这是否应该是堆栈访问。

链接地址: http://www.djcxy.com/p/80445.html

上一篇: How does the operating system detect a stack overflow?

下一篇: How come Go doesn't have stackoverflows