blob: 3f687961cdf848b2349079e67c9666ab5539fb04 [file] [log] [blame]
sewardjcbdddcf2005-03-10 23:23:45 +00001#include <signal.h>
2#include <stdio.h>
njnc45282a2005-03-25 23:50:11 +00003#include <stdlib.h>
4#include <sys/types.h>
5#include <unistd.h>
sewardjcbdddcf2005-03-10 23:23:45 +00006
njncfaa0a72009-03-13 05:38:01 +00007/* What does this test do? It checks that valgrind's signal frame
8 building mechanism can create at least 4MB of signal delivery
9 frames, hence that it can actually expand the stack by that much
10 when delivering signals. A fair-enough thing to want to test.
11
12 It does this by getting into the signal handler, and then
13 recursively invoking the handler by sending itself the signal
14 again, until the stack has grown to 4MB from the starting frame
15 (main).
16
17 Consequence is: it is essential that we do not disable delivery of
18 further signals within the handler itself, else the kernel will
19 wait till the handler exits before delivering the next signal, the
20 frame will be cleared, the stack will never grow, and we'll be in
21 an infinite loop.
22
23 Hence we *must* give the SA_NODEFER flag when setting up the
24 handler.
25*/
sewardj4bdd5052006-10-17 01:28:48 +000026
sewardjcbdddcf2005-03-10 23:23:45 +000027static char *deep;
28
29#define SIZE (4*1024*1024)
30
31static void handler(int sig)
32{
33 char here;
34
35 if (&here < deep) {
36 printf("PASSED\n");
37 exit(0);
38 }
39
40 kill(getpid(), SIGUSR1);
41}
42
43int main()
44{
45 struct sigaction sa;
46
47 char here;
48 deep = &here - SIZE;
49
50 sa.sa_handler = handler;
njncfaa0a72009-03-13 05:38:01 +000051 sa.sa_flags = SA_NODEFER;
sewardjcbdddcf2005-03-10 23:23:45 +000052 sigemptyset(&sa.sa_mask);
53
54 sigaction(SIGUSR1, &sa, NULL);
55
56 kill(getpid(), SIGUSR1);
57
58 printf("FAILED\n");
59 exit(1);
60}
njncfaa0a72009-03-13 05:38:01 +000061