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 // Avoid -D_FORTIFY_SOURCE problems.
148 int rv
__attribute__((unused
));
150 if (sig
== SIGPROF
) {
151 return; // Ignore SIGPROFs intended for a non-Go thread.
153 rv
= runtime_write(2, badsignal
, sizeof badsignal
- 1);
157 /* Handle a signal, for cases where we don't panic. We can split the
161 sig_handler (int sig
)
165 if (runtime_m () == NULL
)
167 runtime_badsignal (sig
);
179 for (i
= 0; runtime_sigtab
[i
].sig
!= -1; ++i
)
183 t
= &runtime_sigtab
[i
];
188 if ((t
->flags
& SigNotify
) != 0)
190 if (__go_sigsend (sig
))
193 if ((t
->flags
& SigKill
) != 0)
195 if ((t
->flags
& SigThrow
) == 0)
198 runtime_startpanic ();
201 const char *name
= NULL
;
203 #ifdef HAVE_STRSIGNAL
204 name
= strsignal (sig
);
208 runtime_printf ("Signal %d\n", sig
);
210 runtime_printf ("%s\n", name
);
213 runtime_printf ("\n");
215 if (runtime_gotraceback ())
220 runtime_traceback (g
);
221 runtime_tracebackothers (g
);
223 /* The gc library calls runtime_dumpregs here, and provides
224 a function that prints the registers saved in context in
231 __builtin_unreachable ();
234 /* The start of handling a signal which panics. */
237 sig_panic_leadin (int sig
)
242 if (runtime_m ()->mallocing
)
244 runtime_printf ("caught signal while mallocing: %d\n", sig
);
245 runtime_throw ("caught signal while mallocing");
248 /* The signal handler blocked signals; unblock them. */
249 i
= sigfillset (&clear
);
250 __go_assert (i
== 0);
251 i
= sigprocmask (SIG_UNBLOCK
, &clear
, NULL
);
252 __go_assert (i
== 0);
257 /* Signal dispatch for signals which panic, on systems which support
258 SA_SIGINFO. This is called on the thread stack, and as such it is
259 permitted to split the stack. */
262 sig_panic_info_handler (int sig
, siginfo_t
*info
,
263 void *context
__attribute__ ((unused
)))
268 if (g
== NULL
|| info
->si_code
== SI_USER
)
275 g
->sigcode0
= info
->si_code
;
276 g
->sigcode1
= (uintptr_t) info
->si_addr
;
278 /* It would be nice to set g->sigpc here as the gc library does, but
279 I don't know how to get it portably. */
281 sig_panic_leadin (sig
);
287 if (info
->si_code
== BUS_ADRERR
&& (uintptr_t) info
->si_addr
< 0x1000)
288 runtime_panicstring ("invalid memory address or "
289 "nil pointer dereference");
290 runtime_printf ("unexpected fault address %p\n", info
->si_addr
);
291 runtime_throw ("fault");
296 if ((info
->si_code
== 0
297 || info
->si_code
== SEGV_MAPERR
298 || info
->si_code
== SEGV_ACCERR
)
299 && (uintptr_t) info
->si_addr
< 0x1000)
300 runtime_panicstring ("invalid memory address or "
301 "nil pointer dereference");
302 runtime_printf ("unexpected fault address %p\n", info
->si_addr
);
303 runtime_throw ("fault");
308 switch (info
->si_code
)
311 runtime_panicstring ("integer divide by zero");
313 runtime_panicstring ("integer overflow");
315 runtime_panicstring ("floating point error");
319 /* All signals with SigPanic should be in cases above, and this
320 handler should only be invoked for those signals. */
321 __builtin_unreachable ();
324 #else /* !defined (SA_SIGINFO) */
327 sig_panic_handler (int sig
)
342 sig_panic_leadin (sig
);
348 runtime_panicstring ("invalid memory address or "
349 "nil pointer dereference");
354 runtime_panicstring ("invalid memory address or "
355 "nil pointer dereference");
360 runtime_panicstring ("integer divide by zero or floating point error");
364 /* All signals with SigPanic should be in cases above, and this
365 handler should only be invoked for those signals. */
366 __builtin_unreachable ();
369 #endif /* !defined (SA_SIGINFO) */
371 /* A signal handler used for signals which are not going to panic.
372 This is called on the alternate signal stack so it may not split
376 sig_tramp (int) __attribute__ ((no_split_stack
));
384 /* We are now running on the stack registered via sigaltstack.
385 (Actually there is a small span of time between runtime_siginit
386 and sigaltstack when the program starts.) */
392 #ifdef USING_SPLIT_STACK
393 __splitstack_getcontext (&gp
->stack_context
[0]);
397 if (gp
!= NULL
&& mp
->gsignal
!= NULL
)
399 /* We are running on the signal stack. Set the split stack
400 context so that the stack guards are checked correctly. */
401 #ifdef USING_SPLIT_STACK
402 __splitstack_setcontext (&mp
->gsignal
->stack_context
[0]);
408 /* We are going to return back to the signal trampoline and then to
409 whatever we were doing before we got the signal. Restore the
410 split stack context so that stack guards are checked
415 #ifdef USING_SPLIT_STACK
416 __splitstack_setcontext (&gp
->stack_context
[0]);
422 runtime_setsig (int32 i
, bool def
__attribute__ ((unused
)), bool restart
)
428 memset (&sa
, 0, sizeof sa
);
430 r
= sigfillset (&sa
.sa_mask
);
431 __go_assert (r
== 0);
433 t
= &runtime_sigtab
[i
];
435 if ((t
->flags
& SigPanic
) == 0)
437 sa
.sa_flags
= SA_ONSTACK
;
438 sa
.sa_handler
= sig_tramp
;
443 sa
.sa_flags
= SA_SIGINFO
;
444 sa
.sa_sigaction
= sig_panic_info_handler
;
447 sa
.sa_handler
= sig_panic_handler
;
452 sa
.sa_flags
|= SA_RESTART
;
454 if (sigaction (t
->sig
, &sa
, NULL
) != 0)
458 /* Used by the os package to raise SIGPIPE. */
460 void os_sigpipe (void) __asm__ (GOSYM_PREFIX
"os.sigpipe");
468 memset (&sa
, 0, sizeof sa
);
470 sa
.sa_handler
= SIG_DFL
;
472 i
= sigemptyset (&sa
.sa_mask
);
473 __go_assert (i
== 0);
475 if (sigaction (SIGPIPE
, &sa
, NULL
) != 0)
482 runtime_setprof(bool on
)