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. */
13 #include "go-assert.h"
20 #ifdef USING_SPLIT_STACK
22 extern void __splitstack_getcontext(void *context[10]);
24 extern void __splitstack_setcontext(void *context[10]);
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
39 SigTab runtime_sigtab[] = {
65 { SIGUSR1, Q + I + R },
71 { SIGUSR2, Q + I + R },
77 { SIGALRM, Q + I + R },
86 { SIGCHLD, Q + I + R },
89 { SIGTSTP, Q + I + R },
92 { SIGTTIN, Q + I + R },
95 { SIGTTOU, Q + I + R },
98 { SIGURG, Q + I + R },
101 { SIGXCPU, Q + I + R },
104 { SIGXFSZ, Q + I + R },
107 { SIGVTALRM, Q + I + R },
110 { SIGPROF, Q + I + R },
113 { SIGWINCH, Q + I + R },
116 { SIGIO, Q + I + R },
119 { SIGPWR, Q + I + R },
128 { SIGINFO, Q + I + R },
131 { SIGTHR, Q + I + R },
141 /* Handle a signal, for cases where we don't panic. We can split the
145 sig_handler (int sig)
153 runtime_sigprof (0, 0, nil, nil);
158 for (i = 0; runtime_sigtab[i].sig != -1; ++i)
162 if (runtime_sigtab[i].sig != sig)
165 if ((runtime_sigtab[i].flags & SigQueue) != 0)
167 if (__go_sigsend (sig)
168 || (runtime_sigtab[sig].flags & SigIgnore) != 0)
170 runtime_exit (2); // SIGINT, SIGTERM, etc
173 if (runtime_panicking)
175 runtime_panicking = 1;
177 /* We should do a stack backtrace here. Until we can do that,
178 we reraise the signal in order to get a slightly better
179 report from the shell. */
181 memset (&sa, 0, sizeof sa);
183 sa.sa_handler = SIG_DFL;
185 i = sigemptyset (&sa.sa_mask);
186 __go_assert (i == 0);
188 if (sigaction (sig, &sa, NULL) != 0)
196 __builtin_unreachable ();
199 /* The start of handling a signal which panics. */
202 sig_panic_leadin (int sig)
207 if (runtime_m ()->mallocing)
209 runtime_printf ("caught signal while mallocing: %d\n", sig);
210 runtime_throw ("caught signal while mallocing");
213 /* The signal handler blocked signals; unblock them. */
214 i = sigfillset (&clear);
215 __go_assert (i == 0);
216 i = sigprocmask (SIG_UNBLOCK, &clear, NULL);
217 __go_assert (i == 0);
222 /* Signal dispatch for signals which panic, on systems which support
223 SA_SIGINFO. This is called on the thread stack, and as such it is
224 permitted to split the stack. */
227 sig_panic_info_handler (int sig, siginfo_t *info,
228 void *context __attribute__ ((unused)))
230 if (runtime_g () == NULL)
236 sig_panic_leadin (sig);
242 if (info->si_code == BUS_ADRERR && (uintptr_t) info->si_addr < 0x1000)
243 runtime_panicstring ("invalid memory address or "
244 "nil pointer dereference");
245 runtime_printf ("unexpected fault address %p\n", info->si_addr);
246 runtime_throw ("fault");
251 if ((info->si_code == 0
252 || info->si_code == SEGV_MAPERR
253 || info->si_code == SEGV_ACCERR)
254 && (uintptr_t) info->si_addr < 0x1000)
255 runtime_panicstring ("invalid memory address or "
256 "nil pointer dereference");
257 runtime_printf ("unexpected fault address %p\n", info->si_addr);
258 runtime_throw ("fault");
263 switch (info->si_code)
266 runtime_panicstring ("integer divide by zero");
268 runtime_panicstring ("integer overflow");
270 runtime_panicstring ("floating point error");
274 /* All signals with SigPanic should be in cases above, and this
275 handler should only be invoked for those signals. */
276 __builtin_unreachable ();
279 #else /* !defined (SA_SIGINFO) */
282 sig_panic_handler (int sig)
284 if (runtime_g () == NULL)
290 sig_panic_leadin (sig);
296 runtime_panicstring ("invalid memory address or "
297 "nil pointer dereference");
302 runtime_panicstring ("invalid memory address or "
303 "nil pointer dereference");
308 runtime_panicstring ("integer divide by zero or floating point error");
312 /* All signals with SigPanic should be in cases above, and this
313 handler should only be invoked for those signals. */
314 __builtin_unreachable ();
317 #endif /* !defined (SA_SIGINFO) */
319 /* Ignore a signal. This is called on the alternate signal stack so
320 it may not split the stack. */
322 static void sig_ignore (int) __attribute__ ((no_split_stack));
325 sig_ignore (int sig __attribute__ ((unused)))
329 /* A signal handler used for signals which are not going to panic.
330 This is called on the alternate signal stack so it may not split
334 sig_tramp (int) __attribute__ ((no_split_stack));
342 /* We are now running on the stack registered via sigaltstack.
343 (Actually there is a small span of time between runtime_siginit
344 and sigaltstack when the program starts.) */
350 #ifdef USING_SPLIT_STACK
351 __splitstack_getcontext (&gp->stack_context[0]);
355 if (gp != NULL && mp->gsignal != NULL)
357 /* We are running on the signal stack. Set the split stack
358 context so that the stack guards are checked correctly. */
359 #ifdef USING_SPLIT_STACK
360 __splitstack_setcontext (&mp->gsignal->stack_context[0]);
366 /* We are going to return back to the signal trampoline and then to
367 whatever we were doing before we got the signal. Restore the
368 split stack context so that stack guards are checked
373 #ifdef USING_SPLIT_STACK
374 __splitstack_setcontext (&gp->stack_context[0]);
379 /* Initialize signal handling for Go. This is called when the program
383 runtime_initsig (int32 queue)
390 memset (&sa, 0, sizeof sa);
392 i = sigfillset (&sa.sa_mask);
393 __go_assert (i == 0);
395 for (i = 0; runtime_sigtab[i].sig != -1; ++i)
397 if (runtime_sigtab[i].flags == 0)
399 if ((runtime_sigtab[i].flags & SigQueue) != queue)
402 if ((runtime_sigtab[i].flags & (SigCatch | SigQueue)) != 0)
404 if ((runtime_sigtab[i].flags & SigPanic) == 0)
406 sa.sa_flags = SA_ONSTACK;
407 sa.sa_handler = sig_tramp;
412 sa.sa_flags = SA_SIGINFO;
413 sa.sa_sigaction = sig_panic_info_handler;
416 sa.sa_handler = sig_panic_handler;
422 sa.sa_flags = SA_ONSTACK;
423 sa.sa_handler = sig_ignore;
426 if ((runtime_sigtab[i].flags & SigRestart) != 0)
427 sa.sa_flags |= SA_RESTART;
429 if (sigaction (runtime_sigtab[i].sig, &sa, NULL) != 0)
435 runtime_resetcpuprofiler(int32 hz)
442 memset (&it, 0, sizeof it);
444 memset (&sa, 0, sizeof sa);
445 i = sigfillset (&sa.sa_mask);
446 __go_assert (i == 0);
450 i = setitimer (ITIMER_PROF, &it, NULL);
451 __go_assert (i == 0);
453 sa.sa_handler = SIG_IGN;
454 i = sigaction (SIGPROF, &sa, NULL);
455 __go_assert (i == 0);
459 sa.sa_handler = sig_handler;
460 sa.sa_flags = SA_RESTART;
461 i = sigaction (SIGPROF, &sa, NULL);
462 __go_assert (i == 0);
464 it.it_interval.tv_sec = 0;
465 it.it_interval.tv_usec = 1000000 / hz;
466 it.it_value = it.it_interval;
467 i = setitimer (ITIMER_PROF, &it, NULL);
468 __go_assert (i == 0);
472 runtime_m()->profilehz = hz;
475 /* Used by the os package to raise SIGPIPE. */
477 void os_sigpipe (void) __asm__ ("libgo_os.os.sigpipe");
485 memset (&sa, 0, sizeof sa);
487 sa.sa_handler = SIG_DFL;
489 i = sigemptyset (&sa.sa_mask);
490 __go_assert (i == 0);
492 if (sigaction (SIGPIPE, &sa, NULL) != 0)