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.) */
349 __splitstack_getcontext (&gp->stack_context[0]);
351 if (gp != NULL && mp->gsignal != NULL)
353 /* We are running on the signal stack. Set the split stack
354 context so that the stack guards are checked correctly. */
355 #ifdef USING_SPLIT_STACK
356 __splitstack_setcontext (&mp->gsignal->stack_context[0]);
362 /* We are going to return back to the signal trampoline and then to
363 whatever we were doing before we got the signal. Restore the
364 split stack context so that stack guards are checked
369 #ifdef USING_SPLIT_STACK
370 __splitstack_setcontext (&gp->stack_context[0]);
375 /* Initialize signal handling for Go. This is called when the program
379 runtime_initsig (int32 queue)
386 memset (&sa, 0, sizeof sa);
388 i = sigfillset (&sa.sa_mask);
389 __go_assert (i == 0);
391 for (i = 0; runtime_sigtab[i].sig != -1; ++i)
393 if (runtime_sigtab[i].flags == 0)
395 if ((runtime_sigtab[i].flags & SigQueue) != queue)
398 if ((runtime_sigtab[i].flags & (SigCatch | SigQueue)) != 0)
400 if ((runtime_sigtab[i].flags & SigPanic) == 0)
402 sa.sa_flags = SA_ONSTACK;
403 sa.sa_handler = sig_tramp;
408 sa.sa_flags = SA_SIGINFO;
409 sa.sa_sigaction = sig_panic_info_handler;
412 sa.sa_handler = sig_panic_handler;
418 sa.sa_flags = SA_ONSTACK;
419 sa.sa_handler = sig_ignore;
422 if ((runtime_sigtab[i].flags & SigRestart) != 0)
423 sa.sa_flags |= SA_RESTART;
425 if (sigaction (runtime_sigtab[i].sig, &sa, NULL) != 0)
431 runtime_resetcpuprofiler(int32 hz)
438 memset (&it, 0, sizeof it);
440 memset (&sa, 0, sizeof sa);
441 i = sigfillset (&sa.sa_mask);
442 __go_assert (i == 0);
446 i = setitimer (ITIMER_PROF, &it, NULL);
447 __go_assert (i == 0);
449 sa.sa_handler = SIG_IGN;
450 i = sigaction (SIGPROF, &sa, NULL);
451 __go_assert (i == 0);
455 sa.sa_handler = sig_handler;
456 sa.sa_flags = SA_RESTART;
457 i = sigaction (SIGPROF, &sa, NULL);
458 __go_assert (i == 0);
460 it.it_interval.tv_sec = 0;
461 it.it_interval.tv_usec = 1000000 / hz;
462 it.it_value = it.it_interval;
463 i = setitimer (ITIMER_PROF, &it, NULL);
464 __go_assert (i == 0);
468 runtime_m()->profilehz = hz;
471 /* Used by the os package to raise SIGPIPE. */
473 void os_sigpipe (void) __asm__ ("libgo_os.os.sigpipe");
481 memset (&sa, 0, sizeof sa);
483 sa.sa_handler = SIG_DFL;
485 i = sigemptyset (&sa.sa_mask);
486 __go_assert (i == 0);
488 if (sigaction (SIGPIPE, &sa, NULL) != 0)