5

导致堆栈溢出和获取的一种明显方法Segmentation fault是递归地将堆栈帧推到彼此之上,直到它繁荣为止。我想知道是否会在不推送新的堆栈帧的情况下发生堆栈溢出。

根据经验,创建一个足够大的阵列也可以做到这一点,但还有其他可能的情况吗?

4

4 回答 4

3

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函数族,只是它通过调整堆栈指针在堆栈上分配内存。

于 2012-04-11T09:28:10.633 回答
1

滥用alloca()或者_alloca()如果您在 Windows SDK/VS 上开发:

alloca() 函数在调用者的堆栈帧中分配 size 个字节的空间。

Note_alloca()现在已弃用,取而代之的是_malloca().

于 2012-04-11T09:11:54.110 回答
1

从根本上说,“堆栈”只是一些内存,而堆栈溢出是当 ESP / EBP 超出该内存的范围时。

您可以通过多种方式完成此操作:

  1. 创建一个巨大的堆栈分配数组,该数组大于剩余堆栈空间的大小:int x[10000000];
  2. 直接设置ESP:__asm mov esp, 0x0
  3. 破坏堆栈,因此当当前函数展开时,ESP/EBP 将被设置为垃圾:int x; memset(&x, 0, 10000000);

还有无数其他方式...

于 2012-04-11T09:16:31.793 回答
1

通过声明和使用大于堆栈大小的数组:

$ ulimit -s
8192
$

然后

int main(void)
{
    volatile char bla[8192 * 1024 + 16] = {0};
}

执行时可能会出现段错误。

于 2012-04-11T09:20:37.910 回答