27

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

asdf
  • 2,281
  • 5
  • 28
  • 29
  • Attempting to set `rlimit_stack` after [Stack Clash](http://www.openwall.com/lists/oss-security/2017/06/19/1) remediations may result in failure or related problems. Also see Red Hat [Issue 1463241](https://bugzilla.redhat.com/show_bug.cgi?id=1463241) – jww Jun 21 '17 at 16:19

3 Answers3

29

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;
}
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • thanks do you know the exact syntax for setting stacj to 64M with setrlimit? – asdf Feb 17 '10 at 07:57
  • 2
    @Werner: this code should compile equally well in C, C++ or Objective-C. Obviously you need the correct `#include` s though, e.g. `#include `. – Paul R Jul 09 '10 at 16:31
  • 1
    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". https://www.kernel.org/doc/Documentation/CodingStyle – Sam Watkins Feb 06 '15 at 01:57
  • 4
    From the same page: "Coding style is very personal." ;-) – Paul R Feb 06 '15 at 06:35
  • Attempting to set `rlimit_stack` after [Stack Clash](http://www.openwall.com/lists/oss-security/2017/06/19/1) remediations may result in failure or related problems. Also see Red Hat [Issue 1463241](https://bugzilla.redhat.com/show_bug.cgi?id=1463241) – jww Jun 21 '17 at 16:20
  • 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. – Madars Vi Oct 21 '17 at 22:15
  • I got an error `error: ‘stderr’ was not declared in this scope` – banan3'14 Apr 29 '18 at 17:03
  • 1
    @banan3'14: did you forget to `#include ` ? – Paul R Apr 29 '18 at 23:13
  • 1
    @Paul, After I got the error, I edited the answer, so my comment seems irrelevant now. – banan3'14 May 01 '18 at 08:48
17

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
wallyk
  • 56,922
  • 16
  • 83
  • 148
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;

    }
Taylor
  • 5,871
  • 2
  • 30
  • 64