* const-uniq-1.c: Expand regex to match AIX XCOFF labels.
[official-gcc.git] / libgo / runtime / go-signal.c
bloba1215f947e82641f97f97dd47e2b062a37d58d2e
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"
16 #ifndef SA_RESTART
17 #define SA_RESTART 0
18 #endif
20 #ifdef USING_SPLIT_STACK
22 extern void __splitstack_getcontext(void *context[10]);
24 extern void __splitstack_setcontext(void *context[10]);
26 #endif
28 #define N SigNotify
29 #define K SigKill
30 #define T SigThrow
31 #define P SigPanic
32 #define D SigDefault
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
37 them. */
39 SigTab runtime_sigtab[] = {
40 #ifdef SIGHUP
41 { SIGHUP, N + K },
42 #endif
43 #ifdef SIGINT
44 { SIGINT, N + K },
45 #endif
46 #ifdef SIGQUIT
47 { SIGQUIT, N + T },
48 #endif
49 #ifdef SIGILL
50 { SIGILL, T },
51 #endif
52 #ifdef SIGTRAP
53 { SIGTRAP, T },
54 #endif
55 #ifdef SIGABRT
56 { SIGABRT, N + T },
57 #endif
58 #ifdef SIGBUS
59 { SIGBUS, P },
60 #endif
61 #ifdef SIGFPE
62 { SIGFPE, P },
63 #endif
64 #ifdef SIGUSR1
65 { SIGUSR1, N },
66 #endif
67 #ifdef SIGSEGV
68 { SIGSEGV, P },
69 #endif
70 #ifdef SIGUSR2
71 { SIGUSR2, N },
72 #endif
73 #ifdef SIGPIPE
74 { SIGPIPE, N },
75 #endif
76 #ifdef SIGALRM
77 { SIGALRM, N },
78 #endif
79 #ifdef SIGTERM
80 { SIGTERM, N + K },
81 #endif
82 #ifdef SIGSTKFLT
83 { SIGSTKFLT, T },
84 #endif
85 #ifdef SIGCHLD
86 { SIGCHLD, N },
87 #endif
88 #ifdef SIGTSTP
89 { SIGTSTP, N + D },
90 #endif
91 #ifdef SIGTTIN
92 { SIGTTIN, N + D },
93 #endif
94 #ifdef SIGTTOU
95 { SIGTTOU, N + D },
96 #endif
97 #ifdef SIGURG
98 { SIGURG, N },
99 #endif
100 #ifdef SIGXCPU
101 { SIGXCPU, N },
102 #endif
103 #ifdef SIGXFSZ
104 { SIGXFSZ, N },
105 #endif
106 #ifdef SIGVTALRM
107 { SIGVTALRM, N },
108 #endif
109 #ifdef SIGPROF
110 { SIGPROF, N },
111 #endif
112 #ifdef SIGWINCH
113 { SIGWINCH, N },
114 #endif
115 #ifdef SIGIO
116 { SIGIO, N },
117 #endif
118 #ifdef SIGPWR
119 { SIGPWR, N },
120 #endif
121 #ifdef SIGSYS
122 { SIGSYS, N },
123 #endif
124 #ifdef SIGEMT
125 { SIGEMT, T },
126 #endif
127 #ifdef SIGINFO
128 { SIGINFO, N },
129 #endif
130 #ifdef SIGTHR
131 { SIGTHR, N },
132 #endif
133 { -1, 0 }
135 #undef N
136 #undef K
137 #undef T
138 #undef P
139 #undef D
142 static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n";
144 static void
145 runtime_badsignal(int32 sig)
147 if (sig == SIGPROF) {
148 return; // Ignore SIGPROFs intended for a non-Go thread.
150 runtime_write(2, badsignal, sizeof badsignal - 1);
151 runtime_exit(1);
154 /* Handle a signal, for cases where we don't panic. We can split the
155 stack here. */
157 static void
158 sig_handler (int sig)
160 int i;
162 if (runtime_m () == NULL)
164 runtime_badsignal (sig);
165 return;
168 #ifdef SIGPROF
169 if (sig == SIGPROF)
171 runtime_sigprof ();
172 return;
174 #endif
176 for (i = 0; runtime_sigtab[i].sig != -1; ++i)
178 SigTab *t;
180 t = &runtime_sigtab[i];
182 if (t->sig != sig)
183 continue;
185 if ((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 runtime_printf ("\n");
212 if (runtime_gotraceback ())
214 G *g;
216 g = runtime_g ();
217 runtime_traceback (g);
218 runtime_tracebackothers (g);
220 /* The gc library calls runtime_dumpregs here, and provides
221 a function that prints the registers saved in context in
222 a readable form. */
225 runtime_exit (2);
228 __builtin_unreachable ();
231 /* The start of handling a signal which panics. */
233 static void
234 sig_panic_leadin (int sig)
236 int i;
237 sigset_t clear;
239 if (runtime_m ()->mallocing)
241 runtime_printf ("caught signal while mallocing: %d\n", sig);
242 runtime_throw ("caught signal while mallocing");
245 /* The signal handler blocked signals; unblock them. */
246 i = sigfillset (&clear);
247 __go_assert (i == 0);
248 i = sigprocmask (SIG_UNBLOCK, &clear, NULL);
249 __go_assert (i == 0);
252 #ifdef SA_SIGINFO
254 /* Signal dispatch for signals which panic, on systems which support
255 SA_SIGINFO. This is called on the thread stack, and as such it is
256 permitted to split the stack. */
258 static void
259 sig_panic_info_handler (int sig, siginfo_t *info,
260 void *context __attribute__ ((unused)))
262 G *g;
264 g = runtime_g ();
265 if (g == NULL || info->si_code == SI_USER)
267 sig_handler (sig);
268 return;
271 g->sig = sig;
272 g->sigcode0 = info->si_code;
273 g->sigcode1 = (uintptr_t) info->si_addr;
275 /* It would be nice to set g->sigpc here as the gc library does, but
276 I don't know how to get it portably. */
278 sig_panic_leadin (sig);
280 switch (sig)
282 #ifdef SIGBUS
283 case SIGBUS:
284 if (info->si_code == BUS_ADRERR && (uintptr_t) info->si_addr < 0x1000)
285 runtime_panicstring ("invalid memory address or "
286 "nil pointer dereference");
287 runtime_printf ("unexpected fault address %p\n", info->si_addr);
288 runtime_throw ("fault");
289 #endif
291 #ifdef SIGSEGV
292 case SIGSEGV:
293 if ((info->si_code == 0
294 || info->si_code == SEGV_MAPERR
295 || info->si_code == SEGV_ACCERR)
296 && (uintptr_t) info->si_addr < 0x1000)
297 runtime_panicstring ("invalid memory address or "
298 "nil pointer dereference");
299 runtime_printf ("unexpected fault address %p\n", info->si_addr);
300 runtime_throw ("fault");
301 #endif
303 #ifdef SIGFPE
304 case SIGFPE:
305 switch (info->si_code)
307 case FPE_INTDIV:
308 runtime_panicstring ("integer divide by zero");
309 case FPE_INTOVF:
310 runtime_panicstring ("integer overflow");
312 runtime_panicstring ("floating point error");
313 #endif
316 /* All signals with SigPanic should be in cases above, and this
317 handler should only be invoked for those signals. */
318 __builtin_unreachable ();
321 #else /* !defined (SA_SIGINFO) */
323 static void
324 sig_panic_handler (int sig)
326 G *g;
328 g = runtime_g ();
329 if (g == NULL)
331 sig_handler (sig);
332 return;
335 g->sig = sig;
336 g->sigcode0 = 0;
337 g->sigcode1 = 0;
339 sig_panic_leadin (sig);
341 switch (sig)
343 #ifdef SIGBUS
344 case SIGBUS:
345 runtime_panicstring ("invalid memory address or "
346 "nil pointer dereference");
347 #endif
349 #ifdef SIGSEGV
350 case SIGSEGV:
351 runtime_panicstring ("invalid memory address or "
352 "nil pointer dereference");
353 #endif
355 #ifdef SIGFPE
356 case SIGFPE:
357 runtime_panicstring ("integer divide by zero or floating point error");
358 #endif
361 /* All signals with SigPanic should be in cases above, and this
362 handler should only be invoked for those signals. */
363 __builtin_unreachable ();
366 #endif /* !defined (SA_SIGINFO) */
368 /* A signal handler used for signals which are not going to panic.
369 This is called on the alternate signal stack so it may not split
370 the stack. */
372 static void
373 sig_tramp (int) __attribute__ ((no_split_stack));
375 static void
376 sig_tramp (int sig)
378 G *gp;
379 M *mp;
381 /* We are now running on the stack registered via sigaltstack.
382 (Actually there is a small span of time between runtime_siginit
383 and sigaltstack when the program starts.) */
384 gp = runtime_g ();
385 mp = runtime_m ();
387 if (gp != NULL)
389 #ifdef USING_SPLIT_STACK
390 __splitstack_getcontext (&gp->stack_context[0]);
391 #endif
394 if (gp != NULL && mp->gsignal != NULL)
396 /* We are running on the signal stack. Set the split stack
397 context so that the stack guards are checked correctly. */
398 #ifdef USING_SPLIT_STACK
399 __splitstack_setcontext (&mp->gsignal->stack_context[0]);
400 #endif
403 sig_handler (sig);
405 /* We are going to return back to the signal trampoline and then to
406 whatever we were doing before we got the signal. Restore the
407 split stack context so that stack guards are checked
408 correctly. */
410 if (gp != NULL)
412 #ifdef USING_SPLIT_STACK
413 __splitstack_setcontext (&gp->stack_context[0]);
414 #endif
418 void
419 runtime_setsig (int32 i, bool def __attribute__ ((unused)), bool restart)
421 struct sigaction sa;
422 int r;
423 SigTab *t;
425 memset (&sa, 0, sizeof sa);
427 r = sigfillset (&sa.sa_mask);
428 __go_assert (r == 0);
430 t = &runtime_sigtab[i];
432 if ((t->flags & SigPanic) == 0)
434 sa.sa_flags = SA_ONSTACK;
435 sa.sa_handler = sig_tramp;
437 else
439 #ifdef SA_SIGINFO
440 sa.sa_flags = SA_SIGINFO;
441 sa.sa_sigaction = sig_panic_info_handler;
442 #else
443 sa.sa_flags = 0;
444 sa.sa_handler = sig_panic_handler;
445 #endif
448 if (restart)
449 sa.sa_flags |= SA_RESTART;
451 if (sigaction (t->sig, &sa, NULL) != 0)
452 __go_assert (0);
455 /* Used by the os package to raise SIGPIPE. */
457 void os_sigpipe (void) __asm__ ("os.sigpipe");
459 void
460 os_sigpipe (void)
462 struct sigaction sa;
463 int i;
465 memset (&sa, 0, sizeof sa);
467 sa.sa_handler = SIG_DFL;
469 i = sigemptyset (&sa.sa_mask);
470 __go_assert (i == 0);
472 if (sigaction (SIGPIPE, &sa, NULL) != 0)
473 abort ();
475 raise (SIGPIPE);
478 void
479 runtime_setprof(bool on)
481 USED(on);