1570af302Sopenharmony_ci// commit: 6871fd773dcedbf056317d5d5e87b4859e97c4a4 2011-03-10 2570af302Sopenharmony_ci// commit: 9505bfbc40fec217820abad7142663eda60cd6be 2014-03-18 3570af302Sopenharmony_ci// catching stackoverflow SIGSEGV using sigaltstack 4570af302Sopenharmony_ci// mips stack_t is inconsistent with other archs 5570af302Sopenharmony_ci#define _XOPEN_SOURCE 700 6570af302Sopenharmony_ci#include <signal.h> 7570af302Sopenharmony_ci#include <stdint.h> 8570af302Sopenharmony_ci#include <stdlib.h> 9570af302Sopenharmony_ci#include <string.h> 10570af302Sopenharmony_ci#include <errno.h> 11570af302Sopenharmony_ci#include "test.h" 12570af302Sopenharmony_ci 13570af302Sopenharmony_ci#define T(f) ((f)==0 || (t_error(#f " failed: %s\n", strerror(errno)),0)) 14570af302Sopenharmony_ci 15570af302Sopenharmony_cistatic char stack[SIGSTKSZ]; 16570af302Sopenharmony_ci 17570af302Sopenharmony_cistatic void handler(int sig) 18570af302Sopenharmony_ci{ 19570af302Sopenharmony_ci uintptr_t i; 20570af302Sopenharmony_ci stack_t ss; 21570af302Sopenharmony_ci 22570af302Sopenharmony_ci i = (uintptr_t)&i; 23570af302Sopenharmony_ci if (i < (uintptr_t)stack || i >= (uintptr_t)stack+SIGSTKSZ) 24570af302Sopenharmony_ci t_error("signal handler was not invoked on the altstack\n"); 25570af302Sopenharmony_ci 26570af302Sopenharmony_ci T(sigaltstack(0, &ss)); 27570af302Sopenharmony_ci if (ss.ss_flags != SS_ONSTACK) 28570af302Sopenharmony_ci t_error("ss_flags is not SS_ONSTACK in the signal handler\n"); 29570af302Sopenharmony_ci} 30570af302Sopenharmony_ci 31570af302Sopenharmony_ciint main(void) 32570af302Sopenharmony_ci{ 33570af302Sopenharmony_ci stack_t ss; 34570af302Sopenharmony_ci struct sigaction sa; 35570af302Sopenharmony_ci 36570af302Sopenharmony_ci ss.ss_sp = stack; 37570af302Sopenharmony_ci ss.ss_size = sizeof stack; 38570af302Sopenharmony_ci ss.ss_flags = 0; 39570af302Sopenharmony_ci sa.sa_handler = handler; 40570af302Sopenharmony_ci sa.sa_flags = SA_ONSTACK; 41570af302Sopenharmony_ci 42570af302Sopenharmony_ci T(sigaltstack(&ss, 0)); 43570af302Sopenharmony_ci T(sigfillset(&sa.sa_mask)); 44570af302Sopenharmony_ci T(sigaction(SIGUSR1, &sa, 0)); 45570af302Sopenharmony_ci T(raise(SIGUSR1)); 46570af302Sopenharmony_ci 47570af302Sopenharmony_ci errno = 0; 48570af302Sopenharmony_ci ss.ss_size = MINSIGSTKSZ-1; 49570af302Sopenharmony_ci if (sigaltstack(&ss, 0) != -1 || errno != ENOMEM) 50570af302Sopenharmony_ci t_error("sigaltstack with stack size < MINSIGSTKSZ should have failed with ENOMEM, " 51570af302Sopenharmony_ci "got %s\n", strerror(errno)); 52570af302Sopenharmony_ci errno = 0; 53570af302Sopenharmony_ci ss.ss_flags = -1; 54570af302Sopenharmony_ci ss.ss_size = MINSIGSTKSZ; 55570af302Sopenharmony_ci if (sigaltstack(&ss, 0) != -1 || errno != EINVAL) 56570af302Sopenharmony_ci t_error("sigaltstack with bad ss_flags should have failed with EINVAL, " 57570af302Sopenharmony_ci "got %s\n", strerror(errno)); 58570af302Sopenharmony_ci errno = 0; 59570af302Sopenharmony_ci T(sigaltstack(0, 0)); 60570af302Sopenharmony_ci 61570af302Sopenharmony_ci return t_status; 62570af302Sopenharmony_ci} 63