runtime: runtime.Caller should succeed even without debug info.
[gcc.git] / libgo / runtime / go-signal.c
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
16 #ifndef SA_RESTART
17 #define SA_RESTART 0
18 #endif
19
20 #ifdef USING_SPLIT_STACK
21
22 extern void __splitstack_getcontext(void *context[10]);
23
24 extern void __splitstack_setcontext(void *context[10]);
25
26 #endif
27
28 #define N SigNotify
29 #define K SigKill
30 #define T SigThrow
31 #define P SigPanic
32 #define D SigDefault
33
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
37 them. */
38
39 SigTab runtime_sigtab[] = {
40 #ifdef SIGHUP
41 { SIGHUP, N + K },
42 #endif
43 #ifdef SIGINT
44 { SIGINT, N + K },
45 #endif
46 #ifdef SIGQUIT
47 { SIGQUIT, N + T },
48 #endif
49 #ifdef SIGILL
50 { SIGILL, T },
51 #endif
52 #ifdef SIGTRAP
53 { SIGTRAP, T },
54 #endif
55 #ifdef SIGABRT
56 { SIGABRT, N + T },
57 #endif
58 #ifdef SIGBUS
59 { SIGBUS, P },
60 #endif
61 #ifdef SIGFPE
62 { SIGFPE, P },
63 #endif
64 #ifdef SIGUSR1
65 { SIGUSR1, N },
66 #endif
67 #ifdef SIGSEGV
68 { SIGSEGV, P },
69 #endif
70 #ifdef SIGUSR2
71 { SIGUSR2, N },
72 #endif
73 #ifdef SIGPIPE
74 { SIGPIPE, N },
75 #endif
76 #ifdef SIGALRM
77 { SIGALRM, N },
78 #endif
79 #ifdef SIGTERM
80 { SIGTERM, N + K },
81 #endif
82 #ifdef SIGSTKFLT
83 { SIGSTKFLT, T },
84 #endif
85 #ifdef SIGCHLD
86 { SIGCHLD, N },
87 #endif
88 #ifdef SIGTSTP
89 { SIGTSTP, N + D },
90 #endif
91 #ifdef SIGTTIN
92 { SIGTTIN, N + D },
93 #endif
94 #ifdef SIGTTOU
95 { SIGTTOU, N + D },
96 #endif
97 #ifdef SIGURG
98 { SIGURG, N },
99 #endif
100 #ifdef SIGXCPU
101 { SIGXCPU, N },
102 #endif
103 #ifdef SIGXFSZ
104 { SIGXFSZ, N },
105 #endif
106 #ifdef SIGVTALRM
107 { SIGVTALRM, N },
108 #endif
109 #ifdef SIGPROF
110 { SIGPROF, N },
111 #endif
112 #ifdef SIGWINCH
113 { SIGWINCH, N },
114 #endif
115 #ifdef SIGIO
116 { SIGIO, N },
117 #endif
118 #ifdef SIGPWR
119 { SIGPWR, N },
120 #endif
121 #ifdef SIGSYS
122 { SIGSYS, N },
123 #endif
124 #ifdef SIGEMT
125 { SIGEMT, T },
126 #endif
127 #ifdef SIGINFO
128 { SIGINFO, N },
129 #endif
130 #ifdef SIGTHR
131 { SIGTHR, N },
132 #endif
133 { -1, 0 }
134 };
135 #undef N
136 #undef K
137 #undef T
138 #undef P
139 #undef D
140
141 /* Handle a signal, for cases where we don't panic. We can split the
142 stack here. */
143
144 static void
145 sig_handler (int sig)
146 {
147 int i;
148
149 #ifdef SIGPROF
150 if (sig == SIGPROF)
151 {
152 runtime_sigprof ();
153 return;
154 }
155 #endif
156
157 for (i = 0; runtime_sigtab[i].sig != -1; ++i)
158 {
159 SigTab *t;
160
161 t = &runtime_sigtab[i];
162
163 if (t->sig != sig)
164 continue;
165
166 if ((t->flags & SigNotify) != 0)
167 {
168 if (__go_sigsend (sig))
169 return;
170 }
171 if ((t->flags & SigKill) != 0)
172 runtime_exit (2);
173 if ((t->flags & SigThrow) == 0)
174 return;
175
176 runtime_startpanic ();
177
178 {
179 const char *name = NULL;
180
181 #ifdef HAVE_STRSIGNAL
182 name = strsignal (sig);
183 #endif
184
185 if (name == NULL)
186 runtime_printf ("Signal %d\n", sig);
187 else
188 runtime_printf ("%s\n", name);
189 }
190
191 runtime_printf ("\n");
192
193 if (runtime_gotraceback ())
194 {
195 G *g;
196
197 g = runtime_g ();
198 runtime_traceback (g);
199 runtime_tracebackothers (g);
200
201 /* The gc library calls runtime_dumpregs here, and provides
202 a function that prints the registers saved in context in
203 a readable form. */
204 }
205
206 runtime_exit (2);
207 }
208
209 __builtin_unreachable ();
210 }
211
212 /* The start of handling a signal which panics. */
213
214 static void
215 sig_panic_leadin (int sig)
216 {
217 int i;
218 sigset_t clear;
219
220 if (runtime_m ()->mallocing)
221 {
222 runtime_printf ("caught signal while mallocing: %d\n", sig);
223 runtime_throw ("caught signal while mallocing");
224 }
225
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);
231 }
232
233 #ifdef SA_SIGINFO
234
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. */
238
239 static void
240 sig_panic_info_handler (int sig, siginfo_t *info,
241 void *context __attribute__ ((unused)))
242 {
243 G *g;
244
245 g = runtime_g ();
246 if (g == NULL || info->si_code == SI_USER)
247 {
248 sig_handler (sig);
249 return;
250 }
251
252 g->sig = sig;
253 g->sigcode0 = info->si_code;
254 g->sigcode1 = (uintptr_t) info->si_addr;
255
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. */
258
259 sig_panic_leadin (sig);
260
261 switch (sig)
262 {
263 #ifdef SIGBUS
264 case SIGBUS:
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");
270 #endif
271
272 #ifdef SIGSEGV
273 case SIGSEGV:
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");
282 #endif
283
284 #ifdef SIGFPE
285 case SIGFPE:
286 switch (info->si_code)
287 {
288 case FPE_INTDIV:
289 runtime_panicstring ("integer divide by zero");
290 case FPE_INTOVF:
291 runtime_panicstring ("integer overflow");
292 }
293 runtime_panicstring ("floating point error");
294 #endif
295 }
296
297 /* All signals with SigPanic should be in cases above, and this
298 handler should only be invoked for those signals. */
299 __builtin_unreachable ();
300 }
301
302 #else /* !defined (SA_SIGINFO) */
303
304 static void
305 sig_panic_handler (int sig)
306 {
307 G *g;
308
309 g = runtime_g ();
310 if (g == NULL)
311 {
312 sig_handler (sig);
313 return;
314 }
315
316 g->sig = sig;
317 g->sigcode0 = 0;
318 g->sigcode1 = 0;
319
320 sig_panic_leadin (sig);
321
322 switch (sig)
323 {
324 #ifdef SIGBUS
325 case SIGBUS:
326 runtime_panicstring ("invalid memory address or "
327 "nil pointer dereference");
328 #endif
329
330 #ifdef SIGSEGV
331 case SIGSEGV:
332 runtime_panicstring ("invalid memory address or "
333 "nil pointer dereference");
334 #endif
335
336 #ifdef SIGFPE
337 case SIGFPE:
338 runtime_panicstring ("integer divide by zero or floating point error");
339 #endif
340 }
341
342 /* All signals with SigPanic should be in cases above, and this
343 handler should only be invoked for those signals. */
344 __builtin_unreachable ();
345 }
346
347 #endif /* !defined (SA_SIGINFO) */
348
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
351 the stack. */
352
353 static void
354 sig_tramp (int) __attribute__ ((no_split_stack));
355
356 static void
357 sig_tramp (int sig)
358 {
359 G *gp;
360 M *mp;
361
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.) */
365 gp = runtime_g ();
366 mp = runtime_m ();
367
368 if (gp != NULL)
369 {
370 #ifdef USING_SPLIT_STACK
371 __splitstack_getcontext (&gp->stack_context[0]);
372 #endif
373 }
374
375 if (gp != NULL && mp->gsignal != NULL)
376 {
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]);
381 #endif
382 }
383
384 sig_handler (sig);
385
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
389 correctly. */
390
391 if (gp != NULL)
392 {
393 #ifdef USING_SPLIT_STACK
394 __splitstack_setcontext (&gp->stack_context[0]);
395 #endif
396 }
397 }
398
399 void
400 runtime_setsig (int32 i, bool def __attribute__ ((unused)), bool restart)
401 {
402 struct sigaction sa;
403 int r;
404 SigTab *t;
405
406 memset (&sa, 0, sizeof sa);
407
408 r = sigfillset (&sa.sa_mask);
409 __go_assert (r == 0);
410
411 t = &runtime_sigtab[i];
412
413 if ((t->flags & SigPanic) == 0)
414 {
415 sa.sa_flags = SA_ONSTACK;
416 sa.sa_handler = sig_tramp;
417 }
418 else
419 {
420 #ifdef SA_SIGINFO
421 sa.sa_flags = SA_SIGINFO;
422 sa.sa_sigaction = sig_panic_info_handler;
423 #else
424 sa.sa_flags = 0;
425 sa.sa_handler = sig_panic_handler;
426 #endif
427 }
428
429 if (restart)
430 sa.sa_flags |= SA_RESTART;
431
432 if (sigaction (t->sig, &sa, NULL) != 0)
433 __go_assert (0);
434 }
435
436 /* Used by the os package to raise SIGPIPE. */
437
438 void os_sigpipe (void) __asm__ ("os.sigpipe");
439
440 void
441 os_sigpipe (void)
442 {
443 struct sigaction sa;
444 int i;
445
446 memset (&sa, 0, sizeof sa);
447
448 sa.sa_handler = SIG_DFL;
449
450 i = sigemptyset (&sa.sa_mask);
451 __go_assert (i == 0);
452
453 if (sigaction (SIGPIPE, &sa, NULL) != 0)
454 abort ();
455
456 raise (SIGPIPE);
457 }
458
459 void
460 runtime_setprof(bool on)
461 {
462 USED(on);
463 }