• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
15 static char stack[SIGSTKSZ];
16 
handler(int sig)17 static 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 
main(void)31 int 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