为什么我们从不直接用保护页来构建整个堆栈 - 旧事新事

作者:袖梨 2026-07-15

在我之前对不同架构上的编译器如何执行堆栈探测的概述中,Cole Tobin 问道:“为什么不使用一个页面错误处理程序来检测其他页面中的堆栈和页面的错误地址?”

Csaba Varga 回答道:“我的猜测是:你不希望通过无效的指针取消引用来分配一大块堆栈,因为指针最终恰好指向堆栈可能增长的位置。大多数时候,你希望无效的指针取消引用导致段错误。”

我同意 Csaba 的观点。

如果整个堆栈由保护页组成,则意味着远低于堆栈限制的单个页面错误可能会花费任意长的时间并分配任意大量的内存。程序可能会说它希望堆栈默认为 1GB,现在堆栈上的单个页面错误可能会导致系统分配 1GB 内存时长时间暂停。如果您在调试器中研究该问题,您会发现单个内存读取需要几分钟的时间。

更糟糕的是,没有办法阻止它,因为它发生在内核模式下。您看到一个程序开始膨胀并消耗系统中的所有内存,因此您转到任务管理器并终止它,但该进程并没有终止。它只是不断增长!

即使保护页超过一页,但它仍然是少量固定数量的页面,系统可以在短时间内满足保护页错误。更重要的是,工作量是有限的。

类别

  • 老新事物

Raymond 参与 Windows 的发展已超过 30 年。 2003 年,他创建了一个名为“The Old New Thing”的网站,该网站的受欢迎程度远远超出了他最疯狂的想象,这一发展至今仍让他心惊胆战。该网站催生了一本书,巧合的是,它的标题也是《旧的新事物》(Addison Wesley 2007)。他偶尔会出现在 Windows 开发文档 Twitter 帐户上,讲述一些没有传达任何有用信息的故事。

相关文章

精彩推荐