This source file includes following definitions.
- stackoverflow_handler_continuation
- stackoverflow_handler
- recurse_1
- recurse
- main
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21
22 #include "sigsegv.h"
23
24 #include <stdio.h>
25 #include <limits.h>
26
27 #if HAVE_STACK_OVERFLOW_RECOVERY
28
29 # if defined _WIN32 && !defined __CYGWIN__
30
31 typedef int sigset_t;
32 # define sigemptyset(set)
33 # define sigprocmask(how,set,oldset)
34 # endif
35
36 # include <stddef.h>
37 # include <stdlib.h>
38 # include <signal.h>
39 # include <setjmp.h>
40 # if HAVE_SETRLIMIT
41 # include <sys/types.h>
42 # include <sys/time.h>
43 # include <sys/resource.h>
44 # endif
45 # include "altstack-util.h"
46
47 static jmp_buf mainloop;
48 static sigset_t mainsigset;
49
50 static volatile int pass = 0;
51
52 static volatile char *stack_lower_bound;
53 static volatile char *stack_upper_bound;
54
55 static void
56 stackoverflow_handler_continuation (void *arg1, void *arg2, void *arg3)
57 {
58 int arg = (int) (long) arg1;
59 longjmp (mainloop, arg);
60 }
61
62 static void
63 stackoverflow_handler (int emergency, stackoverflow_context_t scp)
64 {
65 char dummy;
66 volatile char *addr = &dummy;
67 if (!(addr >= stack_lower_bound && addr <= stack_upper_bound))
68 abort ();
69 pass++;
70 printf ("Stack overflow %d caught.\n", pass);
71 sigprocmask (SIG_SETMASK, &mainsigset, NULL);
72 sigsegv_leave_handler (stackoverflow_handler_continuation,
73 (void *) (long) (emergency ? -1 : pass), NULL, NULL);
74 }
75
76 static volatile int *
77 recurse_1 (int n, volatile int *p)
78 {
79 if (n < INT_MAX)
80 *recurse_1 (n + 1, p) += n;
81 return p;
82 }
83
84 static int
85 recurse (volatile int n)
86 {
87 return *recurse_1 (n, &n);
88 }
89
90 int
91 main ()
92 {
93 sigset_t emptyset;
94
95 # if HAVE_SETRLIMIT && defined RLIMIT_STACK
96
97
98
99 struct rlimit rl;
100 rl.rlim_cur = rl.rlim_max = 0x100000;
101 setrlimit (RLIMIT_STACK, &rl);
102 # endif
103
104
105 prepare_alternate_stack ();
106
107
108 if (stackoverflow_install_handler (&stackoverflow_handler,
109 mystack, MYSTACK_SIZE)
110 < 0)
111 exit (2);
112 stack_lower_bound = mystack;
113 stack_upper_bound = mystack + MYSTACK_SIZE - 1;
114
115
116 sigemptyset (&emptyset);
117 sigprocmask (SIG_BLOCK, &emptyset, &mainsigset);
118
119
120 switch (setjmp (mainloop))
121 {
122 case -1:
123 printf ("emergency exit\n"); exit (1);
124 case 0: case 1:
125 printf ("Starting recursion pass %d.\n", pass + 1);
126 recurse (0);
127 printf ("no endless recursion?!\n"); exit (1);
128 case 2:
129 break;
130 default:
131 abort ();
132 }
133
134
135 check_alternate_stack_no_overflow ();
136
137 printf ("Test passed.\n");
138 exit (0);
139 }
140
141 #else
142
143 int
144 main ()
145 {
146 return 77;
147 }
148
149 #endif