static void sig_handler (int sig) { int i; #ifdef SIGPROF if (sig == SIGPROF) { /* FIXME. */ runtime_sigprof (0, 0, nil, nil); return; } #endif for (i = 0; runtime_sigtab[i].sig != -1; ++i) { struct sigaction sa; SigTab *t; t = &runtime_sigtab[i]; if (t->sig != sig) continue; if ((t->flags & SigNotify) != 0) { if (__go_sigsend (sig)) return; } if ((t->flags & SigKill) != 0) runtime_exit (2); if ((t->flags & SigThrow) == 0) return; runtime_startpanic (); /* We should do a stack backtrace here. Until we can do that, we reraise the signal in order to get a slightly better report from the shell. */ memset (&sa, 0, sizeof sa); sa.sa_handler = SIG_DFL; i = sigemptyset (&sa.sa_mask); __go_assert (i == 0); if (sigaction (sig, &sa, NULL) != 0) abort (); raise (sig); runtime_exit (2); } __builtin_unreachable (); }
static void sig_handler (int sig) { int i; if (runtime_m () == NULL) { runtime_badsignal (sig); return; } #ifdef SIGPROF if (sig == SIGPROF) { runtime_sigprof (); return; } #endif for (i = 0; runtime_sigtab[i].sig != -1; ++i) { SigTab *t; t = &runtime_sigtab[i]; if (t->sig != sig) continue; if ((t->flags & SigNotify) != 0) { if (__go_sigsend (sig)) return; } if ((t->flags & SigKill) != 0) runtime_exit (2); if ((t->flags & SigThrow) == 0) return; runtime_startpanic (); { const char *name = NULL; #ifdef HAVE_STRSIGNAL name = strsignal (sig); #endif if (name == NULL) runtime_printf ("Signal %d\n", sig); else runtime_printf ("%s\n", name); } runtime_printf ("\n"); if (runtime_gotraceback ()) { G *g; g = runtime_g (); runtime_traceback (g); runtime_tracebackothers (g); /* The gc library calls runtime_dumpregs here, and provides a function that prints the registers saved in context in a readable form. */ } runtime_exit (2); } __builtin_unreachable (); }
static void sighandler (int sig) { const char *msg; int i; if (sig == SIGPROF) { /* FIXME. */ runtime_sigprof (0, 0, nil); return; } /* FIXME: Should check siginfo for more information when available. */ msg = NULL; switch (sig) { #ifdef SIGBUS case SIGBUS: msg = "invalid memory address or nil pointer dereference"; break; #endif #ifdef SIGFPE case SIGFPE: msg = "integer divide by zero or floating point error"; break; #endif #ifdef SIGSEGV case SIGSEGV: msg = "invalid memory address or nil pointer dereference"; break; #endif default: break; } if (msg != NULL) { sigset_t clear; if (__sync_bool_compare_and_swap (&m->mallocing, 1, 1)) { fprintf (stderr, "caught signal while mallocing: %s\n", msg); __go_assert (0); } /* The signal handler blocked signals; unblock them. */ i = sigfillset (&clear); __go_assert (i == 0); i = sigprocmask (SIG_UNBLOCK, &clear, NULL); __go_assert (i == 0); __go_panic_msg (msg); } if (__go_sigsend (sig)) return; for (i = 0; signals[i].sig != -1; ++i) { if (signals[i].sig == sig) { struct sigaction sa; if (signals[i].ignore) return; memset (&sa, 0, sizeof sa); sa.sa_handler = SIG_DFL; i = sigemptyset (&sa.sa_mask); __go_assert (i == 0); if (sigaction (sig, &sa, NULL) != 0) abort (); raise (sig); exit (2); } } abort (); }