sigaltstack.c revision 1.1.1.4 1 1.1 christos /* This testcase is part of GDB, the GNU debugger.
2 1.1 christos
3 1.1.1.4 christos Copyright 2004-2017 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This program is free software; you can redistribute it and/or modify
6 1.1 christos it under the terms of the GNU General Public License as published by
7 1.1 christos the Free Software Foundation; either version 3 of the License, or
8 1.1 christos (at your option) any later version.
9 1.1 christos
10 1.1 christos This program is distributed in the hope that it will be useful,
11 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 1.1 christos GNU General Public License for more details.
14 1.1 christos
15 1.1 christos You should have received a copy of the GNU General Public License
16 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 1.1 christos
18 1.1 christos #include <signal.h>
19 1.1 christos #include <stdio.h>
20 1.1 christos #include <stdlib.h>
21 1.1 christos #include <string.h>
22 1.1 christos #include <sys/time.h>
23 1.1 christos
24 1.1 christos enum level { MAIN, OUTER, INNER, LEAF, NR_LEVELS };
25 1.1 christos
26 1.1 christos /* Levels completed flag. */
27 1.1 christos volatile enum level level = NR_LEVELS;
28 1.1 christos
29 1.1 christos void catcher (int signal);
30 1.1 christos
31 1.1 christos void
32 1.1 christos thrower (enum level next_level, int sig, int itimer, int on_stack)
33 1.1 christos {
34 1.1 christos level = next_level;
35 1.1 christos /* Set up the signal handler. */
36 1.1 christos {
37 1.1 christos struct sigaction act;
38 1.1 christos memset (&act, 0, sizeof (act));
39 1.1 christos act.sa_handler = catcher;
40 1.1 christos act.sa_flags |= on_stack;
41 1.1 christos sigaction (sig, &act, NULL);
42 1.1 christos }
43 1.1 christos /* Set up a one-off timer. A timer, rather than SIGSEGV, is used as
44 1.1 christos after a timer handler finishes the interrupted code can safely
45 1.1 christos resume. */
46 1.1 christos {
47 1.1 christos struct itimerval itime;
48 1.1 christos memset (&itime, 0, sizeof (itime));
49 1.1 christos itime.it_value.tv_usec = 250 * 1000;
50 1.1 christos setitimer (itimer, &itime, NULL);
51 1.1 christos }
52 1.1 christos /* Wait. */
53 1.1 christos while (level != LEAF);
54 1.1 christos }
55 1.1 christos
56 1.1 christos void
57 1.1 christos catcher (int signal)
58 1.1 christos {
59 1.1 christos /* Find the next level. */
60 1.1 christos switch (level)
61 1.1 christos {
62 1.1 christos case MAIN:
63 1.1 christos thrower (OUTER, SIGALRM, ITIMER_REAL, SA_ONSTACK);
64 1.1 christos break;
65 1.1 christos case OUTER:
66 1.1 christos thrower (INNER, SIGVTALRM, ITIMER_VIRTUAL, SA_ONSTACK);
67 1.1 christos break;
68 1.1 christos case INNER:
69 1.1 christos level = LEAF;
70 1.1 christos return;
71 1.1 christos }
72 1.1 christos }
73 1.1 christos
74 1.1 christos
75 1.1.1.2 christos int
76 1.1 christos main ()
77 1.1 christos {
78 1.1 christos /* Set up the altstack. */
79 1.1 christos {
80 1.1 christos static char stack[SIGSTKSZ * NR_LEVELS];
81 1.1 christos stack_t alt;
82 1.1 christos memset (&alt, 0, sizeof (alt));
83 1.1 christos alt.ss_sp = stack;
84 1.1 christos alt.ss_size = SIGSTKSZ;
85 1.1 christos alt.ss_flags = 0;
86 1.1 christos if (sigaltstack (&alt, NULL) < 0)
87 1.1 christos {
88 1.1 christos perror ("sigaltstack");
89 1.1 christos exit (0);
90 1.1 christos }
91 1.1 christos }
92 1.1 christos level = MAIN;
93 1.1 christos catcher (0);
94 1.1.1.2 christos return 0;
95 1.1 christos }
96