setrlimit用于限制进程资源使用,其中RLIMIT_STACK是限制栈大小的。
若栈大小超过了限制的大小,则进程会崩溃。
下面代码,设置栈大小为1024字节,然后后面又定义了2 * 1024的数组,并在print也定义了2 * 1024的数组,但是程序并没有崩溃。
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUF_LEN 2 * 1024
void print(){
printf("enter print function\n");
int i;
int length = BUF_LEN;
char szBuf[BUF_LEN];
for(i = 0; i < length; i++)
{
szBuf[i] = i;
}
}
int main()
{
struct rlimit rlimit;
int ret = 0;
int i = 0;
int stackSize = 1 * 1024;
printf("hello world\n");
ret = getrlimit(RLIMIT_STACK, &rlimit);
if(ret < 0)
{
printf("getrlimit failed\n");
return -1;
}
rlimit.rlim_cur = stackSize;
rlimit.rlim_max = stackSize;
ret = setrlimit(RLIMIT_STACK, &rlimit);
if(ret < 0)
{
printf("setrlimit failed\n");
return -1;
}
printf("setrlimit succeed\n");
char szBuf[BUF_LEN];
int length = BUF_LEN;
for(i = 0; i < length; i++)
{
szBuf[i] = i;
}
printf("print\n");
print();
while(1);
return 0;
}
通过/proc/pid/limits可以看到设置是成功的,但是程序并未崩溃。
后面将BUF_LEN改成2 * 1024 * 1024,stackSize设置为1 * 1024 * 1024。
运行结果为:
可以看到进程崩溃了,但是可以看其打印,print是打印出来的,而在print函数调用前面,有个char szBuf[BUF_LEN]的栈变量。这说明崩溃的时候,是在调用print时崩溃的(调用print时,首先会进行栈检查)。不是在main函数里面崩溃的。
其实设置RLIMIT_STACK,并不能修改当前函数调用栈帧的限制。main函数栈帧的限制在编译的时候就确定了,是8M。其生效是在后面的函数调用生成的栈帧中生效。故main函数中设置的栈大小为1M,在后面的函数print中生效。而print函数中定义了2M大小的栈变量szBuf,在main函数真正调用print时,会先进行栈限制检查。很明显未通过检查,崩溃。