Daily bump.
[gcc.git] / libgo / runtime / go-signal.c
1 /* go-signal.c -- signal handling for Go.
2
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. */
6
7 #include <signal.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <sys/time.h>
11
12 #include "runtime.h"
13 #include "go-assert.h"
14 #include "go-panic.h"
15
16 #ifndef SA_RESTART
17 #define SA_RESTART 0
18 #endif
19
20 #ifdef USING_SPLIT_STACK
21
22 extern void __splitstack_getcontext(void *context[10]);
23
24 extern void __splitstack_setcontext(void *context[10]);
25
26 #endif
27
28 #define N SigNotify
29 #define K SigKill
30 #define T SigThrow
31 #define P SigPanic
32 #define D SigDefault
33
34 /* Signal actions. This collects the sigtab tables for several
35 different targets from the master library. SIGKILL, SIGCONT, and
36 SIGSTOP are not listed, as we don't want to set signal handlers for
37 them. */
38
39 SigTab runtime_sigtab[] = {
40 #ifdef SIGHUP
41 { SIGHUP, N + K },
42 #endif
43 #ifdef SIGINT
44 { SIGINT, N + K },
45 #endif
46 #ifdef SIGQUIT
47 { SIGQUIT, N + T },
48 #endif
49 #ifdef SIGILL
50 { SIGILL, T },
51 #endif
52 #ifdef SIGTRAP
53 { SIGTRAP, T },
54 #endif
55 #ifdef SIGABRT
56 { SIGABRT, N + T },
57 #endif
58 #ifdef SIGBUS
59 { SIGBUS, P },
60 #endif
61 #ifdef SIGFPE
62 { SIGFPE, P },
63 #endif
64 #ifdef SIGUSR1
65 { SIGUSR1, N },
66 #endif
67 #ifdef SIGSEGV
68 { SIGSEGV, P },
69 #endif
70 #ifdef SIGUSR2
71 { SIGUSR2, N },
72 #endif
73 #ifdef SIGPIPE
74 { SIGPIPE, N },
75 #endif
76 #ifdef SIGALRM
77 { SIGALRM, N },
78 #endif
79 #ifdef SIGTERM
80 { SIGTERM, N + K },
81 #endif
82 #ifdef SIGSTKFLT
83 { SIGSTKFLT, T },
84 #endif
85 #ifdef SIGCHLD
86 { SIGCHLD, N },
87 #endif
88 #ifdef SIGTSTP
89 { SIGTSTP, N + D },
90 #endif
91 #ifdef SIGTTIN
92 { SIGTTIN, N + D },
93 #endif
94 #ifdef SIGTTOU
95 { SIGTTOU, N + D },
96 #endif
97 #ifdef SIGURG
98 { SIGURG, N },
99 #endif
100 #ifdef SIGXCPU
101 { SIGXCPU, N },
102 #endif
103 #ifdef SIGXFSZ
104 { SIGXFSZ, N },
105 #endif
106 #ifdef SIGVTALRM
107 { SIGVTALRM, N },
108 #endif
109 #ifdef SIGPROF
110 { SIGPROF, N },
111 #endif
112 #ifdef SIGWINCH
113 { SIGWINCH, N },
114 #endif
115 #ifdef SIGIO
116 { SIGIO, N },
117 #endif
118 #ifdef SIGPWR
119 { SIGPWR, N },
120 #endif
121 #ifdef SIGSYS
122 { SIGSYS, N },
123 #endif
124 #ifdef SIGEMT
125 { SIGEMT, T },
126 #endif
127 #ifdef SIGINFO
128 { SIGINFO, N },
129 #endif
130 #ifdef SIGTHR
131 { SIGTHR, N },
132 #endif
133 { -1, 0 }
134 };
135 #undef N
136 #undef K
137 #undef T
138 #undef P
139 #undef D
140
141
142 static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n";
143
144 static void
145 runtime_badsignal(int32 sig)
146 {
147 // Avoid -D_FORTIFY_SOURCE problems.
148 int rv __attribute__((unused));
149
150 if (sig == SIGPROF) {
151 return; // Ignore SIGPROFs intended for a non-Go thread.
152 }
153 rv = runtime_write(2, badsignal, sizeof badsignal - 1);
154 runtime_exit(1);
155 }
156
157 /* Handle a signal, for cases where we don't panic. We can split the
158 stack here. */
159
160 static void
161 sig_handler (int sig)
162 {
163 int i;
164
165 if (runtime_m () == NULL)
166 {
167 runtime_badsignal (sig);
168 return;
169 }
170
171 #ifdef SIGPROF
172 if (sig == SIGPROF)
173 {
174 runtime_sigprof ();
175 return;
176 }
177 #endif
178
179 for (i = 0; runtime_sigtab[i].sig != -1; ++i)
180 {
181 SigTab *t;
182
183 t = &runtime_sigtab[i];
184
185 if (t->sig != sig)
186 continue;
187
188 if ((t->flags & SigNotify) != 0)
189 {
190 if (__go_sigsend (sig))
191 return;
192 }
193 if ((t->flags & SigKill) != 0)
194 runtime_exit (2);
195 if ((t->flags & SigThrow) == 0)
196 return;
197
198 runtime_startpanic ();
199
200 {
201 const char *name = NULL;
202
203 #ifdef HAVE_STRSIGNAL
204 name = strsignal (sig);
205 #endif
206
207 if (name == NULL)
208 runtime_printf ("Signal %d\n", sig);
209 else
210 runtime_printf ("%s\n", name);
211 }
212
213 runtime_printf ("\n");
214
215 if (runtime_gotraceback ())
216 {
217 G *g;
218
219 g = runtime_g ();
220 runtime_traceback (g);
221 runtime_tracebackothers (g);
222
223 /* The gc library calls runtime_dumpregs here, and provides
224 a function that prints the registers saved in context in
225 a readable form. */
226 }
227
228 runtime_exit (2);
229 }
230
231 __builtin_unreachable ();
232 }
233
234 /* The start of handling a signal which panics. */
235
236 static void
237 sig_panic_leadin (int sig)
238 {
239 int i;
240 sigset_t clear;
241
242 if (runtime_m ()->mallocing)
243 {
244 runtime_printf ("caught signal while mallocing: %d\n", sig);
245 runtime_throw ("caught signal while mallocing");
246 }
247
248 /* The signal handler blocked signals; unblock them. */
249 i = sigfillset (&clear);
250 __go_assert (i == 0);
251 i = sigprocmask (SIG_UNBLOCK, &clear, NULL);
252 __go_assert (i == 0);
253 }
254
255 #ifdef SA_SIGINFO
256
257 /* Signal dispatch for signals which panic, on systems which support
258 SA_SIGINFO. This is called on the thread stack, and as such it is
259 permitted to split the stack. */
260
261 static void
262 sig_panic_info_handler (int sig, siginfo_t *info,
263 void *context __attribute__ ((unused)))
264 {
265 G *g;
266
267 g = runtime_g ();
268 if (g == NULL || info->si_code == SI_USER)
269 {
270 sig_handler (sig);
271 return;
272 }
273
274 g->sig = sig;
275 g->sigcode0 = info->si_code;
276 g->sigcode1 = (uintptr_t) info->si_addr;
277
278 /* It would be nice to set g->sigpc here as the gc library does, but
279 I don't know how to get it portably. */
280
281 sig_panic_leadin (sig);
282
283 switch (sig)
284 {
285 #ifdef SIGBUS
286 case SIGBUS:
287 if (info->si_code == BUS_ADRERR && (uintptr_t) info->si_addr < 0x1000)
288 runtime_panicstring ("invalid memory address or "
289 "nil pointer dereference");
290 runtime_printf ("unexpected fault address %p\n", info->si_addr);
291 runtime_throw ("fault");
292 #endif
293
294 #ifdef SIGSEGV
295 case SIGSEGV:
296 if ((info->si_code == 0
297 || info->si_code == SEGV_MAPERR
298 || info->si_code == SEGV_ACCERR)
299 && (uintptr_t) info->si_addr < 0x1000)
300 runtime_panicstring ("invalid memory address or "
301 "nil pointer dereference");
302 runtime_printf ("unexpected fault address %p\n", info->si_addr);
303 runtime_throw ("fault");
304 #endif
305
306 #ifdef SIGFPE
307 case SIGFPE:
308 switch (info->si_code)
309 {
310 case FPE_INTDIV:
311 runtime_panicstring ("integer divide by zero");
312 case FPE_INTOVF:
313 runtime_panicstring ("integer overflow");
314 }
315 runtime_panicstring ("floating point error");
316 #endif
317 }
318
319 /* All signals with SigPanic should be in cases above, and this
320 handler should only be invoked for those signals. */
321 __builtin_unreachable ();
322 }
323
324 #else /* !defined (SA_SIGINFO) */
325
326 static void
327 sig_panic_handler (int sig)
328 {
329 G *g;
330
331 g = runtime_g ();
332 if (g == NULL)
333 {
334 sig_handler (sig);
335 return;
336 }
337
338 g->sig = sig;
339 g->sigcode0 = 0;
340 g->sigcode1 = 0;
341
342 sig_panic_leadin (sig);
343
344 switch (sig)
345 {
346 #ifdef SIGBUS
347 case SIGBUS:
348 runtime_panicstring ("invalid memory address or "
349 "nil pointer dereference");
350 #endif
351
352 #ifdef SIGSEGV
353 case SIGSEGV:
354 runtime_panicstring ("invalid memory address or "
355 "nil pointer dereference");
356 #endif
357
358 #ifdef SIGFPE
359 case SIGFPE:
360 runtime_panicstring ("integer divide by zero or floating point error");
361 #endif
362 }
363
364 /* All signals with SigPanic should be in cases above, and this
365 handler should only be invoked for those signals. */
366 __builtin_unreachable ();
367 }
368
369 #endif /* !defined (SA_SIGINFO) */
370
371 /* A signal handler used for signals which are not going to panic.
372 This is called on the alternate signal stack so it may not split
373 the stack. */
374
375 static void
376 sig_tramp (int) __attribute__ ((no_split_stack));
377
378 static void
379 sig_tramp (int sig)
380 {
381 G *gp;
382 M *mp;
383
384 /* We are now running on the stack registered via sigaltstack.
385 (Actually there is a small span of time between runtime_siginit
386 and sigaltstack when the program starts.) */
387 gp = runtime_g ();
388 mp = runtime_m ();
389
390 if (gp != NULL)
391 {
392 #ifdef USING_SPLIT_STACK
393 __splitstack_getcontext (&gp->stack_context[0]);
394 #endif
395 }
396
397 if (gp != NULL && mp->gsignal != NULL)
398 {
399 /* We are running on the signal stack. Set the split stack
400 context so that the stack guards are checked correctly. */
401 #ifdef USING_SPLIT_STACK
402 __splitstack_setcontext (&mp->gsignal->stack_context[0]);
403 #endif
404 }
405
406 sig_handler (sig);
407
408 /* We are going to return back to the signal trampoline and then to
409 whatever we were doing before we got the signal. Restore the
410 split stack context so that stack guards are checked
411 correctly. */
412
413 if (gp != NULL)
414 {
415 #ifdef USING_SPLIT_STACK
416 __splitstack_setcontext (&gp->stack_context[0]);
417 #endif
418 }
419 }
420
421 void
422 runtime_setsig (int32 i, bool def __attribute__ ((unused)), bool restart)
423 {
424 struct sigaction sa;
425 int r;
426 SigTab *t;
427
428 memset (&sa, 0, sizeof sa);
429
430 r = sigfillset (&sa.sa_mask);
431 __go_assert (r == 0);
432
433 t = &runtime_sigtab[i];
434
435 if ((t->flags & SigPanic) == 0)
436 {
437 sa.sa_flags = SA_ONSTACK;
438 sa.sa_handler = sig_tramp;
439 }
440 else
441 {
442 #ifdef SA_SIGINFO
443 sa.sa_flags = SA_SIGINFO;
444 sa.sa_sigaction = sig_panic_info_handler;
445 #else
446 sa.sa_flags = 0;
447 sa.sa_handler = sig_panic_handler;
448 #endif
449 }
450
451 if (restart)
452 sa.sa_flags |= SA_RESTART;
453
454 if (sigaction (t->sig, &sa, NULL) != 0)
455 __go_assert (0);
456 }
457
458 /* Used by the os package to raise SIGPIPE. */
459
460 void os_sigpipe (void) __asm__ (GOSYM_PREFIX "os.sigpipe");
461
462 void
463 os_sigpipe (void)
464 {
465 struct sigaction sa;
466 int i;
467
468 memset (&sa, 0, sizeof sa);
469
470 sa.sa_handler = SIG_DFL;
471
472 i = sigemptyset (&sa.sa_mask);
473 __go_assert (i == 0);
474
475 if (sigaction (SIGPIPE, &sa, NULL) != 0)
476 abort ();
477
478 raise (SIGPIPE);
479 }
480
481 void
482 runtime_setprof(bool on)
483 {
484 USED(on);
485 }