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
[] = {
142 static int8 badsignal
[] = "runtime: signal received on thread not created by Go.\n";
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);
154 /* Handle a signal, for cases where we don't panic. We can split the
158 sig_handler (int sig
)
162 if (runtime_m () == NULL
)
164 runtime_badsignal (sig
);
176 for (i
= 0; runtime_sigtab
[i
].sig
!= -1; ++i
)
180 t
= &runtime_sigtab
[i
];
185 if ((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 runtime_printf ("\n");
212 if (runtime_gotraceback ())
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
228 __builtin_unreachable ();
231 /* The start of handling a signal which panics. */
234 sig_panic_leadin (int sig
)
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);
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. */
259 sig_panic_info_handler (int sig
, siginfo_t
*info
,
260 void *context
__attribute__ ((unused
)))
265 if (g
== NULL
|| info
->si_code
== SI_USER
)
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
);
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");
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");
305 switch (info
->si_code
)
308 runtime_panicstring ("integer divide by zero");
310 runtime_panicstring ("integer overflow");
312 runtime_panicstring ("floating point error");
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) */
324 sig_panic_handler (int sig
)
339 sig_panic_leadin (sig
);
345 runtime_panicstring ("invalid memory address or "
346 "nil pointer dereference");
351 runtime_panicstring ("invalid memory address or "
352 "nil pointer dereference");
357 runtime_panicstring ("integer divide by zero or floating point error");
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
373 sig_tramp (int) __attribute__ ((no_split_stack
));
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.) */
389 #ifdef USING_SPLIT_STACK
390 __splitstack_getcontext (&gp
->stack_context
[0]);
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]);
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
412 #ifdef USING_SPLIT_STACK
413 __splitstack_setcontext (&gp
->stack_context
[0]);
419 runtime_setsig (int32 i
, bool def
__attribute__ ((unused
)), bool restart
)
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
;
440 sa
.sa_flags
= SA_SIGINFO
;
441 sa
.sa_sigaction
= sig_panic_info_handler
;
444 sa
.sa_handler
= sig_panic_handler
;
449 sa
.sa_flags
|= SA_RESTART
;
451 if (sigaction (t
->sig
, &sa
, NULL
) != 0)
455 /* Used by the os package to raise SIGPIPE. */
457 void os_sigpipe (void) __asm__ ("os.sigpipe");
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)
479 runtime_setprof(bool on
)