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"
15 #include "signal_unix.h"
21 #ifdef USING_SPLIT_STACK
23 extern void __splitstack_getcontext(void *context
[10]);
25 extern void __splitstack_setcontext(void *context
[10]);
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
[] = {
41 { SIGHUP
, N
+ K
, NULL
},
44 { SIGINT
, N
+ K
, NULL
},
47 { SIGQUIT
, N
+ T
, NULL
},
56 { SIGABRT
, N
+ T
, NULL
},
80 { SIGTERM
, N
+ K
, NULL
},
83 { SIGSTKFLT
, T
, NULL
},
89 { SIGCONT
, N
+ D
, NULL
},
92 { SIGTSTP
, N
+ D
, NULL
},
95 { SIGTTIN
, N
+ D
, NULL
},
98 { SIGTTOU
, N
+ D
, NULL
},
104 { SIGXCPU
, N
, NULL
},
107 { SIGXFSZ
, N
, NULL
},
110 { SIGVTALRM
, N
, NULL
},
113 { SIGPROF
, N
, NULL
},
116 { SIGWINCH
, N
, NULL
},
131 { SIGINFO
, N
, NULL
},
144 /* Handle a signal, for cases where we don't panic. We can split the
148 runtime_sighandler (int sig
, Siginfo
*info
,
149 void *context
__attribute__ ((unused
)), G
*gp
)
159 if (m
!= NULL
&& gp
!= m
->g0
&& gp
!= m
->gsignal
)
167 runtime_badsignal (sig
);
171 for (i
= 0; runtime_sigtab
[i
].sig
!= -1; ++i
)
176 t
= &runtime_sigtab
[i
];
183 notify
= info
!= NULL
&& info
->si_code
== SI_USER
;
185 if (notify
|| (t
->flags
& SigNotify
) != 0)
187 if (__go_sigsend (sig
))
190 if ((t
->flags
& SigKill
) != 0)
192 if ((t
->flags
& SigThrow
) == 0)
195 runtime_startpanic ();
198 const char *name
= NULL
;
200 #ifdef HAVE_STRSIGNAL
201 name
= strsignal (sig
);
205 runtime_printf ("Signal %d\n", sig
);
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");
216 runtime_printf ("\n");
218 if (runtime_gotraceback (&crash
))
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
237 __builtin_unreachable ();
240 /* The start of handling a signal which panics. */
243 sig_panic_leadin (G
*gp
)
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);
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. */
265 sig_panic_info_handler (int sig
, Siginfo
*info
, void *context
)
270 if (g
== NULL
|| info
->si_code
== SI_USER
)
272 runtime_sighandler (sig
, info
, context
, g
);
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
);
289 if ((info
->si_code
== BUS_ADRERR
&& (uintptr_t) info
->si_addr
< 0x1000)
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");
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)
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");
312 switch (info
->si_code
)
315 runtime_panicstring ("integer divide by zero");
317 runtime_panicstring ("integer overflow");
319 runtime_panicstring ("floating point error");
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) */
331 sig_panic_handler (int sig
)
338 runtime_sighandler (sig
, NULL
, NULL
, g
);
346 sig_panic_leadin (g
);
352 runtime_panicstring ("invalid memory address or "
353 "nil pointer dereference");
358 runtime_panicstring ("invalid memory address or "
359 "nil pointer dereference");
364 runtime_panicstring ("integer divide by zero or floating point error");
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
380 sig_tramp_info (int, Siginfo
*, void *) __attribute__ ((no_split_stack
));
383 sig_tramp_info (int sig
, Siginfo
*info
, void *context
)
387 #ifdef USING_SPLIT_STACK
388 void *stack_context
[10];
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.) */
399 #ifdef USING_SPLIT_STACK
400 __splitstack_getcontext (&stack_context
[0]);
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]);
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
422 #ifdef USING_SPLIT_STACK
423 __splitstack_setcontext (&stack_context
[0]);
430 static void sig_tramp (int sig
) __attribute__ ((no_split_stack
));
435 sig_tramp_info (sig
, NULL
, NULL
);
441 runtime_setsig (int32 i
, GoSighandler
*fn
, bool restart
)
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)
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
;
462 sa
.sa_flags
= SA_ONSTACK
;
463 if (fn
== runtime_sighandler
)
464 fn
= (void *) sig_tramp
;
465 sa
.sa_handler
= (void *) fn
;
471 sa
.sa_flags
= SA_SIGINFO
;
472 if (fn
== runtime_sighandler
)
473 fn
= (void *) sig_panic_info_handler
;
474 sa
.sa_sigaction
= (void *) fn
;
477 if (fn
== runtime_sighandler
)
478 fn
= (void *) sig_panic_handler
;
479 sa
.sa_handler
= (void *) fn
;
484 sa
.sa_flags
|= SA_RESTART
;
486 if (sigaction (t
->sig
, &sa
, NULL
) != 0)
491 runtime_getsig (int32 i
)
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
;
510 if ((void *) sa
.sa_handler
== sig_panic_info_handler
)
511 return runtime_sighandler
;
513 if ((void *) sa
.sa_handler
== sig_tramp
514 || (void *) sa
.sa_handler
== sig_panic_handler
)
515 return runtime_sighandler
;
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");
531 if (__go_sigsend (SIGPIPE
))
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)
548 runtime_setprof(bool on
)