关于setrlimit RLIMIT_STACK的一点说明
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 * 1024void 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时,会先进行栈限制检查。很明显未通过检查,崩溃。