Merge from branches/gcc-4_8-branch up to rev 204657.
[official-gcc.git] / gcc-4_8-branch / libgo / runtime / go-signal.c
blob23a94db4157ad1a48670b2718f59e7f70ef95995
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>
9 #include <unistd.h>
10 #include <sys/time.h>
12 #include "runtime.h"
13 #include "go-assert.h"
14 #include "go-panic.h"
15 #include "signal_unix.h"
17 #ifndef SA_RESTART
18 #define SA_RESTART 0
19 #endif
21 #ifdef USING_SPLIT_STACK
23 extern void __splitstack_getcontext(void *context[10]);
25 extern void __splitstack_setcontext(void *context[10]);
27 #endif
29 #define N SigNotify
30 #define K SigKill
31 #define T SigThrow
32 #define P SigPanic
33 #define D SigDefault
35 /* Signal actions. This collects the sigtab tables for several
36 different targets from the master library. SIGKILL, SIGCONT, and
37 SIGSTOP are not listed, as we don't want to set signal handlers for
38 them. */
40 SigTab runtime_sigtab[] = {
41 #ifdef SIGHUP
42 { SIGHUP, N + K },
43 #endif
44 #ifdef SIGINT
45 { SIGINT, N + K },
46 #endif
47 #ifdef SIGQUIT
48 { SIGQUIT, N + T },
49 #endif
50 #ifdef SIGILL
51 { SIGILL, T },
52 #endif
53 #ifdef SIGTRAP
54 { SIGTRAP, T },
55 #endif
56 #ifdef SIGABRT
57 { SIGABRT, N + T },
58 #endif
59 #ifdef SIGBUS
60 { SIGBUS, P },
61 #endif
62 #ifdef SIGFPE
63 { SIGFPE, P },
64 #endif
65 #ifdef SIGUSR1
66 { SIGUSR1, N },
67 #endif
68 #ifdef SIGSEGV
69 { SIGSEGV, P },
70 #endif
71 #ifdef SIGUSR2
72 { SIGUSR2, N },
73 #endif
74 #ifdef SIGPIPE
75 { SIGPIPE, N },
76 #endif
77 #ifdef SIGALRM
78 { SIGALRM, N },
79 #endif
80 #ifdef SIGTERM
81 { SIGTERM, N + K },
82 #endif
83 #ifdef SIGSTKFLT
84 { SIGSTKFLT, T },
85 #endif
86 #ifdef SIGCHLD
87 { SIGCHLD, N },
88 #endif
89 #ifdef SIGTSTP
90 { SIGTSTP, N + D },
91 #endif
92 #ifdef SIGTTIN
93 { SIGTTIN, N + D },
94 #endif
95 #ifdef SIGTTOU
96 { SIGTTOU, N + D },
97 #endif
98 #ifdef SIGURG
99 { SIGURG, N },
100 #endif
101 #ifdef SIGXCPU
102 { SIGXCPU, N },
103 #endif
104 #ifdef SIGXFSZ
105 { SIGXFSZ, N },
106 #endif
107 #ifdef SIGVTALRM
108 { SIGVTALRM, N },
109 #endif
110 #ifdef SIGPROF
111 { SIGPROF, N },
112 #endif
113 #ifdef SIGWINCH
114 { SIGWINCH, N },
115 #endif
116 #ifdef SIGIO
117 { SIGIO, N },
118 #endif
119 #ifdef SIGPWR
120 { SIGPWR, N },
121 #endif
122 #ifdef SIGSYS
123 { SIGSYS, N },
124 #endif
125 #ifdef SIGEMT
126 { SIGEMT, T },
127 #endif
128 #ifdef SIGINFO
129 { SIGINFO, N },
130 #endif
131 #ifdef SIGTHR
132 { SIGTHR, N },
133 #endif
134 { -1, 0 }
136 #undef N
137 #undef K
138 #undef T
139 #undef P
140 #undef D
143 static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n";
145 static void
146 runtime_badsignal(int32 sig)
148 // Avoid -D_FORTIFY_SOURCE problems.
149 int rv __attribute__((unused));
151 if (sig == SIGPROF) {
152 return; // Ignore SIGPROFs intended for a non-Go thread.
154 rv = runtime_write(2, badsignal, sizeof badsignal - 1);
155 runtime_exit(1);
158 /* Handle a signal, for cases where we don't panic. We can split the
159 stack here. */
161 void
162 runtime_sighandler (int sig, Siginfo *info,
163 void *context __attribute__ ((unused)), G *gp)
165 M *m;
166 int i;
168 m = runtime_m ();
170 #ifdef SIGPROF
171 if (sig == SIGPROF)
173 if (m != NULL && gp != m->g0 && gp != m->gsignal)
174 runtime_sigprof ();
175 return;
177 #endif
179 if (m == NULL)
181 runtime_badsignal (sig);
182 return;
185 for (i = 0; runtime_sigtab[i].sig != -1; ++i)
187 SigTab *t;
188 bool notify, crash;
190 t = &runtime_sigtab[i];
192 if (t->sig != sig)
193 continue;
195 notify = false;
196 #ifdef SA_SIGINFO
197 notify = info != NULL && info->si_code == SI_USER;
198 #endif
199 if (notify || (t->flags & SigNotify) != 0)
201 if (__go_sigsend (sig))
202 return;
204 if ((t->flags & SigKill) != 0)
205 runtime_exit (2);
206 if ((t->flags & SigThrow) == 0)
207 return;
209 runtime_startpanic ();
212 const char *name = NULL;
214 #ifdef HAVE_STRSIGNAL
215 name = strsignal (sig);
216 #endif
218 if (name == NULL)
219 runtime_printf ("Signal %d\n", sig);
220 else
221 runtime_printf ("%s\n", name);
224 if (m->lockedg != NULL && m->ncgo > 0 && gp == m->g0)
226 runtime_printf("signal arrived during cgo execution\n");
227 gp = m->lockedg;
230 runtime_printf ("\n");
232 if (runtime_gotraceback (&crash))
234 G *g;
236 g = runtime_g ();
237 runtime_traceback (g);
238 runtime_tracebackothers (g);
240 /* The gc library calls runtime_dumpregs here, and provides
241 a function that prints the registers saved in context in
242 a readable form. */
245 if (crash)
246 runtime_crash ();
248 runtime_exit (2);
251 __builtin_unreachable ();
254 /* The start of handling a signal which panics. */
256 static void
257 sig_panic_leadin (int sig)
259 int i;
260 sigset_t clear;
262 if (runtime_m ()->mallocing)
264 runtime_printf ("caught signal while mallocing: %d\n", sig);
265 runtime_throw ("caught signal while mallocing");
268 /* The signal handler blocked signals; unblock them. */
269 i = sigfillset (&clear);
270 __go_assert (i == 0);
271 i = sigprocmask (SIG_UNBLOCK, &clear, NULL);
272 __go_assert (i == 0);
275 #ifdef SA_SIGINFO
277 /* Signal dispatch for signals which panic, on systems which support
278 SA_SIGINFO. This is called on the thread stack, and as such it is
279 permitted to split the stack. */
281 static void
282 sig_panic_info_handler (int sig, Siginfo *info, void *context)
284 G *g;
286 g = runtime_g ();
287 if (g == NULL || info->si_code == SI_USER)
289 runtime_sighandler (sig, info, context, g);
290 return;
293 g->sig = sig;
294 g->sigcode0 = info->si_code;
295 g->sigcode1 = (uintptr_t) info->si_addr;
297 /* It would be nice to set g->sigpc here as the gc library does, but
298 I don't know how to get it portably. */
300 sig_panic_leadin (sig);
302 switch (sig)
304 #ifdef SIGBUS
305 case SIGBUS:
306 if (info->si_code == BUS_ADRERR && (uintptr_t) info->si_addr < 0x1000)
307 runtime_panicstring ("invalid memory address or "
308 "nil pointer dereference");
309 runtime_printf ("unexpected fault address %p\n", info->si_addr);
310 runtime_throw ("fault");
311 #endif
313 #ifdef SIGSEGV
314 case SIGSEGV:
315 if ((info->si_code == 0
316 || info->si_code == SEGV_MAPERR
317 || info->si_code == SEGV_ACCERR)
318 && (uintptr_t) info->si_addr < 0x1000)
319 runtime_panicstring ("invalid memory address or "
320 "nil pointer dereference");
321 runtime_printf ("unexpected fault address %p\n", info->si_addr);
322 runtime_throw ("fault");
323 #endif
325 #ifdef SIGFPE
326 case SIGFPE:
327 switch (info->si_code)
329 case FPE_INTDIV:
330 runtime_panicstring ("integer divide by zero");
331 case FPE_INTOVF:
332 runtime_panicstring ("integer overflow");
334 runtime_panicstring ("floating point error");
335 #endif
338 /* All signals with SigPanic should be in cases above, and this
339 handler should only be invoked for those signals. */
340 __builtin_unreachable ();
343 #else /* !defined (SA_SIGINFO) */
345 static void
346 sig_panic_handler (int sig)
348 G *g;
350 g = runtime_g ();
351 if (g == NULL)
353 runtime_sighandler (sig, NULL, NULL, g);
354 return;
357 g->sig = sig;
358 g->sigcode0 = 0;
359 g->sigcode1 = 0;
361 sig_panic_leadin (sig);
363 switch (sig)
365 #ifdef SIGBUS
366 case SIGBUS:
367 runtime_panicstring ("invalid memory address or "
368 "nil pointer dereference");
369 #endif
371 #ifdef SIGSEGV
372 case SIGSEGV:
373 runtime_panicstring ("invalid memory address or "
374 "nil pointer dereference");
375 #endif
377 #ifdef SIGFPE
378 case SIGFPE:
379 runtime_panicstring ("integer divide by zero or floating point error");
380 #endif
383 /* All signals with SigPanic should be in cases above, and this
384 handler should only be invoked for those signals. */
385 __builtin_unreachable ();
388 #endif /* !defined (SA_SIGINFO) */
390 /* A signal handler used for signals which are not going to panic.
391 This is called on the alternate signal stack so it may not split
392 the stack. */
394 static void
395 sig_tramp_info (int, Siginfo *, void *) __attribute__ ((no_split_stack));
397 static void
398 sig_tramp_info (int sig, Siginfo *info, void *context)
400 G *gp;
401 M *mp;
402 #ifdef USING_SPLIT_STACK
403 void *stack_context[10];
404 #endif
406 /* We are now running on the stack registered via sigaltstack.
407 (Actually there is a small span of time between runtime_siginit
408 and sigaltstack when the program starts.) */
409 gp = runtime_g ();
410 mp = runtime_m ();
412 if (gp != NULL)
414 #ifdef USING_SPLIT_STACK
415 __splitstack_getcontext (&stack_context[0]);
416 #endif
419 if (gp != NULL && mp->gsignal != NULL)
421 /* We are running on the signal stack. Set the split stack
422 context so that the stack guards are checked correctly. */
423 #ifdef USING_SPLIT_STACK
424 __splitstack_setcontext (&mp->gsignal->stack_context[0]);
425 #endif
428 runtime_sighandler (sig, info, context, gp);
430 /* We are going to return back to the signal trampoline and then to
431 whatever we were doing before we got the signal. Restore the
432 split stack context so that stack guards are checked
433 correctly. */
435 if (gp != NULL)
437 #ifdef USING_SPLIT_STACK
438 __splitstack_setcontext (&stack_context[0]);
439 #endif
443 #ifndef SA_SIGINFO
445 static void sig_tramp (int sig) __attribute__ ((no_split_stack));
447 static void
448 sig_tramp (int sig)
450 sig_tramp_info (sig, NULL, NULL);
453 #endif
455 void
456 runtime_setsig (int32 i, GoSighandler *fn, bool restart)
458 struct sigaction sa;
459 int r;
460 SigTab *t;
462 memset (&sa, 0, sizeof sa);
464 r = sigfillset (&sa.sa_mask);
465 __go_assert (r == 0);
467 t = &runtime_sigtab[i];
469 if ((t->flags & SigPanic) == 0)
471 #ifdef SA_SIGINFO
472 sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
473 if (fn == runtime_sighandler)
474 fn = (void *) sig_tramp_info;
475 sa.sa_sigaction = (void *) fn;
476 #else
477 sa.sa_flags = SA_ONSTACK;
478 if (fn == runtime_sighandler)
479 fn = (void *) sig_tramp;
480 sa.sa_handler = (void *) fn;
481 #endif
483 else
485 #ifdef SA_SIGINFO
486 sa.sa_flags = SA_SIGINFO;
487 if (fn == runtime_sighandler)
488 fn = (void *) sig_panic_info_handler;
489 sa.sa_sigaction = (void *) fn;
490 #else
491 sa.sa_flags = 0;
492 if (fn == runtime_sighandler)
493 fn = (void *) sig_panic_handler;
494 sa.sa_handler = (void *) fn;
495 #endif
498 if (restart)
499 sa.sa_flags |= SA_RESTART;
501 if (sigaction (t->sig, &sa, NULL) != 0)
502 __go_assert (0);
505 GoSighandler*
506 runtime_getsig (int32 i)
508 struct sigaction sa;
509 int r;
510 SigTab *t;
512 memset (&sa, 0, sizeof sa);
514 r = sigemptyset (&sa.sa_mask);
515 __go_assert (r == 0);
517 t = &runtime_sigtab[i];
519 if (sigaction (t->sig, NULL, &sa) != 0)
520 runtime_throw ("sigaction read failure");
522 if ((void *) sa.sa_handler == sig_tramp_info)
523 return runtime_sighandler;
524 #ifdef SA_SIGINFO
525 if ((void *) sa.sa_handler == sig_panic_info_handler)
526 return runtime_sighandler;
527 #else
528 if ((void *) sa.sa_handler == sig_tramp
529 || (void *) sa.sa_handler == sig_panic_handler)
530 return runtime_sighandler;
531 #endif
533 return (void *) sa.sa_handler;
536 /* Used by the os package to raise SIGPIPE. */
538 void os_sigpipe (void) __asm__ (GOSYM_PREFIX "os.sigpipe");
540 void
541 os_sigpipe (void)
543 struct sigaction sa;
544 int i;
546 memset (&sa, 0, sizeof sa);
548 sa.sa_handler = SIG_DFL;
550 i = sigemptyset (&sa.sa_mask);
551 __go_assert (i == 0);
553 if (sigaction (SIGPIPE, &sa, NULL) != 0)
554 abort ();
556 raise (SIGPIPE);
559 void
560 runtime_setprof(bool on)
562 USED(on);