2016-07-13 Thomas Preud'homme <thomas.preudhomme@arm.com>
[official-gcc.git] / libgo / runtime / go-signal.c
bloba948c31cca096ae7c1c2a497a2b37f813742c444
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 and SIGSTOP are
37 not listed, as we don't want to set signal handlers for them. */
39 SigTab runtime_sigtab[] = {
40 #ifdef SIGHUP
41 { SIGHUP, N + K, NULL },
42 #endif
43 #ifdef SIGINT
44 { SIGINT, N + K, NULL },
45 #endif
46 #ifdef SIGQUIT
47 { SIGQUIT, N + T, NULL },
48 #endif
49 #ifdef SIGILL
50 { SIGILL, T, NULL },
51 #endif
52 #ifdef SIGTRAP
53 { SIGTRAP, T, NULL },
54 #endif
55 #ifdef SIGABRT
56 { SIGABRT, N + T, NULL },
57 #endif
58 #ifdef SIGBUS
59 { SIGBUS, P, NULL },
60 #endif
61 #ifdef SIGFPE
62 { SIGFPE, P, NULL },
63 #endif
64 #ifdef SIGUSR1
65 { SIGUSR1, N, NULL },
66 #endif
67 #ifdef SIGSEGV
68 { SIGSEGV, P, NULL },
69 #endif
70 #ifdef SIGUSR2
71 { SIGUSR2, N, NULL },
72 #endif
73 #ifdef SIGPIPE
74 { SIGPIPE, N, NULL },
75 #endif
76 #ifdef SIGALRM
77 { SIGALRM, N, NULL },
78 #endif
79 #ifdef SIGTERM
80 { SIGTERM, N + K, NULL },
81 #endif
82 #ifdef SIGSTKFLT
83 { SIGSTKFLT, T, NULL },
84 #endif
85 #ifdef SIGCHLD
86 { SIGCHLD, N, NULL },
87 #endif
88 #ifdef SIGCONT
89 { SIGCONT, N + D, NULL },
90 #endif
91 #ifdef SIGTSTP
92 { SIGTSTP, N + D, NULL },
93 #endif
94 #ifdef SIGTTIN
95 { SIGTTIN, N + D, NULL },
96 #endif
97 #ifdef SIGTTOU
98 { SIGTTOU, N + D, NULL },
99 #endif
100 #ifdef SIGURG
101 { SIGURG, N, NULL },
102 #endif
103 #ifdef SIGXCPU
104 { SIGXCPU, N, NULL },
105 #endif
106 #ifdef SIGXFSZ
107 { SIGXFSZ, N, NULL },
108 #endif
109 #ifdef SIGVTALRM
110 { SIGVTALRM, N, NULL },
111 #endif
112 #ifdef SIGPROF
113 { SIGPROF, N, NULL },
114 #endif
115 #ifdef SIGWINCH
116 { SIGWINCH, N, NULL },
117 #endif
118 #ifdef SIGIO
119 { SIGIO, N, NULL },
120 #endif
121 #ifdef SIGPWR
122 { SIGPWR, N, NULL },
123 #endif
124 #ifdef SIGSYS
125 { SIGSYS, N, NULL },
126 #endif
127 #ifdef SIGEMT
128 { SIGEMT, T, NULL },
129 #endif
130 #ifdef SIGINFO
131 { SIGINFO, N, NULL },
132 #endif
133 #ifdef SIGTHR
134 { SIGTHR, N, NULL },
135 #endif
136 { -1, 0, NULL }
138 #undef N
139 #undef K
140 #undef T
141 #undef P
142 #undef D
144 /* Handle a signal, for cases where we don't panic. We can split the
145 stack here. */
147 void
148 runtime_sighandler (int sig, Siginfo *info,
149 void *context __attribute__ ((unused)), G *gp)
151 M *m;
152 int i;
154 m = runtime_m ();
156 #ifdef SIGPROF
157 if (sig == SIGPROF)
159 if (m != NULL && gp != m->g0 && gp != m->gsignal)
160 runtime_sigprof ();
161 return;
163 #endif
165 if (m == NULL)
167 runtime_badsignal (sig);
168 return;
171 for (i = 0; runtime_sigtab[i].sig != -1; ++i)
173 SigTab *t;
174 bool notify, crash;
176 t = &runtime_sigtab[i];
178 if (t->sig != sig)
179 continue;
181 notify = false;
182 #ifdef SA_SIGINFO
183 notify = info != NULL && info->si_code == SI_USER;
184 #endif
185 if (notify || (t->flags & SigNotify) != 0)
187 if (__go_sigsend (sig))
188 return;
190 if ((t->flags & SigKill) != 0)
191 runtime_exit (2);
192 if ((t->flags & SigThrow) == 0)
193 return;
195 runtime_startpanic ();
198 const char *name = NULL;
200 #ifdef HAVE_STRSIGNAL
201 name = strsignal (sig);
202 #endif
204 if (name == NULL)
205 runtime_printf ("Signal %d\n", sig);
206 else
207 runtime_printf ("%s\n", name);
210 if (m->lockedg != NULL && m->ncgo > 0 && gp == m->g0)
212 runtime_printf("signal arrived during cgo execution\n");
213 gp = m->lockedg;
216 runtime_printf ("\n");
218 if (runtime_gotraceback (&crash))
220 G *g;
222 g = runtime_g ();
223 runtime_traceback ();
224 runtime_tracebackothers (g);
226 /* The gc library calls runtime_dumpregs here, and provides
227 a function that prints the registers saved in context in
228 a readable form. */
231 if (crash)
232 runtime_crash ();
234 runtime_exit (2);
237 __builtin_unreachable ();
240 /* The start of handling a signal which panics. */
242 static void
243 sig_panic_leadin (G *gp)
245 int i;
246 sigset_t clear;
248 if (!runtime_canpanic (gp))
249 runtime_throw ("unexpected signal during runtime execution");
251 /* The signal handler blocked signals; unblock them. */
252 i = sigfillset (&clear);
253 __go_assert (i == 0);
254 i = pthread_sigmask (SIG_UNBLOCK, &clear, NULL);
255 __go_assert (i == 0);
258 #ifdef SA_SIGINFO
260 /* Signal dispatch for signals which panic, on systems which support
261 SA_SIGINFO. This is called on the thread stack, and as such it is
262 permitted to split the stack. */
264 static void
265 sig_panic_info_handler (int sig, Siginfo *info, void *context)
267 G *g;
269 g = runtime_g ();
270 if (g == NULL || info->si_code == SI_USER)
272 runtime_sighandler (sig, info, context, g);
273 return;
276 g->sig = sig;
277 g->sigcode0 = info->si_code;
278 g->sigcode1 = (uintptr_t) info->si_addr;
280 /* It would be nice to set g->sigpc here as the gc library does, but
281 I don't know how to get it portably. */
283 sig_panic_leadin (g);
285 switch (sig)
287 #ifdef SIGBUS
288 case SIGBUS:
289 if ((info->si_code == BUS_ADRERR && (uintptr_t) info->si_addr < 0x1000)
290 || g->paniconfault)
291 runtime_panicstring ("invalid memory address or "
292 "nil pointer dereference");
293 runtime_printf ("unexpected fault address %p\n", info->si_addr);
294 runtime_throw ("fault");
295 #endif
297 #ifdef SIGSEGV
298 case SIGSEGV:
299 if (((info->si_code == 0
300 || info->si_code == SEGV_MAPERR
301 || info->si_code == SEGV_ACCERR)
302 && (uintptr_t) info->si_addr < 0x1000)
303 || g->paniconfault)
304 runtime_panicstring ("invalid memory address or "
305 "nil pointer dereference");
306 runtime_printf ("unexpected fault address %p\n", info->si_addr);
307 runtime_throw ("fault");
308 #endif
310 #ifdef SIGFPE
311 case SIGFPE:
312 switch (info->si_code)
314 case FPE_INTDIV:
315 runtime_panicstring ("integer divide by zero");
316 case FPE_INTOVF:
317 runtime_panicstring ("integer overflow");
319 runtime_panicstring ("floating point error");
320 #endif
323 /* All signals with SigPanic should be in cases above, and this
324 handler should only be invoked for those signals. */
325 __builtin_unreachable ();
328 #else /* !defined (SA_SIGINFO) */
330 static void
331 sig_panic_handler (int sig)
333 G *g;
335 g = runtime_g ();
336 if (g == NULL)
338 runtime_sighandler (sig, NULL, NULL, g);
339 return;
342 g->sig = sig;
343 g->sigcode0 = 0;
344 g->sigcode1 = 0;
346 sig_panic_leadin (g);
348 switch (sig)
350 #ifdef SIGBUS
351 case SIGBUS:
352 runtime_panicstring ("invalid memory address or "
353 "nil pointer dereference");
354 #endif
356 #ifdef SIGSEGV
357 case SIGSEGV:
358 runtime_panicstring ("invalid memory address or "
359 "nil pointer dereference");
360 #endif
362 #ifdef SIGFPE
363 case SIGFPE:
364 runtime_panicstring ("integer divide by zero or floating point error");
365 #endif
368 /* All signals with SigPanic should be in cases above, and this
369 handler should only be invoked for those signals. */
370 __builtin_unreachable ();
373 #endif /* !defined (SA_SIGINFO) */
375 /* A signal handler used for signals which are not going to panic.
376 This is called on the alternate signal stack so it may not split
377 the stack. */
379 static void
380 sig_tramp_info (int, Siginfo *, void *) __attribute__ ((no_split_stack));
382 static void
383 sig_tramp_info (int sig, Siginfo *info, void *context)
385 G *gp;
386 M *mp;
387 #ifdef USING_SPLIT_STACK
388 void *stack_context[10];
389 #endif
391 /* We are now running on the stack registered via sigaltstack.
392 (Actually there is a small span of time between runtime_siginit
393 and sigaltstack when the program starts.) */
394 gp = runtime_g ();
395 mp = runtime_m ();
397 if (gp != NULL)
399 #ifdef USING_SPLIT_STACK
400 __splitstack_getcontext (&stack_context[0]);
401 #endif
404 if (gp != NULL && mp->gsignal != NULL)
406 /* We are running on the signal stack. Set the split stack
407 context so that the stack guards are checked correctly. */
408 #ifdef USING_SPLIT_STACK
409 __splitstack_setcontext (&mp->gsignal->stack_context[0]);
410 #endif
413 runtime_sighandler (sig, info, context, gp);
415 /* We are going to return back to the signal trampoline and then to
416 whatever we were doing before we got the signal. Restore the
417 split stack context so that stack guards are checked
418 correctly. */
420 if (gp != NULL)
422 #ifdef USING_SPLIT_STACK
423 __splitstack_setcontext (&stack_context[0]);
424 #endif
428 #ifndef SA_SIGINFO
430 static void sig_tramp (int sig) __attribute__ ((no_split_stack));
432 static void
433 sig_tramp (int sig)
435 sig_tramp_info (sig, NULL, NULL);
438 #endif
440 void
441 runtime_setsig (int32 i, GoSighandler *fn, bool restart)
443 struct sigaction sa;
444 int r;
445 SigTab *t;
447 memset (&sa, 0, sizeof sa);
449 r = sigfillset (&sa.sa_mask);
450 __go_assert (r == 0);
452 t = &runtime_sigtab[i];
454 if ((t->flags & SigPanic) == 0)
456 #ifdef SA_SIGINFO
457 sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
458 if (fn == runtime_sighandler)
459 fn = (void *) sig_tramp_info;
460 sa.sa_sigaction = (void *) fn;
461 #else
462 sa.sa_flags = SA_ONSTACK;
463 if (fn == runtime_sighandler)
464 fn = (void *) sig_tramp;
465 sa.sa_handler = (void *) fn;
466 #endif
468 else
470 #ifdef SA_SIGINFO
471 sa.sa_flags = SA_SIGINFO;
472 if (fn == runtime_sighandler)
473 fn = (void *) sig_panic_info_handler;
474 sa.sa_sigaction = (void *) fn;
475 #else
476 sa.sa_flags = 0;
477 if (fn == runtime_sighandler)
478 fn = (void *) sig_panic_handler;
479 sa.sa_handler = (void *) fn;
480 #endif
483 if (restart)
484 sa.sa_flags |= SA_RESTART;
486 if (sigaction (t->sig, &sa, NULL) != 0)
487 __go_assert (0);
490 GoSighandler*
491 runtime_getsig (int32 i)
493 struct sigaction sa;
494 int r;
495 SigTab *t;
497 memset (&sa, 0, sizeof sa);
499 r = sigemptyset (&sa.sa_mask);
500 __go_assert (r == 0);
502 t = &runtime_sigtab[i];
504 if (sigaction (t->sig, NULL, &sa) != 0)
505 runtime_throw ("sigaction read failure");
507 if ((void *) sa.sa_handler == sig_tramp_info)
508 return runtime_sighandler;
509 #ifdef SA_SIGINFO
510 if ((void *) sa.sa_handler == sig_panic_info_handler)
511 return runtime_sighandler;
512 #else
513 if ((void *) sa.sa_handler == sig_tramp
514 || (void *) sa.sa_handler == sig_panic_handler)
515 return runtime_sighandler;
516 #endif
518 return (void *) sa.sa_handler;
521 /* Used by the os package to raise SIGPIPE. */
523 void os_sigpipe (void) __asm__ (GOSYM_PREFIX "os.sigpipe");
525 void
526 os_sigpipe (void)
528 struct sigaction sa;
529 int i;
531 if (__go_sigsend (SIGPIPE))
532 return;
534 memset (&sa, 0, sizeof sa);
536 sa.sa_handler = SIG_DFL;
538 i = sigemptyset (&sa.sa_mask);
539 __go_assert (i == 0);
541 if (sigaction (SIGPIPE, &sa, NULL) != 0)
542 abort ();
544 raise (SIGPIPE);
547 void
548 runtime_setprof(bool on)
550 USED(on);