Increase stack size in Linux with setrlimit
Asked Answered
A

3

29

reading information about how to increase stack size for a c++ application compiled with gnu, at compilation time, I understood that it can be done with setrlimit at the beginning of the program. Nevertheless I could not find any successful example on how to use it and in which part of the program apply it in order to get a 64M stack size for a c++ program, could anybody help me?

Thanlks

Athletic answered 17/2, 2010 at 7:44 Comment(1)
Attempting to set rlimit_stack after Stack Clash remediations may result in failure or related problems. Also see Red Hat Issue 1463241Incombustible
S
31

Normally you would set the stack size early on, e,g, at the start of main(), before calling any other functions. Typically the logic would be:

  • call getrlimit to get current stack size
  • if current size < required stack size then
    • call setrlimit to increase stack size to required size

In C that might be coded something like this:

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

int main (int argc, char **argv)
{
    const rlim_t kStackSize = 64L * 1024L * 1024L;   // min stack size = 64 Mb
    struct rlimit rl;
    int result;

    result = getrlimit(RLIMIT_STACK, &rl);
    if (result == 0)
    {
        if (rl.rlim_cur < kStackSize)
        {
            rl.rlim_cur = kStackSize;
            result = setrlimit(RLIMIT_STACK, &rl);
            if (result != 0)
            {
                fprintf(stderr, "setrlimit returned result = %d\n", result);
            }
        }
    }

    // ...

    return 0;
}
Sumpter answered 17/2, 2010 at 7:51 Comment(9)
thanks do you know the exact syntax for setting stacj to 64M with setrlimit?Athletic
@Werner: this code should compile equally well in C, C++ or Objective-C. Obviously you need the correct #include s though, e.g. #include <sys/resource.h>.Sumpter
Nice one. Just a tip, your code violates Linus's principle of Code Quality with TABs: "if you need more than 3 levels of indentation, you're screwed anyway, and should fix your program". kernel.org/doc/Documentation/CodingStyleOogonium
From the same page: "Coding style is very personal." ;-)Sumpter
Attempting to set rlimit_stack after Stack Clash remediations may result in failure or related problems. Also see Red Hat Issue 1463241Incombustible
I would test: if (rl.rlim_cur!=RLIM_INFINITY && rl.rlim_cur < kStackSize) to ensure that we do not conflict with RLIM_INFINITY constant. However standard says that RLIM_INFINITY should be large enough, but if set to RLIM_INFINITY, then no need to increase limit.Meadow
I got an error error: ‘stderr’ was not declared in this scopeEnquire
@banan3'14: did you forget to #include <stdio.h> ?Sumpter
@Paul, After I got the error, I edited the answer, so my comment seems irrelevant now.Enquire
W
22

See if the runtime execution maximum is limiting it:

[wally@zf conf]$  ulimit -all
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 16114
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 16114
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Note that the stack size, by default, is limited to 10 MiB. So to increase it to 64 MiB:

[wally@zf conf]$ ulimit -s 64M
-bash: ulimit: 64M: invalid number
[wally@zf conf]$ ulimit -s 65536
[wally@zf conf]$ ulimit -all
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 16114
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 65536
cpu time               (seconds, -t) unlimited
max user processes              (-u) 16114
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
Weiner answered 17/2, 2010 at 7:54 Comment(4)
yes, i know i can use ulimit to increase stack size, but i need to do this for this concrete application which is intended for normal users that can not use ulimit, beacuse admin reasonsAthletic
On Linux Mint 18.3 the default stack size limit is 8192KB, not 10MiB.Enquire
-bash: ulimit: 64M: invalid numberCaddric
@Sebi2020: Yes, I got that too in my example above. The correction is there too.Weiner
H
5

To get beyond the hard limit in setrlimit (on OSX its only 64MB by default), create a new thread using pthreads with a stack size of your choice. Here's a C snippet:

    // Call function f with a 256MB stack.
    static int bigstack(void *(*f)(void *), void* userdata) {

      pthread_t thread;
      pthread_attr_t attr;

      // allocate a 256MB region for the stack.
      size_t stacksize = 256*1024*1024;
      pthread_attr_init(&attr);
      pthread_attr_setstacksize(&attr, stacksize);

      int rc = pthread_create(&thread, &attr, f, userdata);
      if (rc){
        printf("ERROR: return code from pthread_create() is %d\n", rc);
        return 0;
      }
      pthread_join(thread, NULL);
      return 1;

    }
Hintz answered 14/2, 2012 at 16:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.