在 x86-32/x86-64 架构的 Windows 操作系统上,线程堆栈虚拟内存由“保留部分”、“提交部分”、“保护页”和“保留页”组成。
问题:
想象一下,我有 1 页提交内存和 1MB 线程堆栈保留内存。
我在堆栈上分配了一些等于 K 页的内存,但没有初始化。对于示例 10,K 相等。似乎在堆栈帧的开头,堆栈上的内存将由用户空间代码分配,如下所示:
sub esp, K*4096
当存在对保护页的读|写请求时,保护页机制起作用。
但是我将对超出此保护页的某些内存执行读/写操作,该怎么办?
您通常会开始测试在启用运行时检查的情况下编译的代码。/MSVC++ 上的 RTC,在调试配置中默认启用,它会在函数序言中注入对 _chkstk() 的调用。 GCC/g++ 有非常相似的东西.
它探测函数序言中分配的页面,每隔 4096 个字节读取一次。这可以确保您在出错时始终会点击防护页面,触发该站点的名称并帮助您修复错误。
如果没有进行该检查,从技术上讲,您可以寻址根本不属于堆栈的页面。尽管它很可能会触发处理器的#GP 陷阱,但不能保证它会发生,因为该页面可能已被另一个不相关的分配映射。你一定很不幸,事情已经完成了。基本的 UB,诊断起来绝对很糟糕,因为你从不怀疑堆栈,/RTC 非常有价值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)