Ticket #3140: stack-overflow-bug.c

File stack-overflow-bug.c, 1.8 KB (added by bhaible, 16 years ago)

test program provoking a stack overflow

Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <sys/types.h>
4#include <sys/time.h>
5#include <sys/resource.h>
6#include <errno.h>
7#include <signal.h>
8#include <string.h>
9#include <unistd.h>
10#ifndef SIGSTKSZ
11# define SIGSTKSZ 16384
12#endif
13#ifndef STDERR_FILENO
14# define STDERR_FILENO 2
15#endif
16
17static void die (int) __attribute__ ((noreturn));
18static void
19die (int signo)
20{
21 char const *message;
22 message = signo ? "program error" : "stack overflow";
23 write (STDERR_FILENO, message, strlen (message));
24 write (STDERR_FILENO, "\n", 1);
25 if (! signo)
26 _exit (1);
27 raise (signo);
28 abort ();
29}
30
31/* Storage for the alternate signal stack. */
32static union
33{
34 char buffer[SIGSTKSZ];
35
36 /* These other members are for proper alignment. There's no
37 standard way to guarantee stack alignment, but this seems enough
38 in practice. */
39 long double ld;
40 long l;
41 void *p;
42} alternate_signal_stack;
43
44int
45c_stack_action ()
46{
47 int r;
48 stack_t st;
49 struct sigaction act;
50
51 st.ss_flags = 0;
52 st.ss_sp = alternate_signal_stack.buffer;
53 st.ss_size = sizeof alternate_signal_stack.buffer;
54 r = sigaltstack (&st, NULL);
55 if (r != 0)
56 return r;
57
58 sigemptyset (&act.sa_mask);
59 act.sa_flags = SA_NODEFER | SA_RESETHAND;
60 act.sa_handler = die;
61
62 return sigaction (SIGSEGV, &act, NULL);
63}
64
65static volatile int *
66recurse_1 (volatile int n, volatile int *p)
67{
68 if (n >= 0)
69 *recurse_1 (n + 1, p) += n;
70 return p;
71}
72
73static int
74recurse (volatile int n)
75{
76 int sum = 0;
77 return *recurse_1 (n, &sum);
78}
79
80int
81main (int argc, char **argv)
82{
83 struct rlimit rl;
84 rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
85 setrlimit (RLIMIT_STACK, &rl);
86
87 if (c_stack_action () == 0)
88 {
89 return recurse (0);
90 }
91 fputs ("skipping test: ", stderr);
92 perror ("c_stack_action");
93 return 77;
94}