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