0%

C 默认栈大小不足导致 SIGSEGV 的问题

环境:Ubuntu 20.04

代码很简单,在 main 函数里面定义一个长度为 1024K 的数组(一个 int 占 4 个字节):

1
2
3
4
int main()
{
int a[1024 * 1024 / 4] = {};
}

然后编译执行:

1
2
3
4
$ gcc main.cpp 
$ ./a.out

Segmentation fault (core dumped)

原因

为了保护操作系统,防止无限递归这种错误导致内存被耗光,系统对程序的栈大小有一个默认值的限制。

参考:https://stackoverflow.com/questions/1825964/c-c-maximum-stack-size-of-program

实际的限制可以使用 ulimit -s 来查看。

在我本机上,其实是先执行了 ulimit -s 1024 将栈大小限制为 1024K 了,然后我的数组就用了 1024K,另外还有函数调用本身需要保存一些信息(比如返回地址等),所以就超过了 1024K,也就是超出了栈的大小了。

解决方法

有一个解决方法是,将 ulimit -s 的值增大,比如,设置成 8M:

1
ulimit -s 8192

然后重新执行 ./a.out

1
$ ./a.out

再次执行就没有报错了,因为我的栈空间足够大了。

启发

之前使用 swoole 的时候,有时候有 SIGSEGV 这种错误,现在看来或许是有什么地方超出了栈的大小了。