Update copyright year range in all GDB files.
[deliverable/binutils-gdb.git] / gdb / common / common-exceptions.h
1 /* Exception (throw catch) mechanism, for GDB, the GNU debugger.
2
3 Copyright (C) 1986-2019 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program 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
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #ifndef COMMON_EXCEPTIONS_H
21 #define COMMON_EXCEPTIONS_H
22
23 #include <setjmp.h>
24 #include <new>
25
26 /* Reasons for calling throw_exceptions(). NOTE: all reason values
27 must be different from zero. enum value 0 is reserved for internal
28 use as the return value from an initial setjmp(). */
29
30 enum return_reason
31 {
32 /* User interrupt. */
33 RETURN_QUIT = -2,
34 /* Any other error. */
35 RETURN_ERROR
36 };
37
38 #define RETURN_MASK(reason) (1 << (int)(-reason))
39
40 typedef enum
41 {
42 RETURN_MASK_QUIT = RETURN_MASK (RETURN_QUIT),
43 RETURN_MASK_ERROR = RETURN_MASK (RETURN_ERROR),
44 RETURN_MASK_ALL = (RETURN_MASK_QUIT | RETURN_MASK_ERROR)
45 } return_mask;
46
47 /* Describe all exceptions. */
48
49 enum errors {
50 GDB_NO_ERROR,
51
52 /* Any generic error, the corresponding text is in
53 exception.message. */
54 GENERIC_ERROR,
55
56 /* Something requested was not found. */
57 NOT_FOUND_ERROR,
58
59 /* Thread library lacks support necessary for finding thread local
60 storage. */
61 TLS_NO_LIBRARY_SUPPORT_ERROR,
62
63 /* Load module not found while attempting to find thread local storage. */
64 TLS_LOAD_MODULE_NOT_FOUND_ERROR,
65
66 /* Thread local storage has not been allocated yet. */
67 TLS_NOT_ALLOCATED_YET_ERROR,
68
69 /* Something else went wrong while attempting to find thread local
70 storage. The ``struct gdb_exception'' message field provides
71 more detail. */
72 TLS_GENERIC_ERROR,
73
74 /* Problem parsing an XML document. */
75 XML_PARSE_ERROR,
76
77 /* Error accessing memory. */
78 MEMORY_ERROR,
79
80 /* Value not available. E.g., a register was not collected in a
81 traceframe. */
82 NOT_AVAILABLE_ERROR,
83
84 /* Value was optimized out. Note: if the value was a register, this
85 means the register was not saved in the frame. */
86 OPTIMIZED_OUT_ERROR,
87
88 /* DW_OP_entry_value resolving failed. */
89 NO_ENTRY_VALUE_ERROR,
90
91 /* Target throwing an error has been closed. Current command should be
92 aborted as the inferior state is no longer valid. */
93 TARGET_CLOSE_ERROR,
94
95 /* An undefined command was executed. */
96 UNDEFINED_COMMAND_ERROR,
97
98 /* Requested feature, method, mechanism, etc. is not supported. */
99 NOT_SUPPORTED_ERROR,
100
101 /* The number of candidates generated during line completion has
102 reached the user's specified limit. This isn't an error, this exception
103 is used to halt searching for more completions, but for consistency
104 "_ERROR" is appended to the name. */
105 MAX_COMPLETIONS_REACHED_ERROR,
106
107 /* Add more errors here. */
108 NR_ERRORS
109 };
110
111 struct gdb_exception
112 {
113 enum return_reason reason;
114 enum errors error;
115 const char *message;
116 };
117
118 /* The different exception mechanisms that TRY/CATCH can map to. */
119
120 /* Make GDB exceptions use setjmp/longjmp behind the scenes. */
121 #define GDB_XCPT_SJMP 1
122
123 /* Make GDB exceptions use try/catch behind the scenes. */
124 #define GDB_XCPT_TRY 2
125
126 /* Specify this mode to build with TRY/CATCH mapped directly to raw
127 try/catch. GDB won't work correctly, but building that way catches
128 code tryin to break/continue out of the try block, along with
129 spurious code between the TRY and the CATCH block. */
130 #define GDB_XCPT_RAW_TRY 3
131
132 #define GDB_XCPT GDB_XCPT_TRY
133
134 /* Functions to drive the sjlj-based exceptions state machine. Though
135 declared here by necessity, these functions should be considered
136 internal to the exceptions subsystem and not used other than via
137 the TRY/CATCH (or TRY_SJLJ/CATCH_SJLJ) macros defined below. */
138
139 extern jmp_buf *exceptions_state_mc_init (void);
140 extern int exceptions_state_mc_action_iter (void);
141 extern int exceptions_state_mc_action_iter_1 (void);
142 extern int exceptions_state_mc_catch (struct gdb_exception *, int);
143
144 /* Same, but for the C++ try/catch-based TRY/CATCH mechanism. */
145
146 #if GDB_XCPT != GDB_XCPT_SJMP
147 extern void *exception_try_scope_entry (void);
148 extern void exception_try_scope_exit (void *saved_state);
149 extern void exception_rethrow (void) ATTRIBUTE_NORETURN;
150 #endif
151
152 /* Macro to wrap up standard try/catch behavior.
153
154 The double loop lets us correctly handle code "break"ing out of the
155 try catch block. (It works as the "break" only exits the inner
156 "while" loop, the outer for loop detects this handling it
157 correctly.) Of course "return" and "goto" are not so lucky.
158
159 For instance:
160
161 *INDENT-OFF*
162
163 TRY
164 {
165 }
166 CATCH (e, RETURN_MASK_ERROR)
167 {
168 switch (e.reason)
169 {
170 case RETURN_ERROR: ...
171 }
172 }
173 END_CATCH
174
175 Note that the SJLJ version of the macros are actually named
176 TRY_SJLJ/CATCH_SJLJ in order to make it possible to call them even
177 when TRY/CATCH are mapped to C++ try/catch. The SJLJ variants are
178 needed in some cases where gdb exceptions need to cross third-party
179 library code compiled without exceptions support (e.g.,
180 readline). */
181
182 #define TRY_SJLJ \
183 { \
184 jmp_buf *buf = \
185 exceptions_state_mc_init (); \
186 setjmp (*buf); \
187 } \
188 while (exceptions_state_mc_action_iter ()) \
189 while (exceptions_state_mc_action_iter_1 ())
190
191 #define CATCH_SJLJ(EXCEPTION, MASK) \
192 { \
193 struct gdb_exception EXCEPTION; \
194 if (exceptions_state_mc_catch (&(EXCEPTION), MASK))
195
196 #define END_CATCH_SJLJ \
197 }
198
199 #if GDB_XCPT == GDB_XCPT_SJMP
200
201 /* If using SJLJ-based exceptions for all exceptions, then provide
202 standard aliases. */
203
204 #define TRY TRY_SJLJ
205 #define CATCH CATCH_SJLJ
206 #define END_CATCH END_CATCH_SJLJ
207
208 #endif /* GDB_XCPT_SJMP */
209
210 #if GDB_XCPT == GDB_XCPT_TRY || GDB_XCPT == GDB_XCPT_RAW_TRY
211
212 /* Prevent error/quit during TRY from calling cleanups established
213 prior to here. This pops out the scope in either case of normal
214 exit or exception exit. */
215 struct exception_try_scope
216 {
217 exception_try_scope ()
218 {
219 saved_state = exception_try_scope_entry ();
220 }
221 ~exception_try_scope ()
222 {
223 exception_try_scope_exit (saved_state);
224 }
225
226 void *saved_state;
227 };
228
229 #if GDB_XCPT == GDB_XCPT_TRY
230
231 /* We still need to wrap TRY/CATCH in C++ so that cleanups and C++
232 exceptions can coexist.
233
234 The TRY blocked is wrapped in a do/while(0) so that break/continue
235 within the block works the same as in C.
236
237 END_CATCH makes sure that even if the CATCH block doesn't want to
238 catch the exception, we stop at every frame in the unwind chain to
239 run its cleanups, which may e.g., have pointers to stack variables
240 that are going to be destroyed.
241
242 There's an outer scope around the whole TRY/END_CATCH in order to
243 cause a compilation error if you forget to add the END_CATCH at the
244 end a TRY/CATCH construct. */
245
246 #define TRY \
247 { \
248 try \
249 { \
250 exception_try_scope exception_try_scope_instance; \
251 do \
252 {
253
254 #define CATCH(EXCEPTION, MASK) \
255 } while (0); \
256 } \
257 catch (struct gdb_exception ## _ ## MASK &EXCEPTION)
258
259 #define END_CATCH \
260 catch (...) \
261 { \
262 exception_rethrow (); \
263 } \
264 }
265
266 #else
267
268 #define TRY try
269 #define CATCH(EXCEPTION, MASK) \
270 catch (struct gdb_exception ## _ ## MASK &EXCEPTION)
271 #define END_CATCH
272
273 #endif
274
275 /* The exception types client code may catch. They're just shims
276 around gdb_exception that add nothing but type info. Which is used
277 is selected depending on the MASK argument passed to CATCH. */
278
279 struct gdb_exception_RETURN_MASK_ALL : public gdb_exception
280 {
281 };
282
283 struct gdb_exception_RETURN_MASK_ERROR : public gdb_exception_RETURN_MASK_ALL
284 {
285 };
286
287 struct gdb_exception_RETURN_MASK_QUIT : public gdb_exception_RETURN_MASK_ALL
288 {
289 };
290
291 #endif /* GDB_XCPT_TRY || GDB_XCPT_RAW_TRY */
292
293 /* An exception type that inherits from both std::bad_alloc and a gdb
294 exception. This is necessary because operator new can only throw
295 std::bad_alloc, and OTOH, we want exceptions thrown due to memory
296 allocation error to be caught by all the CATCH/RETURN_MASK_ALL
297 spread around the codebase. */
298
299 struct gdb_quit_bad_alloc
300 : public gdb_exception_RETURN_MASK_QUIT,
301 public std::bad_alloc
302 {
303 explicit gdb_quit_bad_alloc (gdb_exception ex)
304 : std::bad_alloc ()
305 {
306 gdb_exception *self = this;
307
308 *self = ex;
309 }
310 };
311
312 /* *INDENT-ON* */
313
314 /* Throw an exception (as described by "struct gdb_exception"),
315 landing in the inner most containing exception handler established
316 using TRY/CATCH. */
317 extern void throw_exception (struct gdb_exception exception)
318 ATTRIBUTE_NORETURN;
319
320 /* Throw an exception by executing a LONG JUMP to the inner most
321 containing exception handler established using TRY_SJLJ. Necessary
322 in some cases where we need to throw GDB exceptions across
323 third-party library code (e.g., readline). */
324 extern void throw_exception_sjlj (struct gdb_exception exception)
325 ATTRIBUTE_NORETURN;
326
327 /* Convenience wrappers around throw_exception that throw GDB
328 errors. */
329 extern void throw_verror (enum errors, const char *fmt, va_list ap)
330 ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0);
331 extern void throw_vquit (const char *fmt, va_list ap)
332 ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0);
333 extern void throw_error (enum errors error, const char *fmt, ...)
334 ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3);
335 extern void throw_quit (const char *fmt, ...)
336 ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2);
337
338 /* A pre-defined non-exception. */
339 extern const struct gdb_exception exception_none;
340
341 #endif /* COMMON_EXCEPTIONS_H */
This page took 0.037616 seconds and 4 git commands to generate.