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