Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / runtime / go-signal.c
blob3838ab98871ca3592d0723dd5acc86f5c5ca4f98
1 /* go-signal.c -- signal handling for Go.
3 Copyright 2009 The Go Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file. */
7 #include <signal.h>
8 #include <stdlib.h>
10 #include "go-assert.h"
11 #include "go-panic.h"
12 #include "go-signal.h"
14 #include "runtime.h"
16 #undef int
18 #ifndef SA_ONSTACK
19 #define SA_ONSTACK 0
20 #endif
22 /* What to do for a signal. */
24 struct sigtab
26 /* Signal number. */
27 int sig;
28 /* Nonzero if the signal should be ignored. */
29 _Bool ignore;
32 /* What to do for signals. */
34 static struct sigtab signals[] =
36 { SIGHUP, 0 },
37 { SIGINT, 0 },
38 { SIGALRM, 1 },
39 { SIGTERM, 0 },
40 #ifdef SIGBUS
41 { SIGBUS, 0 },
42 #endif
43 #ifdef SIGFPE
44 { SIGFPE, 0 },
45 #endif
46 #ifdef SIGUSR1
47 { SIGUSR1, 1 },
48 #endif
49 #ifdef SIGSEGV
50 { SIGSEGV, 0 },
51 #endif
52 #ifdef SIGUSR2
53 { SIGUSR2, 1 },
54 #endif
55 #ifdef SIGPIPE
56 { SIGPIPE, 1 },
57 #endif
58 #ifdef SIGCHLD
59 { SIGCHLD, 1 },
60 #endif
61 #ifdef SIGTSTP
62 { SIGTSTP, 1 },
63 #endif
64 #ifdef SIGTTIN
65 { SIGTTIN, 1 },
66 #endif
67 #ifdef SIGTTOU
68 { SIGTTOU, 1 },
69 #endif
70 #ifdef SIGURG
71 { SIGURG, 1 },
72 #endif
73 #ifdef SIGXCPU
74 { SIGXCPU, 1 },
75 #endif
76 #ifdef SIGXFSZ
77 { SIGXFSZ, 1 },
78 #endif
79 #ifdef SIGVTARLM
80 { SIGVTALRM, 1 },
81 #endif
82 #ifdef SIGPROF
83 { SIGPROF, 1 },
84 #endif
85 #ifdef SIGWINCH
86 { SIGWINCH, 1 },
87 #endif
88 #ifdef SIGIO
89 { SIGIO, 1 },
90 #endif
91 #ifdef SIGPWR
92 { SIGPWR, 1 },
93 #endif
94 { -1, 0 }
97 /* The Go signal handler. */
99 static void
100 sighandler (int sig)
102 const char *msg;
103 int i;
105 /* FIXME: Should check siginfo for more information when
106 available. */
107 msg = NULL;
108 switch (sig)
110 #ifdef SIGBUS
111 case SIGBUS:
112 msg = "invalid memory address or nil pointer dereference";
113 break;
114 #endif
116 #ifdef SIGFPE
117 case SIGFPE:
118 msg = "integer divide by zero or floating point error";
119 break;
120 #endif
122 #ifdef SIGSEGV
123 case SIGSEGV:
124 msg = "invalid memory address or nil pointer dereference";
125 break;
126 #endif
128 default:
129 break;
132 if (msg != NULL)
134 sigset_t clear;
136 if (__sync_bool_compare_and_swap (&m->mallocing, 1, 1))
138 fprintf (stderr, "caught signal while mallocing: %s\n", msg);
139 __go_assert (0);
142 /* The signal handler blocked signals; unblock them. */
143 i = sigfillset (&clear);
144 __go_assert (i == 0);
145 i = sigprocmask (SIG_UNBLOCK, &clear, NULL);
146 __go_assert (i == 0);
148 __go_panic_msg (msg);
151 if (__go_sigsend (sig))
152 return;
153 for (i = 0; signals[i].sig != -1; ++i)
155 if (signals[i].sig == sig)
157 struct sigaction sa;
159 if (signals[i].ignore)
160 return;
162 memset (&sa, 0, sizeof sa);
164 sa.sa_handler = SIG_DFL;
166 i = sigemptyset (&sa.sa_mask);
167 __go_assert (i == 0);
169 if (sigaction (sig, &sa, NULL) != 0)
170 abort ();
172 raise (sig);
173 exit (2);
176 abort ();
179 /* Initialize signal handling for Go. This is called when the program
180 starts. */
182 void
183 __initsig ()
185 struct sigaction sa;
186 int i;
188 siginit ();
190 memset (&sa, 0, sizeof sa);
192 sa.sa_handler = sighandler;
194 i = sigfillset (&sa.sa_mask);
195 __go_assert (i == 0);
197 for (i = 0; signals[i].sig != -1; ++i)
198 if (sigaction (signals[i].sig, &sa, NULL) != 0)
199 __go_assert (0);