发布于2026-07-15 阅读(0)
扫一扫,手机访问
之前在不同架构上的编译器如何执行堆栈探测的讨论中,有读者提出了一个有意思的问题:为什么不直接用页面错误处理程序来检测其他页面中的堆栈和页面的错误地址?
另一位同行 Csaba Varga 给出了一个很到位的判断:问题在于,你并不希望因为一个无效指针的偶然指向,就触发整个堆栈的分配——毕竟,那个指针说不定恰好指到了堆栈可能增长的位置。大多数时候,我们期望无效指针的解引用直接导致段错误,而不是悄无声息地触发一大块内存分配。
这个观点很值得认同。
试想一下,假如整个堆栈都由保护页构成,那么一个远低于堆栈限制的页面错误,就可能耗费难以预估的时间,并且分配出任意大的内存。程序可能声明它希望堆栈默认为 1GB,结果堆栈上一个单页面错误,系统就不得不花上几分钟去分配这 1GB 内存。如果你在调试器中追踪这个问题,你会发现单次内存读取竟然需要几分钟才能完成。
更糟糕的是,这个过程发生在内核模式下,你根本没法阻止它。你眼睁睁看着程序开始膨胀,吞噬系统内存,于是到任务管理器里终止它——但进程压根儿没停。它还在继续膨胀!
反过来看,如果保护页只有一页(或少量固定页面),系统就能在很短时间内处理保护页错误,工作量是受控的。
这篇博客的作者 Raymond 在 Windows 领域深耕超过 30 年。2003 年,他创建了“The Old New Thing”网站,其受欢迎程度远超他的预期,至今仍让他感慨。该网站后来催生了一本同名书籍(Addison Wesley 2007)。他偶尔会出现在 Windows 开发文档的 Twitter 账号上,讲述一些“没什么用”的小故事。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8