c3f12711de6dd0209671e7e4cd2fbf05ad514d68
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.base / sigrepeat.c
1 /* This testcase is part of GDB, the GNU debugger.
2
3 Copyright 2004-2021 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <signal.h>
24 #include <sys/time.h>
25
26 static volatile int done[2];
27 static volatile int repeats[2];
28 static int itimer[2] = { ITIMER_REAL, ITIMER_VIRTUAL };
29 static int alarm[2] = { SIGALRM, SIGVTALRM };
30
31 static void
32 handler (int sig)
33 {
34 int sigi;
35 switch (sig)
36 {
37 case SIGALRM: sigi = 0; break;
38 case SIGVTALRM: sigi = 1; break;
39 default: abort ();
40 }
41 if (repeats[sigi]++ > 3)
42 {
43 /* Hit with enough signals, cancel everything and get out. */
44 {
45 struct itimerval itime;
46 memset (&itime, 0, sizeof (itime));
47 setitimer (itimer[sigi], &itime, NULL);
48 }
49 {
50 struct sigaction action;
51 memset (&action, 0, sizeof (action));
52 action.sa_handler = SIG_IGN;
53 sigaction (sig, &action, NULL);
54 }
55 done[sigi] = 1;
56 return;
57 }
58 /* Set up a nested virtual timer. */
59 while (1)
60 {
61 /* Wait until a signal has become pending, that way when this
62 handler returns it will be immediatly delivered leading to
63 back-to-back signals. */
64 sigset_t set;
65 sigemptyset (&set);
66 if (sigpending (&set) < 0)
67 {
68 perror ("sigrepeat");
69 abort ();
70 }
71 if (sigismember (&set, sig))
72 break;
73 }
74 } /* handler */
75
76 int
77 main ()
78 {
79 int i;
80 /* Set up the signal handler. */
81 for (i = 0; i < 2; i++)
82 {
83 struct sigaction action;
84 memset (&action, 0, sizeof (action));
85 action.sa_handler = handler;
86 sigaction (alarm[i], &action, NULL);
87 }
88
89 /* Set up a rapidly repeating timers. A timer, rather than SIGSEGV,
90 is used as after a timer handler returns the interrupted code can
91 safely resume. The intent is for the program to swamp GDB with a
92 backlog of pending signals. */
93 for (i = 0; i < 2; i++)
94 {
95 struct itimerval itime;
96 memset (&itime, 0, sizeof (itime));
97 itime.it_interval.tv_usec = 1;
98 itime.it_value.tv_usec = 250 * 1000;
99 setitimer (itimer[i], &itime, NULL);
100 }
101
102 /* Wait. */
103 while (!done[0] && !done[1]); /* infinite loop */
104 return 0;
105 }
This page took 0.031096 seconds and 3 git commands to generate.