1// commit: 6871fd773dcedbf056317d5d5e87b4859e97c4a4 2011-03-10 2// commit: 9505bfbc40fec217820abad7142663eda60cd6be 2014-03-18 3// catching stackoverflow SIGSEGV using sigaltstack 4// mips stack_t is inconsistent with other archs 5#define _XOPEN_SOURCE 700 6#include <signal.h> 7#include <stdint.h> 8#include <stdlib.h> 9#include <string.h> 10#include <errno.h> 11#include "test.h" 12 13#define T(f) ((f)==0 || (t_error(#f " failed: %s\n", strerror(errno)),0)) 14 15static char stack[SIGSTKSZ]; 16 17static void handler(int sig) 18{ 19 uintptr_t i; 20 stack_t ss; 21 22 i = (uintptr_t)&i; 23 if (i < (uintptr_t)stack || i >= (uintptr_t)stack+SIGSTKSZ) 24 t_error("signal handler was not invoked on the altstack\n"); 25 26 T(sigaltstack(0, &ss)); 27 if (ss.ss_flags != SS_ONSTACK) 28 t_error("ss_flags is not SS_ONSTACK in the signal handler\n"); 29} 30 31int main(void) 32{ 33 stack_t ss; 34 struct sigaction sa; 35 36 ss.ss_sp = stack; 37 ss.ss_size = sizeof stack; 38 ss.ss_flags = 0; 39 sa.sa_handler = handler; 40 sa.sa_flags = SA_ONSTACK; 41 42 T(sigaltstack(&ss, 0)); 43 T(sigfillset(&sa.sa_mask)); 44 T(sigaction(SIGUSR1, &sa, 0)); 45 T(raise(SIGUSR1)); 46 47 errno = 0; 48 ss.ss_size = MINSIGSTKSZ-1; 49 if (sigaltstack(&ss, 0) != -1 || errno != ENOMEM) 50 t_error("sigaltstack with stack size < MINSIGSTKSZ should have failed with ENOMEM, " 51 "got %s\n", strerror(errno)); 52 errno = 0; 53 ss.ss_flags = -1; 54 ss.ss_size = MINSIGSTKSZ; 55 if (sigaltstack(&ss, 0) != -1 || errno != EINVAL) 56 t_error("sigaltstack with bad ss_flags should have failed with EINVAL, " 57 "got %s\n", strerror(errno)); 58 errno = 0; 59 T(sigaltstack(0, 0)); 60 61 return t_status; 62} 63