sewardj | cbdddcf | 2005-03-10 23:23:45 +0000 | [diff] [blame] | 1 | #include <signal.h> |
| 2 | #include <stdio.h> |
njn | c45282a | 2005-03-25 23:50:11 +0000 | [diff] [blame] | 3 | #include <stdlib.h> |
| 4 | #include <sys/types.h> |
| 5 | #include <unistd.h> |
sewardj | cbdddcf | 2005-03-10 23:23:45 +0000 | [diff] [blame] | 6 | |
njn | cfaa0a7 | 2009-03-13 05:38:01 +0000 | [diff] [blame] | 7 | /* 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 | */ |
sewardj | 4bdd505 | 2006-10-17 01:28:48 +0000 | [diff] [blame] | 26 | |
sewardj | cbdddcf | 2005-03-10 23:23:45 +0000 | [diff] [blame] | 27 | static char *deep; |
| 28 | |
| 29 | #define SIZE (4*1024*1024) |
| 30 | |
| 31 | static 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 | |
| 43 | int main() |
| 44 | { |
| 45 | struct sigaction sa; |
| 46 | |
| 47 | char here; |
| 48 | deep = &here - SIZE; |
| 49 | |
| 50 | sa.sa_handler = handler; |
njn | cfaa0a7 | 2009-03-13 05:38:01 +0000 | [diff] [blame] | 51 | sa.sa_flags = SA_NODEFER; |
sewardj | cbdddcf | 2005-03-10 23:23:45 +0000 | [diff] [blame] | 52 | sigemptyset(&sa.sa_mask); |
| 53 | |
| 54 | sigaction(SIGUSR1, &sa, NULL); |
| 55 | |
| 56 | kill(getpid(), SIGUSR1); |
| 57 | |
| 58 | printf("FAILED\n"); |
| 59 | exit(1); |
| 60 | } |
njn | cfaa0a7 | 2009-03-13 05:38:01 +0000 | [diff] [blame] | 61 | |