且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

_chkstk() 函数的目的是什么?

更新时间:2022-06-12 04:31:19

Windows 页面在额外堆栈***您的线程使用.在堆栈的末尾,有一个保护页被映射为不可访问的内存——如果程序访问它(因为它试图使用比当前映射更多的堆栈),就会出现访问冲突.操作系统捕获错误,映射到与旧保护页相同地址的另一堆栈页中,在旧保护页之后创建一个新的保护页,然后从导致违规的指令恢复.

Windows pages in extra stack for your thread as it is used. At the end of the stack, there is one guard page mapped as inaccessible memory -- if the program accesses it (because it is trying to use more stack than is currently mapped), there's an access violation. The OS catches the fault, maps in another page of stack at the same address as the old guard page, creates a new guard page just beyond the old one, and resumes from the instruction that caused the violation.

如果一个函数有不止一页的局部变量,那么它访问的第一个地址可能会超过当前栈尾的一页.因此,它会错过保护页面并触发操作系统没有意识到的访问冲突,因为需要更多堆栈.如果所需的总堆栈特别大,它甚至可能超出保护页,超出分配给堆栈的虚拟地址空间的末尾,并进入实际用于其他用途的内存.

If a function has more than one page of local variables, then the first address it accesses might be more than one page beyond the current end of the stack. Hence it would miss the guard page and trigger an access violation that the OS doesn't realise is because more stack is needed. If the total stack required is particularly huge, it could perhaps even reach beyond the guard page, beyond the end of the virtual address space assigned to stack, and into memory that's actually in use for something else.

因此,_chkstk 确保有足够的空间用于局部变量.您可以想象它通过以页面大小的间隔按递增顺序接触局部变量的内存来实现这一点,以确保它不会错过保护页面(所谓的堆栈探测").我不知道它是否真的这样做了,不过,它可能需要更直接的路由并指示操作系统映射到一定数量的堆栈中.无论哪种方式,如果所需的总数大于堆栈可用的虚拟地址空间,那么操作系统可以抱怨它而不是做一些未定义的事情.

So, _chkstk ensures that there is enough space for the local variables. You can imagine that it does this by touching the memory for the local variables at page-sized intervals, in increasing order, to ensure that it doesn't miss the guard page (so-called "stack probes"). I don't know whether it actually does that, though, possibly it takes a more direct route and instructs the OS to map in a certain amount of stack. Either way, if the total required is greater than the virtual address space available for stack, then the OS can complain about it instead of doing something undefined.