为啥在 Linux 上 fork 或 exec 后 RLIMIT_STACK 丢失?

Posted

技术标签:

【中文标题】为啥在 Linux 上 fork 或 exec 后 RLIMIT_STACK 丢失?【英文标题】:Why is RLIMIT_STACK lost after fork or exec on linux?为什么在 Linux 上 fork 或 exec 后 RLIMIT_STACK 丢失? 【发布时间】:2010-03-01 02:43:25 【问题描述】:

在linux上,据说进程的rlimit在fork或exec之后保持不变。但是在 fork 或 exec 之后,我在孩子身上丢失了我的 RLIMIT_STACK。有人能解释一下吗? 这是我的程序的一些描述性输出。

//父级有这样的RLIMIT_STACK

RLIMIT_STACK,软 - 10485760,硬 - -1

//fork 之后,child 丢失了它的 RLIMIT_STACK

在 fork 后的子项中,RLIMIT_STACK,软 - -1,硬 - -1

//在child中,在exec之前,RLIMIT_STACK soft再次设置为10485760

RLIMIT_STACK 设置正常。

设置后在子级中,RLIMIT_STACK,软 - 10485760,硬 - -1 子 pid = 3096

//exec之后,新进程又丢失了它的RLIMIT_STACK

RLIMIT_STACK 得到,软 - -1,硬 - -1

提前致谢 冯

【问题讨论】:

什么版本和平台? RLIMIT_STACK 行为在 2.6.23 和 2.6.25 中发生了变化。 该应用程序是在 2.4.20-18.7smp i686 平台上编译为 32 位的。它是在上面发布的平台上运行的。只有在这种情况下,问题才会出现。在64位平台上编译运行正常没有这个问题,在32位平台上编译也可以正常运行。 尝试在Stack *** 修正后设置rlimit_stack 可能会导致失败或相关问题。另请参阅红帽 Issue 1463241 【参考方案1】:

这似乎是 libpthread 的 linuxthread 实现的一个问题(我不确定它是否是一个错误)。 我写了一个简单的程序:

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char **argv)
struct rlimit resource_limit;
if(getrlimit(RLIMIT_STACK, &resource_limit) != 0)
    fprintf(stderr, "Failed to get rlimit: %s\n", strerror(errno));
    return 1;

else
    fprintf(stderr, "In parent, RLIMIT_STACK, soft-%d, hard-%d\n",
            resource_limit.rlim_cur, resource_limit.rlim_max);


int child_status = 0;
pid_t pid = fork();
switch(pid)
    case 0://child
        if(getrlimit(RLIMIT_STACK, &resource_limit) != 0)
            fprintf(stderr, "Failed to get rlimit: %s\n", strerror(errno));
            return 1;
        
        else
            fprintf(stderr, "In child after fork, RLIMIT_STACK, soft-%d, hard-%d\n",
                    resource_limit.rlim_cur, resource_limit.rlim_max);
        
        break;
    case -1:
        fprintf(stderr, "Fork error: %s\n", strerror(errno));
        break;
    default://parent
        waitpid(pid, &child_status, 0);
        break;

return 0;

如果这个程序在没有 -lpthread 选项的情况下编译和链接,它在任何地方都可以正常运行。但是当它与 -lpthread 选项链接时,会发生连线的事情:如果它在动态链接到 libpthread 的 linuxthread 版本的机器上运行,它会给出:

In parent, RLIMIT_STACK, soft-10485760, hard--1
In child after fork, RLIMIT_STACK, soft--1, hard--1

但是当它在动态链接到 libpthread 的 NPTL 版本的机器上运行时,它会给出预期的结果:

In parent, RLIMIT_STACK, soft-10485760, hard--1
In child after fork, RLIMIT_STACK, soft-10485760, hard--1

【讨论】:

以上是关于为啥在 Linux 上 fork 或 exec 后 RLIMIT_STACK 丢失?的主要内容,如果未能解决你的问题,请参考以下文章

linux中fork,source和exec的区别

linux中fork,source和exec的区别

linux中fork, source和exec的区别

Linux中的进程 --fork,exec,守护进程分析

Linux信号量,在forked->exec'd进程之间共享?

Linux下进程的创建(system(); fork(); exec*())