OSDN Git Service

Don't catch LIBPROF in Go code.
[pf3gnuchains/gcc-fork.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
10 #include "go-assert.h"
11 #include "go-panic.h"
12 #include "go-signal.h"
13
14 #include "runtime.h"
15
16 #undef int 
17
18 #ifndef SA_ONSTACK
19 #define SA_ONSTACK 0
20 #endif
21
22 /* What to do for a signal.  */
23
24 struct sigtab
25 {
26   /* Signal number.  */
27   int sig;
28   /* Nonzero if the signal should be ignored.  */
29   _Bool ignore;
30 };
31
32 /* What to do for signals.  */
33
34 static struct sigtab signals[] =
35 {
36   { SIGHUP, 0 },
37   { SIGINT, 0 },
38   { SIGALRM, 1 },
39   { SIGTERM, 0 },
40 #ifdef SIGBUS
41   { SIGBUS, 0 },
42 #endif
43 #ifdef SIGFPE
44   { SIGFPE, 0 },
45 #endif
46 #ifdef SIGUSR1
47   { SIGUSR1, 1 },
48 #endif
49 #ifdef SIGSEGV
50   { SIGSEGV, 0 },
51 #endif
52 #ifdef SIGUSR2
53   { SIGUSR2, 1 },
54 #endif
55 #ifdef SIGPIPE
56   { SIGPIPE, 1 },
57 #endif
58 #ifdef SIGCHLD
59   { SIGCHLD, 1 },
60 #endif
61 #ifdef SIGTSTP
62   { SIGTSTP, 1 },
63 #endif
64 #ifdef SIGTTIN
65   { SIGTTIN, 1 },
66 #endif
67 #ifdef SIGTTOU
68   { SIGTTOU, 1 },
69 #endif
70 #ifdef SIGURG
71   { SIGURG, 1 },
72 #endif
73 #ifdef SIGXCPU
74   { SIGXCPU, 1 },
75 #endif
76 #ifdef SIGXFSZ
77   { SIGXFSZ, 1 },
78 #endif
79 #ifdef SIGVTARLM
80   { SIGVTALRM, 1 },
81 #endif
82 #ifdef SIGWINCH
83   { SIGWINCH, 1 },
84 #endif
85 #ifdef SIGIO
86   { SIGIO, 1 },
87 #endif
88 #ifdef SIGPWR
89   { SIGPWR, 1 },
90 #endif
91   { -1, 0 }
92 };
93
94 /* The Go signal handler.  */
95
96 static void
97 sighandler (int sig)
98 {
99   const char *msg;
100   int i;
101
102   /* FIXME: Should check siginfo for more information when
103      available.  */
104   msg = NULL;
105   switch (sig)
106     {
107 #ifdef SIGBUS
108     case SIGBUS:
109       msg = "invalid memory address or nil pointer dereference";
110       break;
111 #endif
112
113 #ifdef SIGFPE
114     case SIGFPE:
115       msg = "integer divide by zero or floating point error";
116       break;
117 #endif
118
119 #ifdef SIGSEGV
120     case SIGSEGV:
121       msg = "invalid memory address or nil pointer dereference";
122       break;
123 #endif
124
125     default:
126       break;
127     }
128
129   if (msg != NULL)
130     {
131       sigset_t clear;
132
133       if (__sync_bool_compare_and_swap (&m->mallocing, 1, 1))
134         {
135           fprintf (stderr, "caught signal while mallocing: %s\n", msg);
136           __go_assert (0);
137         }
138
139       /* The signal handler blocked signals; unblock them.  */
140       i = sigfillset (&clear);
141       __go_assert (i == 0);
142       i = sigprocmask (SIG_UNBLOCK, &clear, NULL);
143       __go_assert (i == 0);
144
145       __go_panic_msg (msg);
146     }
147
148   if (__go_sigsend (sig))
149     return;
150   for (i = 0; signals[i].sig != -1; ++i)
151     {
152       if (signals[i].sig == sig)
153         {
154           struct sigaction sa;
155
156           if (signals[i].ignore)
157             return;
158
159           memset (&sa, 0, sizeof sa);
160
161           sa.sa_handler = SIG_DFL;
162
163           i = sigemptyset (&sa.sa_mask);
164           __go_assert (i == 0);
165
166           if (sigaction (sig, &sa, NULL) != 0)
167             abort ();
168
169           raise (sig);
170           exit (2);
171         }
172     }
173   abort ();
174 }
175
176 /* Initialize signal handling for Go.  This is called when the program
177    starts.  */
178
179 void
180 __initsig ()
181 {
182   struct sigaction sa;
183   int i;
184
185   siginit ();
186
187   memset (&sa, 0, sizeof sa);
188
189   sa.sa_handler = sighandler;
190
191   i = sigfillset (&sa.sa_mask);
192   __go_assert (i == 0);
193
194   for (i = 0; signals[i].sig != -1; ++i)
195     if (sigaction (signals[i].sig, &sa, NULL) != 0)
196       __go_assert (0);
197 }