github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/runtime/go-signal.c (about)

     1  /* go-signal.c -- signal handling for Go.
     2  
     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.  */
     6  
     7  #include <signal.h>
     8  #include <stdlib.h>
     9  #include <unistd.h>
    10  #include <sys/time.h>
    11  
    12  #include "runtime.h"
    13  #include "go-assert.h"
    14  #include "go-panic.h"
    15  #include "signal_unix.h"
    16  
    17  #ifndef SA_RESTART
    18    #define SA_RESTART 0
    19  #endif
    20  
    21  #ifdef USING_SPLIT_STACK
    22  
    23  extern void __splitstack_getcontext(void *context[10]);
    24  
    25  extern void __splitstack_setcontext(void *context[10]);
    26  
    27  #endif
    28  
    29  #define N SigNotify
    30  #define K SigKill
    31  #define T SigThrow
    32  #define P SigPanic
    33  #define D SigDefault
    34  
    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
    38     them.  */
    39  
    40  SigTab runtime_sigtab[] = {
    41  #ifdef SIGHUP
    42    { SIGHUP,	N + K },
    43  #endif
    44  #ifdef SIGINT
    45    { SIGINT, 	N + K },
    46  #endif
    47  #ifdef SIGQUIT
    48    { SIGQUIT, 	N + T },
    49  #endif
    50  #ifdef SIGILL
    51    { SIGILL, 	T },
    52  #endif
    53  #ifdef SIGTRAP
    54    { SIGTRAP, 	T },
    55  #endif
    56  #ifdef SIGABRT
    57    { SIGABRT, 	N + T },
    58  #endif
    59  #ifdef SIGBUS
    60    { SIGBUS, 	P },
    61  #endif
    62  #ifdef SIGFPE
    63    { SIGFPE, 	P },
    64  #endif
    65  #ifdef SIGUSR1
    66    { SIGUSR1, 	N },
    67  #endif
    68  #ifdef SIGSEGV
    69    { SIGSEGV, 	P },
    70  #endif
    71  #ifdef SIGUSR2
    72    { SIGUSR2, 	N },
    73  #endif
    74  #ifdef SIGPIPE
    75    { SIGPIPE, 	N },
    76  #endif
    77  #ifdef SIGALRM
    78    { SIGALRM, 	N },
    79  #endif
    80  #ifdef SIGTERM
    81    { SIGTERM, 	N + K },
    82  #endif
    83  #ifdef SIGSTKFLT
    84    { SIGSTKFLT, 	T },
    85  #endif
    86  #ifdef SIGCHLD
    87    { SIGCHLD, 	N },
    88  #endif
    89  #ifdef SIGTSTP
    90    { SIGTSTP, 	N + D },
    91  #endif
    92  #ifdef SIGTTIN
    93    { SIGTTIN, 	N + D },
    94  #endif
    95  #ifdef SIGTTOU
    96    { SIGTTOU, 	N + D },
    97  #endif
    98  #ifdef SIGURG
    99    { SIGURG, 	N },
   100  #endif
   101  #ifdef SIGXCPU
   102    { SIGXCPU, 	N },
   103  #endif
   104  #ifdef SIGXFSZ
   105    { SIGXFSZ, 	N },
   106  #endif
   107  #ifdef SIGVTALRM
   108    { SIGVTALRM, 	N },
   109  #endif
   110  #ifdef SIGPROF
   111    { SIGPROF, 	N },
   112  #endif
   113  #ifdef SIGWINCH
   114    { SIGWINCH, 	N },
   115  #endif
   116  #ifdef SIGIO
   117    { SIGIO, 	N },
   118  #endif
   119  #ifdef SIGPWR
   120    { SIGPWR, 	N },
   121  #endif
   122  #ifdef SIGSYS
   123    { SIGSYS, 	N },
   124  #endif
   125  #ifdef SIGEMT
   126    { SIGEMT,	T },
   127  #endif
   128  #ifdef SIGINFO
   129    { SIGINFO,	N },
   130  #endif
   131  #ifdef SIGTHR
   132    { SIGTHR,	N },
   133  #endif
   134    { -1,		0 }
   135  };
   136  #undef N
   137  #undef K
   138  #undef T
   139  #undef P
   140  #undef D
   141  
   142  /* Handle a signal, for cases where we don't panic.  We can split the
   143     stack here.  */
   144  
   145  void
   146  runtime_sighandler (int sig, Siginfo *info,
   147  		    void *context __attribute__ ((unused)), G *gp)
   148  {
   149    M *m;
   150    int i;
   151  
   152    m = runtime_m ();
   153  
   154  #ifdef SIGPROF
   155    if (sig == SIGPROF)
   156      {
   157        if (m != NULL && gp != m->g0 && gp != m->gsignal)
   158  	runtime_sigprof ();
   159        return;
   160      }
   161  #endif
   162  
   163    if (m == NULL)
   164      {
   165        runtime_badsignal (sig);
   166        return;
   167      }
   168  
   169    for (i = 0; runtime_sigtab[i].sig != -1; ++i)
   170      {
   171        SigTab *t;
   172        bool notify, crash;
   173  
   174        t = &runtime_sigtab[i];
   175  
   176        if (t->sig != sig)
   177  	continue;
   178  
   179        notify = false;
   180  #ifdef SA_SIGINFO
   181        notify = info != NULL && info->si_code == SI_USER;
   182  #endif
   183        if (notify || (t->flags & SigNotify) != 0)
   184  	{
   185  	  if (__go_sigsend (sig))
   186  	    return;
   187  	}
   188        if ((t->flags & SigKill) != 0)
   189  	runtime_exit (2);
   190        if ((t->flags & SigThrow) == 0)
   191  	return;
   192  
   193        runtime_startpanic ();
   194  
   195        {
   196  	const char *name = NULL;
   197  
   198  #ifdef HAVE_STRSIGNAL
   199  	name = strsignal (sig);
   200  #endif
   201  
   202  	if (name == NULL)
   203  	  runtime_printf ("Signal %d\n", sig);
   204  	else
   205  	  runtime_printf ("%s\n", name);
   206        }
   207  
   208        if (m->lockedg != NULL && m->ncgo > 0 && gp == m->g0)
   209  	{
   210  	  runtime_printf("signal arrived during cgo execution\n");
   211  	  gp = m->lockedg;
   212  	}
   213  
   214        runtime_printf ("\n");
   215  
   216        if (runtime_gotraceback (&crash))
   217  	{
   218  	  G *g;
   219  
   220  	  g = runtime_g ();
   221  	  runtime_traceback ();
   222  	  runtime_tracebackothers (g);
   223  
   224  	  /* The gc library calls runtime_dumpregs here, and provides
   225  	     a function that prints the registers saved in context in
   226  	     a readable form.  */
   227  	}
   228  
   229        if (crash)
   230  	runtime_crash ();
   231  
   232        runtime_exit (2);
   233      }
   234  
   235    __builtin_unreachable ();
   236  }
   237  
   238  /* The start of handling a signal which panics.  */
   239  
   240  static void
   241  sig_panic_leadin (G *gp)
   242  {
   243    int i;
   244    sigset_t clear;
   245  
   246    if (!runtime_canpanic (gp))
   247      runtime_throw ("unexpected signal during runtime execution");
   248  
   249    /* The signal handler blocked signals; unblock them.  */
   250    i = sigfillset (&clear);
   251    __go_assert (i == 0);
   252    i = pthread_sigmask (SIG_UNBLOCK, &clear, NULL);
   253    __go_assert (i == 0);
   254  }
   255  
   256  #ifdef SA_SIGINFO
   257  
   258  /* Signal dispatch for signals which panic, on systems which support
   259     SA_SIGINFO.  This is called on the thread stack, and as such it is
   260     permitted to split the stack.  */
   261  
   262  static void
   263  sig_panic_info_handler (int sig, Siginfo *info, void *context)
   264  {
   265    G *g;
   266  
   267    g = runtime_g ();
   268    if (g == NULL || info->si_code == SI_USER)
   269      {
   270        runtime_sighandler (sig, info, context, g);
   271        return;
   272      }
   273  
   274    g->sig = sig;
   275    g->sigcode0 = info->si_code;
   276    g->sigcode1 = (uintptr_t) info->si_addr;
   277  
   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.  */
   280  
   281    sig_panic_leadin (g);
   282  
   283    switch (sig)
   284      {
   285  #ifdef SIGBUS
   286      case SIGBUS:
   287        if ((info->si_code == BUS_ADRERR && (uintptr_t) info->si_addr < 0x1000)
   288  	  || g->paniconfault)
   289  	runtime_panicstring ("invalid memory address or "
   290  			     "nil pointer dereference");
   291        runtime_printf ("unexpected fault address %p\n", info->si_addr);
   292        runtime_throw ("fault");
   293  #endif
   294  
   295  #ifdef SIGSEGV
   296      case SIGSEGV:
   297        if (((info->si_code == 0
   298  	    || info->si_code == SEGV_MAPERR
   299  	    || info->si_code == SEGV_ACCERR)
   300  	   && (uintptr_t) info->si_addr < 0x1000)
   301  	  || g->paniconfault)
   302  	runtime_panicstring ("invalid memory address or "
   303  			     "nil pointer dereference");
   304        runtime_printf ("unexpected fault address %p\n", info->si_addr);
   305        runtime_throw ("fault");
   306  #endif
   307  
   308  #ifdef SIGFPE
   309      case SIGFPE:
   310        switch (info->si_code)
   311  	{
   312  	case FPE_INTDIV:
   313  	  runtime_panicstring ("integer divide by zero");
   314  	case FPE_INTOVF:
   315  	  runtime_panicstring ("integer overflow");
   316  	}
   317        runtime_panicstring ("floating point error");
   318  #endif
   319      }
   320  
   321    /* All signals with SigPanic should be in cases above, and this
   322       handler should only be invoked for those signals.  */
   323    __builtin_unreachable ();
   324  }
   325  
   326  #else /* !defined (SA_SIGINFO) */
   327  
   328  static void
   329  sig_panic_handler (int sig)
   330  {
   331    G *g;
   332  
   333    g = runtime_g ();
   334    if (g == NULL)
   335      {
   336        runtime_sighandler (sig, NULL, NULL, g);
   337        return;
   338      }
   339  
   340    g->sig = sig;
   341    g->sigcode0 = 0;
   342    g->sigcode1 = 0;
   343  
   344    sig_panic_leadin (g);
   345  
   346    switch (sig)
   347      {
   348  #ifdef SIGBUS
   349      case SIGBUS:
   350        runtime_panicstring ("invalid memory address or "
   351  			   "nil pointer dereference");
   352  #endif
   353  
   354  #ifdef SIGSEGV
   355      case SIGSEGV:
   356        runtime_panicstring ("invalid memory address or "
   357  			   "nil pointer dereference");
   358  #endif
   359  
   360  #ifdef SIGFPE
   361      case SIGFPE:
   362        runtime_panicstring ("integer divide by zero or floating point error");
   363  #endif
   364      }
   365  
   366    /* All signals with SigPanic should be in cases above, and this
   367       handler should only be invoked for those signals.  */
   368    __builtin_unreachable ();
   369  }
   370  
   371  #endif /* !defined (SA_SIGINFO) */
   372  
   373  /* A signal handler used for signals which are not going to panic.
   374     This is called on the alternate signal stack so it may not split
   375     the stack.  */
   376  
   377  static void
   378  sig_tramp_info (int, Siginfo *, void *) __attribute__ ((no_split_stack));
   379  
   380  static void
   381  sig_tramp_info (int sig, Siginfo *info, void *context)
   382  {
   383    G *gp;
   384    M *mp;
   385  #ifdef USING_SPLIT_STACK
   386    void *stack_context[10];
   387  #endif
   388  
   389    /* We are now running on the stack registered via sigaltstack.
   390       (Actually there is a small span of time between runtime_siginit
   391       and sigaltstack when the program starts.)  */
   392    gp = runtime_g ();
   393    mp = runtime_m ();
   394  
   395    if (gp != NULL)
   396      {
   397  #ifdef USING_SPLIT_STACK
   398        __splitstack_getcontext (&stack_context[0]);
   399  #endif
   400      }
   401  
   402    if (gp != NULL && mp->gsignal != NULL)
   403      {
   404        /* We are running on the signal stack.  Set the split stack
   405  	 context so that the stack guards are checked correctly.  */
   406  #ifdef USING_SPLIT_STACK
   407        __splitstack_setcontext (&mp->gsignal->stack_context[0]);
   408  #endif
   409      }
   410  
   411    runtime_sighandler (sig, info, context, gp);
   412  
   413    /* We are going to return back to the signal trampoline and then to
   414       whatever we were doing before we got the signal.  Restore the
   415       split stack context so that stack guards are checked
   416       correctly.  */
   417  
   418    if (gp != NULL)
   419      {
   420  #ifdef USING_SPLIT_STACK
   421        __splitstack_setcontext (&stack_context[0]);
   422  #endif
   423      }
   424  }
   425  
   426  #ifndef SA_SIGINFO
   427  
   428  static void sig_tramp (int sig) __attribute__ ((no_split_stack));
   429  
   430  static void
   431  sig_tramp (int sig)
   432  {
   433    sig_tramp_info (sig, NULL, NULL);
   434  }
   435  
   436  #endif
   437  
   438  void
   439  runtime_setsig (int32 i, GoSighandler *fn, bool restart)
   440  {
   441    struct sigaction sa;
   442    int r;
   443    SigTab *t;
   444  
   445    memset (&sa, 0, sizeof sa);
   446  
   447    r = sigfillset (&sa.sa_mask);
   448    __go_assert (r == 0);
   449  
   450    t = &runtime_sigtab[i];
   451  
   452    if ((t->flags & SigPanic) == 0)
   453      {
   454  #ifdef SA_SIGINFO
   455        sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
   456        if (fn == runtime_sighandler)
   457  	fn = (void *) sig_tramp_info;
   458        sa.sa_sigaction = (void *) fn;
   459  #else
   460        sa.sa_flags = SA_ONSTACK;
   461        if (fn == runtime_sighandler)
   462  	fn = (void *) sig_tramp;
   463        sa.sa_handler = (void *) fn;
   464  #endif
   465      }
   466    else
   467      {
   468  #ifdef SA_SIGINFO
   469        sa.sa_flags = SA_SIGINFO;
   470        if (fn == runtime_sighandler)
   471  	fn = (void *) sig_panic_info_handler;
   472        sa.sa_sigaction = (void *) fn;
   473  #else
   474        sa.sa_flags = 0;
   475        if (fn == runtime_sighandler)
   476  	fn = (void *) sig_panic_handler;
   477        sa.sa_handler = (void *) fn;
   478  #endif
   479      }
   480  
   481    if (restart)
   482      sa.sa_flags |= SA_RESTART;
   483  
   484    if (sigaction (t->sig, &sa, NULL) != 0)
   485      __go_assert (0);
   486  }
   487  
   488  GoSighandler*
   489  runtime_getsig (int32 i)
   490  {
   491    struct sigaction sa;
   492    int r;
   493    SigTab *t;
   494  
   495    memset (&sa, 0, sizeof sa);
   496  
   497    r = sigemptyset (&sa.sa_mask);
   498    __go_assert (r == 0);
   499  
   500    t = &runtime_sigtab[i];
   501  
   502    if (sigaction (t->sig, NULL, &sa) != 0)
   503      runtime_throw ("sigaction read failure");
   504  
   505    if ((void *) sa.sa_handler == sig_tramp_info)
   506      return runtime_sighandler;
   507  #ifdef SA_SIGINFO
   508    if ((void *) sa.sa_handler == sig_panic_info_handler)
   509      return runtime_sighandler;
   510  #else
   511    if ((void *) sa.sa_handler == sig_tramp
   512        || (void *) sa.sa_handler == sig_panic_handler)
   513      return runtime_sighandler;
   514  #endif
   515  
   516    return (void *) sa.sa_handler;
   517  }
   518  
   519  /* Used by the os package to raise SIGPIPE.  */
   520  
   521  void os_sigpipe (void) __asm__ (GOSYM_PREFIX "os.sigpipe");
   522  
   523  void
   524  os_sigpipe (void)
   525  {
   526    struct sigaction sa;
   527    int i;
   528  
   529    memset (&sa, 0, sizeof sa);
   530  
   531    sa.sa_handler = SIG_DFL;
   532  
   533    i = sigemptyset (&sa.sa_mask);
   534    __go_assert (i == 0);
   535  
   536    if (sigaction (SIGPIPE, &sa, NULL) != 0)
   537      abort ();
   538  
   539    raise (SIGPIPE);
   540  }
   541  
   542  void
   543  runtime_setprof(bool on)
   544  {
   545  	USED(on);
   546  }