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