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, SIGCONT, and
37 SIGSTOP are not listed, as we don't want to set signal handlers for
40 SigTab runtime_sigtab
[] = {
143 static int8 badsignal
[] = "runtime: signal received on thread not created by Go.\n";
146 runtime_badsignal(int32 sig
)
148 // Avoid -D_FORTIFY_SOURCE problems.
149 int rv
__attribute__((unused
));
151 if (sig
== SIGPROF
) {
152 return; // Ignore SIGPROFs intended for a non-Go thread.
154 rv
= runtime_write(2, badsignal
, sizeof badsignal
- 1);
158 /* Handle a signal, for cases where we don't panic. We can split the
162 runtime_sighandler (int sig
, Siginfo
*info
,
163 void *context
__attribute__ ((unused
)), G
*gp
)
173 if (m
!= NULL
&& gp
!= m
->g0
&& gp
!= m
->gsignal
)
181 runtime_badsignal (sig
);
185 for (i
= 0; runtime_sigtab
[i
].sig
!= -1; ++i
)
190 t
= &runtime_sigtab
[i
];
197 notify
= info
!= NULL
&& info
->si_code
== SI_USER
;
199 if (notify
|| (t
->flags
& SigNotify
) != 0)
201 if (__go_sigsend (sig
))
204 if ((t
->flags
& SigKill
) != 0)
206 if ((t
->flags
& SigThrow
) == 0)
209 runtime_startpanic ();
212 const char *name
= NULL
;
214 #ifdef HAVE_STRSIGNAL
215 name
= strsignal (sig
);
219 runtime_printf ("Signal %d\n", sig
);
221 runtime_printf ("%s\n", name
);
224 if (m
->lockedg
!= NULL
&& m
->ncgo
> 0 && gp
== m
->g0
)
226 runtime_printf("signal arrived during cgo execution\n");
230 runtime_printf ("\n");
232 if (runtime_gotraceback (&crash
))
237 runtime_traceback (g
);
238 runtime_tracebackothers (g
);
240 /* The gc library calls runtime_dumpregs here, and provides
241 a function that prints the registers saved in context in
251 __builtin_unreachable ();
254 /* The start of handling a signal which panics. */
257 sig_panic_leadin (int sig
)
262 if (runtime_m ()->mallocing
)
264 runtime_printf ("caught signal while mallocing: %d\n", sig
);
265 runtime_throw ("caught signal while mallocing");
268 /* The signal handler blocked signals; unblock them. */
269 i
= sigfillset (&clear
);
270 __go_assert (i
== 0);
271 i
= sigprocmask (SIG_UNBLOCK
, &clear
, NULL
);
272 __go_assert (i
== 0);
277 /* Signal dispatch for signals which panic, on systems which support
278 SA_SIGINFO. This is called on the thread stack, and as such it is
279 permitted to split the stack. */
282 sig_panic_info_handler (int sig
, Siginfo
*info
, void *context
)
287 if (g
== NULL
|| info
->si_code
== SI_USER
)
289 runtime_sighandler (sig
, info
, context
, g
);
294 g
->sigcode0
= info
->si_code
;
295 g
->sigcode1
= (uintptr_t) info
->si_addr
;
297 /* It would be nice to set g->sigpc here as the gc library does, but
298 I don't know how to get it portably. */
300 sig_panic_leadin (sig
);
306 if (info
->si_code
== BUS_ADRERR
&& (uintptr_t) info
->si_addr
< 0x1000)
307 runtime_panicstring ("invalid memory address or "
308 "nil pointer dereference");
309 runtime_printf ("unexpected fault address %p\n", info
->si_addr
);
310 runtime_throw ("fault");
315 if ((info
->si_code
== 0
316 || info
->si_code
== SEGV_MAPERR
317 || info
->si_code
== SEGV_ACCERR
)
318 && (uintptr_t) info
->si_addr
< 0x1000)
319 runtime_panicstring ("invalid memory address or "
320 "nil pointer dereference");
321 runtime_printf ("unexpected fault address %p\n", info
->si_addr
);
322 runtime_throw ("fault");
327 switch (info
->si_code
)
330 runtime_panicstring ("integer divide by zero");
332 runtime_panicstring ("integer overflow");
334 runtime_panicstring ("floating point error");
338 /* All signals with SigPanic should be in cases above, and this
339 handler should only be invoked for those signals. */
340 __builtin_unreachable ();
343 #else /* !defined (SA_SIGINFO) */
346 sig_panic_handler (int sig
)
353 runtime_sighandler (sig
, NULL
, NULL
, g
);
361 sig_panic_leadin (sig
);
367 runtime_panicstring ("invalid memory address or "
368 "nil pointer dereference");
373 runtime_panicstring ("invalid memory address or "
374 "nil pointer dereference");
379 runtime_panicstring ("integer divide by zero or floating point error");
383 /* All signals with SigPanic should be in cases above, and this
384 handler should only be invoked for those signals. */
385 __builtin_unreachable ();
388 #endif /* !defined (SA_SIGINFO) */
390 /* A signal handler used for signals which are not going to panic.
391 This is called on the alternate signal stack so it may not split
395 sig_tramp_info (int, Siginfo
*, void *) __attribute__ ((no_split_stack
));
398 sig_tramp_info (int sig
, Siginfo
*info
, void *context
)
402 #ifdef USING_SPLIT_STACK
403 void *stack_context
[10];
406 /* We are now running on the stack registered via sigaltstack.
407 (Actually there is a small span of time between runtime_siginit
408 and sigaltstack when the program starts.) */
414 #ifdef USING_SPLIT_STACK
415 __splitstack_getcontext (&stack_context
[0]);
419 if (gp
!= NULL
&& mp
->gsignal
!= NULL
)
421 /* We are running on the signal stack. Set the split stack
422 context so that the stack guards are checked correctly. */
423 #ifdef USING_SPLIT_STACK
424 __splitstack_setcontext (&mp
->gsignal
->stack_context
[0]);
428 runtime_sighandler (sig
, info
, context
, gp
);
430 /* We are going to return back to the signal trampoline and then to
431 whatever we were doing before we got the signal. Restore the
432 split stack context so that stack guards are checked
437 #ifdef USING_SPLIT_STACK
438 __splitstack_setcontext (&stack_context
[0]);
445 static void sig_tramp (int sig
) __attribute__ ((no_split_stack
));
450 sig_tramp_info (sig
, NULL
, NULL
);
456 runtime_setsig (int32 i
, GoSighandler
*fn
, bool restart
)
462 memset (&sa
, 0, sizeof sa
);
464 r
= sigfillset (&sa
.sa_mask
);
465 __go_assert (r
== 0);
467 t
= &runtime_sigtab
[i
];
469 if ((t
->flags
& SigPanic
) == 0)
472 sa
.sa_flags
= SA_ONSTACK
| SA_SIGINFO
;
473 if (fn
== runtime_sighandler
)
474 fn
= (void *) sig_tramp_info
;
475 sa
.sa_sigaction
= (void *) fn
;
477 sa
.sa_flags
= SA_ONSTACK
;
478 if (fn
== runtime_sighandler
)
479 fn
= (void *) sig_tramp
;
480 sa
.sa_handler
= (void *) fn
;
486 sa
.sa_flags
= SA_SIGINFO
;
487 if (fn
== runtime_sighandler
)
488 fn
= (void *) sig_panic_info_handler
;
489 sa
.sa_sigaction
= (void *) fn
;
492 if (fn
== runtime_sighandler
)
493 fn
= (void *) sig_panic_handler
;
494 sa
.sa_handler
= (void *) fn
;
499 sa
.sa_flags
|= SA_RESTART
;
501 if (sigaction (t
->sig
, &sa
, NULL
) != 0)
506 runtime_getsig (int32 i
)
512 memset (&sa
, 0, sizeof sa
);
514 r
= sigemptyset (&sa
.sa_mask
);
515 __go_assert (r
== 0);
517 t
= &runtime_sigtab
[i
];
519 if (sigaction (t
->sig
, NULL
, &sa
) != 0)
520 runtime_throw ("sigaction read failure");
522 if ((void *) sa
.sa_handler
== sig_tramp_info
)
523 return runtime_sighandler
;
525 if ((void *) sa
.sa_handler
== sig_panic_info_handler
)
526 return runtime_sighandler
;
528 if ((void *) sa
.sa_handler
== sig_tramp
529 || (void *) sa
.sa_handler
== sig_panic_handler
)
530 return runtime_sighandler
;
533 return (void *) sa
.sa_handler
;
536 /* Used by the os package to raise SIGPIPE. */
538 void os_sigpipe (void) __asm__ (GOSYM_PREFIX
"os.sigpipe");
546 memset (&sa
, 0, sizeof sa
);
548 sa
.sa_handler
= SIG_DFL
;
550 i
= sigemptyset (&sa
.sa_mask
);
551 __go_assert (i
== 0);
553 if (sigaction (SIGPIPE
, &sa
, NULL
) != 0)
560 runtime_setprof(bool on
)