栈溢出

问题源于这次招聘试题,其中有个同事故意在试题出了两道关于栈溢出,分别如下:

void main()
{
int a = 9;
int b = a & 8;
int c[1];
int i;
for(i = 0; i < 2; i ++)
{
c[i] = i*i + i;
}
printf("%d %d %d",a,b,c[0]);
}

void why()
{
printf("Hello!");
exit(0);
}

void func(int b)
{
int array[1];
array[2] = (int)why;
}

int main()
{
func(1);
printf("World!");
return 0;
}

看到这两个题目,我的直觉告诉我,运行时肯定会报错。但是看到答案后,既然是可以正常运行。

1、在vs2005(缺省配置)上运行,确实如我所想出现“栈破环”提示。

2、在vc6.0上运行,确实没有任何错误提示。

并且在两个环境上输出的结果也不一样。

经过Debug跟踪,可以看到在vs2005下,&b - &a = 12 byte,而在vc6.0下只有4个字节,显然,按正常思维来看,应该是4个字节没错,但是为什么在vs2005下会是12字节呢?

  经过分析,原来是vs2005为了精准的定位栈溢出及其位置,会像函数堆栈那样添加安全的cookie,所以就会出现上面的多出8个字节。

vs2005下引入了两个编译选项,在这两个编译选项的作用下生成的可执行文件包含了对堆栈溢出的相关检查,由此报错。

一、一个编译选项是/GS选项,实现的是像函数堆栈中添加安全cookie

二、另一个编译选项是基本运行时检查。其关闭方法如下截图。

在关闭了Basic Runtime checks 之后,运行结果跟vc6.0就完全一致,可见不一致的结果完全是因为vs2005下有堆栈溢出的检查机制导致的。

原文地址:https://www.cnblogs.com/coderyoyo/p/stack_overflow.html