导致堆栈溢出的一个显而易见的方式是获得Segmentation fault
,将递归地将堆栈帧叠加到彼此的顶部,直到它繁荣。我想知道如果堆栈溢出可能发生,甚至没有推动新的堆栈帧。如何溢出堆栈而不推送新的堆栈帧?
创建一个足够大的阵列也可以从经验中做到,但是还有其他可能的场景吗?
导致堆栈溢出的一个显而易见的方式是获得Segmentation fault
,将递归地将堆栈帧叠加到彼此的顶部,直到它繁荣。我想知道如果堆栈溢出可能发生,甚至没有推动新的堆栈帧。如何溢出堆栈而不推送新的堆栈帧?
创建一个足够大的阵列也可以从经验中做到,但是还有其他可能的场景吗?
C99使用可调整大小的数组,您可以使用它并将其调整为较大的数组。然而,这个可调整大小的阵列使用alloca
来实现。下面是UNIX ENV一个示例代码:
#include <stdio.h>
#include <alloca.h>
#include <stdlib.h>
#include <stdbool.h>
int
main()
{
while (true)
{
void *p = alloca(32UL);
printf("new memory allocated at %p \n", p);
}
exit(EXIT_SUCCESS);
}
而且你的输出看起来就像这样
new memory allocated at 0xbf800a60
new memory allocated at 0xbf800a30
new memory allocated at 0xbf800a00
new memory allocated at 0xbf8009d0
new memory allocated at 0xbf8009a0
[1] 3977 segmentation fault ./a.out
alloca
是在malloc
家庭的功能,但它通过调整栈上分配的内存堆栈指针。
滥用alloca()
或_alloca()
如果你正在开发的Windows SDK/VS:
的ALLOCA()函数分配的空间大小字节在 调用者的堆栈帧。
注意_alloca()
现在被弃用,有利于_malloca()
。
从根本上说,“堆栈”只是一些内存,当ESP/EBP超出这个内存的界限时,堆栈溢出。
int x[10000000];
__asm mov esp, 0x0
您可以通过多种方式实现这一点破坏堆栈,因此当当前函数展开时,ESP/EBP将被设置为垃圾:int x; memset(&x, 0, 10000000);
And coun tless其他方式...
通过声明和使用数组比你的堆栈大小:
$ ulimit -s
8192
$
然后
int main(void)
{
volatile char bla[8192 * 1024 + 16] = {0};
}
很可能在执行时出现段错误。
为什么输入volatile?在我的示例中为 – 2012-04-11 09:30:22
,以避免编译器优化它,因为它不在程序中的其他地方使用。如果你使用'printf'打印'for'循环来打印所有元素,那么你不需要'volatile'限定符,因为编译器无法优化它。 – ouah 2012-04-11 09:32:17
这将在Linux/UNIX环境中。 – 2012-04-11 09:08:09
'alloca'和VLA。 – Mat 2012-04-11 09:09:07