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

进程内存布局

4064394-572f552615dbbf72.png
image.png

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

linux查看栈上限方法

  • linux可以通过ulimit命令查看栈上限和设置上限
ulimit -a 查看进程所有资源上限
ulimit -s xx 修改栈上限
  • 也可以通过程序中调用函数修改
    每个进程都有一组资源限制,其中一些可以用getrlimit和setrlimit函 数查询和更改。
#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系统实现 支持的。


4064394-381ab496c6ebb711.png
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;
}
4064394-0f1c73dc90e0d857.png
image.png

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

gcc -Wl,--stack=size

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值