为什么最大堆栈深度不断变化? [英] Why is max stack depth keeping changing?

查看:48
本文介绍了为什么最大堆栈深度不断变化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于以下代码,最后一个输出(最大堆栈深度不断变化):

For following code, the last output (which is max stack depth is keeping changing):

#include <stdio.h>
#include <windows.h>

int depth=0;

void func(){
    int x=depth;
    printf("%d\n",depth++);
    func();  
    printf("%d\n",x);
}

int main(){
    func();
    return 0;
}

//由cl/F 1 test.c

第一次是3717,第二次是3700,第三次是3695.

The first time is 3717, the second is 3700, the third is 3695.

我认为对于恒定的堆栈大小,最大堆栈深度应该是恒定的.但为什么会改变?

I thought for constant stack size, max stack depth should be constant. but why is it changing?

推荐答案

在运行 x86/x64 CPU 的 Microsoft Windows 平台上,为堆栈保留的内存总是以 页面 边界和 堆栈溢出 当堆栈增长超出该页面边界时将发生.一个页面通常是 4096 字节的内存.

On the Microsoft Windows platform running x86/x64 CPUs, the memory reserved for the stack always ends on a page boundary and a stack overflow will occur when the stack grows beyond that page boundary. A page is normally 4096 bytes of memory.

如果没有地址空间布局随机化 (ASLR),堆栈也会从一个页面开始边界,这意味着最大堆栈大小将是页面大小的倍数.默认情况下,堆栈的最大大小为 1 MiB,即 4096 字节的 256 页.

Without Address Space Layout Randomization (ASLR), the stack will also start at a page boundary, which means the maximum stack size will be a multiple of the page size. By default, the stack has a maximum size of 1 MiB, which is 256 pages of 4096 bytes.

然而,当 ASLR 处于活动状态时,堆栈的起始地址不再位于页面边界上,而是随机的.由于为堆栈保留的内存仍以页面边界结束,这意味着最大堆栈大小是随机的,不再是页面大小的倍数.

However, with ASLR active, the starting address of the stack is no longer on a page boundary, but is random. Since the memory reserved for the stack still ends on a page boundary, this means that the maximum stack size is random and is no longer a multiple of the page size.

最大堆栈大小的这种随机性是堆栈溢出的时间也是随机的原因.

This randomness of the maximum stack size is the reason why the time of the stack overflow is also random.

Microsoft 链接器在默认情况下启用 ASLR 构建可执行文件.为了禁用 ASLR,您必须在调用链接器时添加 /DYNAMICBASE:NO 选项.之后,无论何时运行程序,堆栈溢出都应该在完全相同的时间发生.

The Microsoft linker builds executable files with ASLR enabled by default. In order to disable ASLR, you must add the /DYNAMICBASE:NO option when invoking the linker. Afterwards, the stack overflow should occur at exactly the same time whenever you run your program.

这篇关于为什么最大堆栈深度不断变化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆