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
[] = {
141 /* Handle a signal, for cases where we don't panic. We can split the
145 sig_handler (int sig
)
157 for (i
= 0; runtime_sigtab
[i
].sig
!= -1; ++i
)
161 t
= &runtime_sigtab
[i
];
166 if ((t
->flags
& SigNotify
) != 0)
168 if (__go_sigsend (sig
))
171 if ((t
->flags
& SigKill
) != 0)
173 if ((t
->flags
& SigThrow
) == 0)
176 runtime_startpanic ();
179 const char *name
= NULL
;
181 #ifdef HAVE_STRSIGNAL
182 name
= strsignal (sig
);
186 runtime_printf ("Signal %d\n", sig
);
188 runtime_printf ("%s\n", name
);
191 runtime_printf ("\n");
193 if (runtime_gotraceback ())
198 runtime_traceback (g
);
199 runtime_tracebackothers (g
);
201 /* The gc library calls runtime_dumpregs here, and provides
202 a function that prints the registers saved in context in
209 __builtin_unreachable ();
212 /* The start of handling a signal which panics. */
215 sig_panic_leadin (int sig
)
220 if (runtime_m ()->mallocing
)
222 runtime_printf ("caught signal while mallocing: %d\n", sig
);
223 runtime_throw ("caught signal while mallocing");
226 /* The signal handler blocked signals; unblock them. */
227 i
= sigfillset (&clear
);
228 __go_assert (i
== 0);
229 i
= sigprocmask (SIG_UNBLOCK
, &clear
, NULL
);
230 __go_assert (i
== 0);
235 /* Signal dispatch for signals which panic, on systems which support
236 SA_SIGINFO. This is called on the thread stack, and as such it is
237 permitted to split the stack. */
240 sig_panic_info_handler (int sig
, siginfo_t
*info
,
241 void *context
__attribute__ ((unused
)))
246 if (g
== NULL
|| info
->si_code
== SI_USER
)
253 g
->sigcode0
= info
->si_code
;
254 g
->sigcode1
= (uintptr_t) info
->si_addr
;
256 /* It would be nice to set g->sigpc here as the gc library does, but
257 I don't know how to get it portably. */
259 sig_panic_leadin (sig
);
265 if (info
->si_code
== BUS_ADRERR
&& (uintptr_t) info
->si_addr
< 0x1000)
266 runtime_panicstring ("invalid memory address or "
267 "nil pointer dereference");
268 runtime_printf ("unexpected fault address %p\n", info
->si_addr
);
269 runtime_throw ("fault");
274 if ((info
->si_code
== 0
275 || info
->si_code
== SEGV_MAPERR
276 || info
->si_code
== SEGV_ACCERR
)
277 && (uintptr_t) info
->si_addr
< 0x1000)
278 runtime_panicstring ("invalid memory address or "
279 "nil pointer dereference");
280 runtime_printf ("unexpected fault address %p\n", info
->si_addr
);
281 runtime_throw ("fault");
286 switch (info
->si_code
)
289 runtime_panicstring ("integer divide by zero");
291 runtime_panicstring ("integer overflow");
293 runtime_panicstring ("floating point error");
297 /* All signals with SigPanic should be in cases above, and this
298 handler should only be invoked for those signals. */
299 __builtin_unreachable ();
302 #else /* !defined (SA_SIGINFO) */
305 sig_panic_handler (int sig
)
320 sig_panic_leadin (sig
);
326 runtime_panicstring ("invalid memory address or "
327 "nil pointer dereference");
332 runtime_panicstring ("invalid memory address or "
333 "nil pointer dereference");
338 runtime_panicstring ("integer divide by zero or floating point error");
342 /* All signals with SigPanic should be in cases above, and this
343 handler should only be invoked for those signals. */
344 __builtin_unreachable ();
347 #endif /* !defined (SA_SIGINFO) */
349 /* A signal handler used for signals which are not going to panic.
350 This is called on the alternate signal stack so it may not split
354 sig_tramp (int) __attribute__ ((no_split_stack
));
362 /* We are now running on the stack registered via sigaltstack.
363 (Actually there is a small span of time between runtime_siginit
364 and sigaltstack when the program starts.) */
370 #ifdef USING_SPLIT_STACK
371 __splitstack_getcontext (&gp
->stack_context
[0]);
375 if (gp
!= NULL
&& mp
->gsignal
!= NULL
)
377 /* We are running on the signal stack. Set the split stack
378 context so that the stack guards are checked correctly. */
379 #ifdef USING_SPLIT_STACK
380 __splitstack_setcontext (&mp
->gsignal
->stack_context
[0]);
386 /* We are going to return back to the signal trampoline and then to
387 whatever we were doing before we got the signal. Restore the
388 split stack context so that stack guards are checked
393 #ifdef USING_SPLIT_STACK
394 __splitstack_setcontext (&gp
->stack_context
[0]);
400 runtime_setsig (int32 i
, bool def
__attribute__ ((unused
)), bool restart
)
406 memset (&sa
, 0, sizeof sa
);
408 r
= sigfillset (&sa
.sa_mask
);
409 __go_assert (r
== 0);
411 t
= &runtime_sigtab
[i
];
413 if ((t
->flags
& SigPanic
) == 0)
415 sa
.sa_flags
= SA_ONSTACK
;
416 sa
.sa_handler
= sig_tramp
;
421 sa
.sa_flags
= SA_SIGINFO
;
422 sa
.sa_sigaction
= sig_panic_info_handler
;
425 sa
.sa_handler
= sig_panic_handler
;
430 sa
.sa_flags
|= SA_RESTART
;
432 if (sigaction (t
->sig
, &sa
, NULL
) != 0)
436 /* Used by the os package to raise SIGPIPE. */
438 void os_sigpipe (void) __asm__ ("os.sigpipe");
446 memset (&sa
, 0, sizeof sa
);
448 sa
.sa_handler
= SIG_DFL
;
450 i
= sigemptyset (&sa
.sa_mask
);
451 __go_assert (i
== 0);
453 if (sigaction (SIGPIPE
, &sa
, NULL
) != 0)
460 runtime_setprof(bool on
)