我最近使用了/FAsu
Visual C++ compiler option输出一个特别长的成员函数定义的源+程序集。在汇编输出中,堆栈帧建立后,有一个神秘的_chkstk()
函数调用。
_chkstk()
上的 MSDN 页面没有解释调用这个函数的原因。我还看到了 Stack Overflow 问题 Allocating a buffer of more a page size on stack will corrupt memory? ,但我不明白 OP 和接受的答案在说什么。
_chkstk()
CRT 函数的用途是什么?它有什么作用?
最佳答案
Windows 页面在使用时为您的线程提供额外堆栈。在堆栈的末尾,有一个保护页面被映射为不可访问的内存——如果程序访问它(因为它试图使用比当前映射的更多的堆栈),则存在访问冲突。操作系统捕捉到错误,将堆栈的另一页映射到与旧保护页相同的地址,在旧保护页之外创建一个新保护页,并从导致违规的指令恢复。
如果一个函数有不止一页的局部变量,那么它访问的第一个地址可能比当前堆栈末尾多一页。因此它会错过保护页面并触发操作系统没有意识到的访问冲突,因为需要更多的堆栈。如果所需的总堆栈特别大,它甚至可能超出保护页,超出分配给堆栈的虚拟地址空间的末尾,并进入实际用于其他用途的内存。
因此,_chkstk
确保有足够的空间用于局部变量。您可以想象它通过按页面大小的间隔按递增顺序触摸局部变量的内存来做到这一点,以确保它不会错过保护页面(所谓的“堆栈探测器”)。我不知道它是否真的这样做,但可能它需要更直接的路线并指示操作系统映射到一定数量的堆栈。无论哪种方式,如果所需的总数大于堆栈可用的虚拟地址空间,那么操作系统可以提示它而不是做一些未定义的事情。
关于c++ - _chkstk() 函数的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8400118/