File: stack-growsdown.c

package info (click to toggle)
dmtcp 2.6.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 6,496 kB
  • sloc: cpp: 33,592; ansic: 28,099; sh: 6,735; makefile: 1,950; perl: 1,690; python: 1,241; asm: 138; java: 13
file content (64 lines) | stat: -rw-r--r-- 2,068 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <time.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>

int CUR_LIMIT = -1;

void recursive_fnc2(char x) {
  // In one second, this will force 32 MB, and Linux default stack size is 8 MB
  struct timespec time = {0, 2<<27}; // 1/8 seconds
  nanosleep(&time, NULL);
  printf("."); fflush(stdout);

  // Restore rlim_cur on restart.
  // FIXME:  DMTCP should restore rlim_cur automatically, without this code.
  //   Instead, we rely on hack: ckpt usually happening during the 'nanosleep'
  struct rlimit stack_limit = {0, 0};
  getrlimit(RLIMIT_STACK, &stack_limit);
  stack_limit.rlim_cur = CUR_LIMIT;
  setrlimit(RLIMIT_STACK, &stack_limit);

  // Could use alloca(), but it's not POSIX.
  char extra_stack_memory[2<<20]; // 1 MB
  extra_stack_memory[0] = x;
  if (extra_stack_memory[0] != '\0') {
    return; // avoid -Wunused-but-set-variable
  }

  recursive_fnc2(x);
}

void recursive_fnc1(char x) {
  char extra_stack_memory[2<<22]; // 4 MB
  extra_stack_memory[0] = '\0';
  if (extra_stack_memory[0] != '\0') {
    while (1); // just loop; rlim_max not large enough for valid test.
  }
  recursive_fnc2(x);
}

int main() {
  struct rlimit stack_limit = {0, 0};
  getrlimit(RLIMIT_STACK, &stack_limit);
  printf("RLIMIT_STACK(soft,hard):   %u, %u\n",
         (unsigned)stack_limit.rlim_cur, (unsigned)stack_limit.rlim_max);
  if (stack_limit.rlim_max >= stack_limit.rlim_cur * 16) {
    // Default stack size is 8 MB; so, we set it to 128 MB
    // It will exceed 8 MB in less than a second, and exceed stack limit in 16 s
    stack_limit.rlim_cur *= 16;
    CUR_LIMIT = stack_limit.rlim_cur;
    int rc = setrlimit(RLIMIT_STACK, &stack_limit);
    if (rc == -1) {
      perror("setrlimit");
      while (1);
    }
    printf("Setting rlim_cur for RLIMIT_STACK to %u.\n", 2<<26);
  } else {
    printf("Can't test MAP_STACKGROWSDOWN for '[stack]'.\n");
    while (1); // just loop; rlim_max not large enough for valid test.
  }

  recursive_fnc1('\0');
  return 0;
}