3
votes

On linux, it is said that rlimit of a process is kept intact after either fork or exec. But I lose my RLIMIT_STACK in the child either after fork or after exec. Would someone please give some explain?

Here is some descriptive output of my program.

//The parent has an RLIMIT_STACK like this

RLIMIT_STACK, soft - 10485760, hard - -1

//Right after fork, the child loses its RLIMIT_STACK

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

//In the child, before exec, RLIMIT_STACK soft is set to 10485760 again

RLIMIT_STACK set OK.

In child after set, RLIMIT_STACK, soft - 10485760, hard - -1 Child pid = 3096

//After exec, the new process loses its RLIMIT_STACK again

RLIMIT_STACK got, soft - -1, hard - -1

Thanks in advance
Feng

1
What version and platform? RLIMIT_STACK behavior changed in 2.6.23 and 2.6.25. - Ignacio Vazquez-Abrams
The app was compiled on a 2.4.20-18.7smp i686 platform as a 32-bit one. And it was run on the platform posted above. Only under this circumstance does the problem show. It runs OK without this problem if it is compiled on the 64-bit platform where it is to run, also it runs OK on the 32-bit platform if it is compiled there. - Utoah
Attempting to set rlimit_stack after Stack Clash remediations may result in failure or related problems. Also see Red Hat Issue 1463241 - jww

1 Answers

1
votes

This seems a problem(I am not sure if it is a bug) of linuxthread implementation of libpthread.
I wrote a simple program:

#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;

}


If this program is compiled and linked without -lpthread option, it runs OK everywhere. But when it is linked with -lpthread option, wired things happen: if it is run on a machine where it is dynamically linked to a linuxthread version of libpthread, it gives:

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

But when run on a machine where it is dynamically linked to a NPTL version of libpthread, it gives the expected result:

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