]>
Commit | Line | Data |
---|---|---|
8b67b708 | 1 | /* Handling of compile-time options that influence the library. |
3881a3de HA |
2 | Copyright (C) 2005, 2007, 2009, 2010, 2011, 2012 |
3 | Free Software Foundation, Inc. | |
8b67b708 | 4 | |
58fc89f6 | 5 | This file is part of the GNU Fortran runtime library (libgfortran). |
8b67b708 FXC |
6 | |
7 | Libgfortran is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
748086b7 | 9 | the Free Software Foundation; either version 3, or (at your option) |
8b67b708 FXC |
10 | any later version. |
11 | ||
8b67b708 FXC |
12 | Libgfortran is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
748086b7 JJ |
17 | Under Section 7 of GPL version 3, you are granted additional |
18 | permissions described in the GCC Runtime Library Exception, version | |
19 | 3.1, as published by the Free Software Foundation. | |
20 | ||
21 | You should have received a copy of the GNU General Public License and | |
22 | a copy of the GCC Runtime Library Exception along with this program; | |
23 | see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
24 | <http://www.gnu.org/licenses/>. */ | |
8b67b708 | 25 | |
8b67b708 | 26 | #include "libgfortran.h" |
2b840e50 | 27 | #include <signal.h> |
2b840e50 | 28 | |
8b67b708 FXC |
29 | |
30 | /* Useful compile-time options will be stored in here. */ | |
31 | compile_options_t compile_options; | |
32 | ||
2b840e50 | 33 | |
de8bd142 JB |
34 | volatile sig_atomic_t fatal_error_in_progress = 0; |
35 | ||
3881a3de HA |
36 | |
37 | /* Helper function for backtrace_handler to write information about the | |
38 | received signal to stderr before actually giving the backtrace. */ | |
39 | static void | |
40 | show_signal (int signum) | |
41 | { | |
42 | const char * name = NULL, * desc = NULL; | |
43 | ||
44 | switch (signum) | |
45 | { | |
59c61547 TB |
46 | #if defined(SIGQUIT) |
47 | case SIGQUIT: | |
48 | name = "SIGQUIT"; | |
49 | desc = "Terminal quit signal"; | |
50 | break; | |
51 | #endif | |
52 | ||
53 | /* The following 4 signals are defined by C89. */ | |
54 | case SIGILL: | |
55 | name = "SIGILL"; | |
56 | desc = "Illegal instruction"; | |
57 | break; | |
58 | ||
59 | case SIGABRT: | |
60 | name = "SIGABRT"; | |
61 | desc = "Process abort signal"; | |
62 | break; | |
63 | ||
64 | case SIGFPE: | |
65 | name = "SIGFPE"; | |
66 | desc = "Floating-point exception - erroneous arithmetic operation"; | |
67 | break; | |
68 | ||
3881a3de HA |
69 | case SIGSEGV: |
70 | name = "SIGSEGV"; | |
59c61547 | 71 | desc = "Segmentation fault - invalid memory reference"; |
3881a3de | 72 | break; |
3881a3de HA |
73 | |
74 | #if defined(SIGBUS) | |
75 | case SIGBUS: | |
76 | name = "SIGBUS"; | |
59c61547 | 77 | desc = "Access to an undefined portion of a memory object"; |
3881a3de HA |
78 | break; |
79 | #endif | |
80 | ||
59c61547 TB |
81 | #if defined(SIGSYS) |
82 | case SIGSYS: | |
83 | name = "SIGSYS"; | |
84 | desc = "Bad system call"; | |
3881a3de HA |
85 | break; |
86 | #endif | |
87 | ||
59c61547 TB |
88 | #if defined(SIGTRAP) |
89 | case SIGTRAP: | |
90 | name = "SIGTRAP"; | |
91 | desc = "Trace/breakpoint trap"; | |
92 | break; | |
93 | #endif | |
94 | ||
95 | #if defined(SIGXCPU) | |
96 | case SIGXCPU: | |
97 | name = "SIGXCPU"; | |
98 | desc = "CPU time limit exceeded"; | |
99 | break; | |
100 | #endif | |
101 | ||
102 | #if defined(SIGXFSZ) | |
103 | case SIGXFSZ: | |
104 | name = "SIGXFSZ"; | |
105 | desc = "File size limit exceeded"; | |
3881a3de HA |
106 | break; |
107 | #endif | |
108 | } | |
109 | ||
110 | if (name) | |
59c61547 | 111 | st_printf ("\nProgram received signal %s: %s.\n", name, desc); |
3881a3de HA |
112 | else |
113 | st_printf ("\nProgram received signal %d.\n", signum); | |
114 | } | |
115 | ||
116 | ||
2b840e50 FXC |
117 | /* A signal handler to allow us to output a backtrace. */ |
118 | void | |
de8bd142 | 119 | backtrace_handler (int signum) |
2b840e50 | 120 | { |
de8bd142 JB |
121 | /* Since this handler is established for more than one kind of signal, |
122 | it might still get invoked recursively by delivery of some other kind | |
123 | of signal. Use a static variable to keep track of that. */ | |
124 | if (fatal_error_in_progress) | |
125 | raise (signum); | |
126 | fatal_error_in_progress = 1; | |
127 | ||
3881a3de | 128 | show_signal (signum); |
de8bd142 JB |
129 | show_backtrace(); |
130 | ||
131 | /* Now reraise the signal. We reactivate the signal's | |
132 | default handling, which is to terminate the process. | |
133 | We could just call exit or abort, | |
134 | but reraising the signal sets the return status | |
135 | from the process correctly. */ | |
136 | signal (signum, SIG_DFL); | |
137 | raise (signum); | |
2b840e50 FXC |
138 | } |
139 | ||
140 | ||
155732f5 JB |
141 | /* Helper function for set_options because we need to access the |
142 | global variable options which is not seen in set_options. */ | |
143 | static void | |
144 | maybe_find_addr2line (void) | |
145 | { | |
146 | if (options.backtrace == -1) | |
147 | find_addr2line (); | |
148 | } | |
149 | ||
2bb6de3a JD |
150 | /* Set the usual compile-time options. */ |
151 | extern void set_options (int , int []); | |
152 | export_proto(set_options); | |
8b67b708 FXC |
153 | |
154 | void | |
2bb6de3a | 155 | set_options (int num, int options[]) |
8b67b708 | 156 | { |
2bb6de3a JD |
157 | if (num >= 1) |
158 | compile_options.warn_std = options[0]; | |
159 | if (num >= 2) | |
160 | compile_options.allow_std = options[1]; | |
161 | if (num >= 3) | |
162 | compile_options.pedantic = options[2]; | |
de8bd142 JB |
163 | /* options[3] is the removed -fdump-core option. It's place in the |
164 | options array is retained due to ABI compatibility. Remove when | |
165 | bumping the library ABI. */ | |
2bb6de3a JD |
166 | if (num >= 5) |
167 | compile_options.backtrace = options[4]; | |
168 | if (num >= 6) | |
169 | compile_options.sign_zero = options[5]; | |
18fe404f TK |
170 | if (num >= 7) |
171 | compile_options.bounds_check = options[6]; | |
80b91c0b JB |
172 | /* options[7] is the -frange-check option, which no longer affects |
173 | the library behavior; range checking is now always done when | |
174 | parsing integers. It's place in the options array is retained due | |
175 | to ABI compatibility. Remove when bumping the library ABI. */ | |
2b840e50 | 176 | |
de8bd142 JB |
177 | /* If backtrace is required, we set signal handlers on the POSIX |
178 | 2001 signals with core action. */ | |
2b840e50 FXC |
179 | if (compile_options.backtrace) |
180 | { | |
de8bd142 JB |
181 | #if defined(SIGQUIT) |
182 | signal (SIGQUIT, backtrace_handler); | |
183 | #endif | |
184 | ||
74544378 | 185 | /* The following 4 signals are defined by C89. */ |
de8bd142 | 186 | signal (SIGILL, backtrace_handler); |
de8bd142 | 187 | signal (SIGABRT, backtrace_handler); |
de8bd142 | 188 | signal (SIGFPE, backtrace_handler); |
de8bd142 | 189 | signal (SIGSEGV, backtrace_handler); |
2b840e50 FXC |
190 | |
191 | #if defined(SIGBUS) | |
de8bd142 | 192 | signal (SIGBUS, backtrace_handler); |
2b840e50 FXC |
193 | #endif |
194 | ||
de8bd142 JB |
195 | #if defined(SIGSYS) |
196 | signal (SIGSYS, backtrace_handler); | |
2b840e50 FXC |
197 | #endif |
198 | ||
de8bd142 JB |
199 | #if defined(SIGTRAP) |
200 | signal (SIGTRAP, backtrace_handler); | |
201 | #endif | |
202 | ||
203 | #if defined(SIGXCPU) | |
204 | signal (SIGXCPU, backtrace_handler); | |
205 | #endif | |
206 | ||
207 | #if defined(SIGXFSZ) | |
208 | signal (SIGXFSZ, backtrace_handler); | |
2b840e50 | 209 | #endif |
155732f5 JB |
210 | |
211 | maybe_find_addr2line (); | |
2b840e50 | 212 | } |
8b67b708 FXC |
213 | } |
214 | ||
215 | ||
216 | /* Default values for the compile-time options. Keep in sync with | |
217 | gcc/fortran/options.c (gfc_init_options). */ | |
218 | void | |
219 | init_compile_options (void) | |
220 | { | |
5fb41e29 | 221 | compile_options.warn_std = GFC_STD_F95_DEL | GFC_STD_LEGACY; |
8b67b708 | 222 | compile_options.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL |
5fb41e29 | 223 | | GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77 |
58fc89f6 | 224 | | GFC_STD_F2008_OBS | GFC_STD_GNU | GFC_STD_LEGACY; |
5f8f5313 | 225 | compile_options.pedantic = 0; |
868d75db | 226 | compile_options.backtrace = 0; |
2bb6de3a | 227 | compile_options.sign_zero = 1; |
8b67b708 | 228 | } |
eaa90d25 TK |
229 | |
230 | /* Function called by the front-end to tell us the | |
231 | default for unformatted data conversion. */ | |
232 | ||
233 | extern void set_convert (int); | |
234 | export_proto (set_convert); | |
235 | ||
236 | void | |
237 | set_convert (int conv) | |
238 | { | |
239 | compile_options.convert = conv; | |
240 | } | |
d67ab5ee TK |
241 | |
242 | extern void set_record_marker (int); | |
243 | export_proto (set_record_marker); | |
244 | ||
245 | ||
246 | void | |
247 | set_record_marker (int val) | |
248 | { | |
249 | ||
250 | switch(val) | |
251 | { | |
252 | case 4: | |
07b3bbf2 | 253 | compile_options.record_marker = sizeof (GFC_INTEGER_4); |
d67ab5ee TK |
254 | break; |
255 | ||
256 | case 8: | |
07b3bbf2 | 257 | compile_options.record_marker = sizeof (GFC_INTEGER_8); |
d67ab5ee TK |
258 | break; |
259 | ||
260 | default: | |
261 | runtime_error ("Invalid value for record marker"); | |
262 | break; | |
263 | } | |
264 | } | |
07b3bbf2 TK |
265 | |
266 | extern void set_max_subrecord_length (int); | |
267 | export_proto (set_max_subrecord_length); | |
268 | ||
269 | void set_max_subrecord_length(int val) | |
270 | { | |
271 | if (val > GFC_MAX_SUBRECORD_LENGTH || val < 1) | |
272 | { | |
273 | runtime_error ("Invalid value for maximum subrecord length"); | |
274 | return; | |
275 | } | |
276 | ||
277 | compile_options.max_subrecord_length = val; | |
278 | } |