toplev: gcc version information for jit
[official-gcc.git] / libgo / runtime / go-signal.c
blob4a1bf5636e50ec77dcf307a6b66a5569bbb5ba04
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
142 /* Handle a signal, for cases where we don't panic. We can split the
143 stack here. */
145 void
146 runtime_sighandler (int sig, Siginfo *info,
147 void *context __attribute__ ((unused)), G *gp)
149 M *m;
150 int i;
152 m = runtime_m ();
154 #ifdef SIGPROF
155 if (sig == SIGPROF)
157 if (m != NULL && gp != m->g0 && gp != m->gsignal)
158 runtime_sigprof ();
159 return;
161 #endif
163 if (m == NULL)
165 runtime_badsignal (sig);
166 return;
169 for (i = 0; runtime_sigtab[i].sig != -1; ++i)
171 SigTab *t;
172 bool notify, crash;
174 t = &runtime_sigtab[i];
176 if (t->sig != sig)
177 continue;
179 notify = false;
180 #ifdef SA_SIGINFO
181 notify = info != NULL && info->si_code == SI_USER;
182 #endif
183 if (notify || (t->flags & SigNotify) != 0)
185 if (__go_sigsend (sig))
186 return;
188 if ((t->flags & SigKill) != 0)
189 runtime_exit (2);
190 if ((t->flags & SigThrow) == 0)
191 return;
193 runtime_startpanic ();
196 const char *name = NULL;
198 #ifdef HAVE_STRSIGNAL
199 name = strsignal (sig);
200 #endif
202 if (name == NULL)
203 runtime_printf ("Signal %d\n", sig);
204 else
205 runtime_printf ("%s\n", name);
208 if (m->lockedg != NULL && m->ncgo > 0 && gp == m->g0)
210 runtime_printf("signal arrived during cgo execution\n");
211 gp = m->lockedg;
214 runtime_printf ("\n");
216 if (runtime_gotraceback (&crash))
218 G *g;
220 g = runtime_g ();
221 runtime_traceback ();
222 runtime_tracebackothers (g);
224 /* The gc library calls runtime_dumpregs here, and provides
225 a function that prints the registers saved in context in
226 a readable form. */
229 if (crash)
230 runtime_crash ();
232 runtime_exit (2);
235 __builtin_unreachable ();
238 /* The start of handling a signal which panics. */
240 static void
241 sig_panic_leadin (G *gp)
243 int i;
244 sigset_t clear;
246 if (!runtime_canpanic (gp))
247 runtime_throw ("unexpected signal during runtime execution");
249 /* The signal handler blocked signals; unblock them. */
250 i = sigfillset (&clear);
251 __go_assert (i == 0);
252 i = pthread_sigmask (SIG_UNBLOCK, &clear, NULL);
253 __go_assert (i == 0);
256 #ifdef SA_SIGINFO
258 /* Signal dispatch for signals which panic, on systems which support
259 SA_SIGINFO. This is called on the thread stack, and as such it is
260 permitted to split the stack. */
262 static void
263 sig_panic_info_handler (int sig, Siginfo *info, void *context)
265 G *g;
267 g = runtime_g ();
268 if (g == NULL || info->si_code == SI_USER)
270 runtime_sighandler (sig, info, context, g);
271 return;
274 g->sig = sig;
275 g->sigcode0 = info->si_code;
276 g->sigcode1 = (uintptr_t) info->si_addr;
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. */
281 sig_panic_leadin (g);
283 switch (sig)
285 #ifdef SIGBUS
286 case SIGBUS:
287 if ((info->si_code == BUS_ADRERR && (uintptr_t) info->si_addr < 0x1000)
288 || g->paniconfault)
289 runtime_panicstring ("invalid memory address or "
290 "nil pointer dereference");
291 runtime_printf ("unexpected fault address %p\n", info->si_addr);
292 runtime_throw ("fault");
293 #endif
295 #ifdef SIGSEGV
296 case SIGSEGV:
297 if (((info->si_code == 0
298 || info->si_code == SEGV_MAPERR
299 || info->si_code == SEGV_ACCERR)
300 && (uintptr_t) info->si_addr < 0x1000)
301 || g->paniconfault)
302 runtime_panicstring ("invalid memory address or "
303 "nil pointer dereference");
304 runtime_printf ("unexpected fault address %p\n", info->si_addr);
305 runtime_throw ("fault");
306 #endif
308 #ifdef SIGFPE
309 case SIGFPE:
310 switch (info->si_code)
312 case FPE_INTDIV:
313 runtime_panicstring ("integer divide by zero");
314 case FPE_INTOVF:
315 runtime_panicstring ("integer overflow");
317 runtime_panicstring ("floating point error");
318 #endif
321 /* All signals with SigPanic should be in cases above, and this
322 handler should only be invoked for those signals. */
323 __builtin_unreachable ();
326 #else /* !defined (SA_SIGINFO) */
328 static void
329 sig_panic_handler (int sig)
331 G *g;
333 g = runtime_g ();
334 if (g == NULL)
336 runtime_sighandler (sig, NULL, NULL, g);
337 return;
340 g->sig = sig;
341 g->sigcode0 = 0;
342 g->sigcode1 = 0;
344 sig_panic_leadin (g);
346 switch (sig)
348 #ifdef SIGBUS
349 case SIGBUS:
350 runtime_panicstring ("invalid memory address or "
351 "nil pointer dereference");
352 #endif
354 #ifdef SIGSEGV
355 case SIGSEGV:
356 runtime_panicstring ("invalid memory address or "
357 "nil pointer dereference");
358 #endif
360 #ifdef SIGFPE
361 case SIGFPE:
362 runtime_panicstring ("integer divide by zero or floating point error");
363 #endif
366 /* All signals with SigPanic should be in cases above, and this
367 handler should only be invoked for those signals. */
368 __builtin_unreachable ();
371 #endif /* !defined (SA_SIGINFO) */
373 /* A signal handler used for signals which are not going to panic.
374 This is called on the alternate signal stack so it may not split
375 the stack. */
377 static void
378 sig_tramp_info (int, Siginfo *, void *) __attribute__ ((no_split_stack));
380 static void
381 sig_tramp_info (int sig, Siginfo *info, void *context)
383 G *gp;
384 M *mp;
385 #ifdef USING_SPLIT_STACK
386 void *stack_context[10];
387 #endif
389 /* We are now running on the stack registered via sigaltstack.
390 (Actually there is a small span of time between runtime_siginit
391 and sigaltstack when the program starts.) */
392 gp = runtime_g ();
393 mp = runtime_m ();
395 if (gp != NULL)
397 #ifdef USING_SPLIT_STACK
398 __splitstack_getcontext (&stack_context[0]);
399 #endif
402 if (gp != NULL && mp->gsignal != NULL)
404 /* We are running on the signal stack. Set the split stack
405 context so that the stack guards are checked correctly. */
406 #ifdef USING_SPLIT_STACK
407 __splitstack_setcontext (&mp->gsignal->stack_context[0]);
408 #endif
411 runtime_sighandler (sig, info, context, gp);
413 /* We are going to return back to the signal trampoline and then to
414 whatever we were doing before we got the signal. Restore the
415 split stack context so that stack guards are checked
416 correctly. */
418 if (gp != NULL)
420 #ifdef USING_SPLIT_STACK
421 __splitstack_setcontext (&stack_context[0]);
422 #endif
426 #ifndef SA_SIGINFO
428 static void sig_tramp (int sig) __attribute__ ((no_split_stack));
430 static void
431 sig_tramp (int sig)
433 sig_tramp_info (sig, NULL, NULL);
436 #endif
438 void
439 runtime_setsig (int32 i, GoSighandler *fn, bool restart)
441 struct sigaction sa;
442 int r;
443 SigTab *t;
445 memset (&sa, 0, sizeof sa);
447 r = sigfillset (&sa.sa_mask);
448 __go_assert (r == 0);
450 t = &runtime_sigtab[i];
452 if ((t->flags & SigPanic) == 0)
454 #ifdef SA_SIGINFO
455 sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
456 if (fn == runtime_sighandler)
457 fn = (void *) sig_tramp_info;
458 sa.sa_sigaction = (void *) fn;
459 #else
460 sa.sa_flags = SA_ONSTACK;
461 if (fn == runtime_sighandler)
462 fn = (void *) sig_tramp;
463 sa.sa_handler = (void *) fn;
464 #endif
466 else
468 #ifdef SA_SIGINFO
469 sa.sa_flags = SA_SIGINFO;
470 if (fn == runtime_sighandler)
471 fn = (void *) sig_panic_info_handler;
472 sa.sa_sigaction = (void *) fn;
473 #else
474 sa.sa_flags = 0;
475 if (fn == runtime_sighandler)
476 fn = (void *) sig_panic_handler;
477 sa.sa_handler = (void *) fn;
478 #endif
481 if (restart)
482 sa.sa_flags |= SA_RESTART;
484 if (sigaction (t->sig, &sa, NULL) != 0)
485 __go_assert (0);
488 GoSighandler*
489 runtime_getsig (int32 i)
491 struct sigaction sa;
492 int r;
493 SigTab *t;
495 memset (&sa, 0, sizeof sa);
497 r = sigemptyset (&sa.sa_mask);
498 __go_assert (r == 0);
500 t = &runtime_sigtab[i];
502 if (sigaction (t->sig, NULL, &sa) != 0)
503 runtime_throw ("sigaction read failure");
505 if ((void *) sa.sa_handler == sig_tramp_info)
506 return runtime_sighandler;
507 #ifdef SA_SIGINFO
508 if ((void *) sa.sa_handler == sig_panic_info_handler)
509 return runtime_sighandler;
510 #else
511 if ((void *) sa.sa_handler == sig_tramp
512 || (void *) sa.sa_handler == sig_panic_handler)
513 return runtime_sighandler;
514 #endif
516 return (void *) sa.sa_handler;
519 /* Used by the os package to raise SIGPIPE. */
521 void os_sigpipe (void) __asm__ (GOSYM_PREFIX "os.sigpipe");
523 void
524 os_sigpipe (void)
526 struct sigaction sa;
527 int i;
529 memset (&sa, 0, sizeof sa);
531 sa.sa_handler = SIG_DFL;
533 i = sigemptyset (&sa.sa_mask);
534 __go_assert (i == 0);
536 if (sigaction (SIGPIPE, &sa, NULL) != 0)
537 abort ();
539 raise (SIGPIPE);
542 void
543 runtime_setprof(bool on)
545 USED(on);