深入理解计算机系统

[c/c++]3.如何查看和更改程序运行栈的大小

2020-02-15  本文已影响0人  MachinePlay

进程内存布局

image.png

我们写程序运行栈的栈帧保存在栈区,函数调用深度太多将导致爆栈
栈的大小有上限,每个进程可以指定软上限,操作系统可指定硬上限

linux查看栈上限方法

ulimit -a 查看进程所有资源上限
ulimit -s xx 修改栈上限
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlptr);
int setrlimit(int resource, const struct rlimit *rlptr);

两个函数返回值:若成功,返回0;若出错,返回非0
这两个函数在Single UNIX Specification的XSI扩展中定义。进程 的资源限制通常是在系统初始化时由0进程建立的,然后由后续进程继 承。每种实现都可以用自己的方法对资源限制做出调整。

对这两个函数的每一次调用都指定一个资源以及一个指向下列结构 的指针。

struct rlimit {
rlim_t rlim_cur; /* soft limit: current limit */
rlim_t rlim_max; /* hard limit: maximum value for rlim_cur */ };

在更改资源限制时,须遵循下列3条规则。
(1)任何一个进程都可将一个软限制值更改为小于或等于其硬限 制值。
(2)任何一个进程都可降低其硬限制值,但它必须大于或等于其 软限制值。这种降低,对普通用户而言是不可逆的。
(3)只有超级用户进程可以提高硬限制值。

常量RLIM_INFINITY指定了一个无限量的限制。
这两个函数的 resource 参数取下列值之一。图 7-15 显示哪些资源限 制是由 Single UNIX Specification定义并由本书讨论的4种UNIX系统实现 支持的。


image.png
RLIMIT_AS 进程总的可用存储空间的最大长度(字节)。这影响 到 sbrk 函数(1.11节)和mmap函数(14.8节)。

RLIMIT_CORE core文件的最大字节数,若其值为0则阻止创建core 文件。

RLIMIT_CPU CPU时间的最大量值(秒),当超过此软限制时,向 该进程发送SIGXCPU信号。

RLIMIT_DATA 数据段的最大字节长度。这是始化数据、非初始以及堆的总和。

RLIMIT_FSIZE 可以创建的文件的最大字节长度。当超过此软限制时,则向该进程发送SIGXFSZ信号。

RLIMIT_MEMLOCK 一个进程使用mlock(2)能够锁定在存储空间中
的最大字节长度。

RLIMIT_MSGQUEUE 进程为POSIX消息队列可分配的最大存储字
节数。

RLIMIT_NICE 为了影响进程的调度优先级,nice值(8.16节)可设
置的最大限制。

RLIMIT_NOFILE 每个进程能打开的最多文件数。

RLIMIT_NPROC 每个实际用户 ID 可拥有的最大子进程数。更改此 限制将影响到sysconf函数在参数_SC_CHILD_MAX中返回的值(见2.5.4 节)。

RLIMIT_SWAP 用户可消耗的交换空间的最大字节数 

RLIMIT_VMEM 这是RLIMIT_AS的同义词。

资源限制影响到调用进程并由其子进程继承。这就意味着,为了影
响一个用户的所有后续进程,需将资源限制的设置构造在shell之中。确 实,Bourne shell、GNU Bourne-again shell和Korn shell具有内置的ulimit命令,C shell具有内置limit命令。(umask和chdir函数也必须是shell内置 的。)

打印由系统支持的所有资源当前的软限制和硬限制。 为了在各种实现上编译该程序,我们已经条件地包括了各种不同的资源 名。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>

rlimit my_rlimit;

int main() {
    /*----------------------------------- get cpu rlimit ----------------------------------------*/
    int ret = getrlimit(RLIMIT_CPU, &my_rlimit);
    printf("cpu   rlimit: (%llu)  (%llu)\n", my_rlimit.rlim_cur, my_rlimit.rlim_max);
    
    /*----------------------------------- get nire rlimit ----------------------------------------*/
    ret = getrlimit(RLIMIT_AS, &my_rlimit);
    printf("AS    rlimit: (%llu)  (%llu)\n", my_rlimit.rlim_cur, my_rlimit.rlim_max);

    /*----------------------------------- get stack rlimit ----------------------------------------*/
    ret = getrlimit(RLIMIT_STACK, &my_rlimit);
    printf("stack rlimit: (%llu)  (%llu)\n", my_rlimit.rlim_cur, my_rlimit.rlim_max);

    return 0;
}
image.png

windows可以在编译前指定gcc 参数,修改默认栈大小

gcc -Wl,--stack=size

上一篇下一篇

猜你喜欢

热点阅读