• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revision3ec66096627bb23fcbca943b1788456bd61092d9 (tree)
Time2016-09-24 01:34:28
AuthorPedro Alves <palves@redh...>
CommiterPedro Alves

Log Message

CATCH(e, RETURN_MASK_ERROR) -> CATCH(const gdb_error &e): core bits

This changes GDB's TRY/CATCH macros in a way that allowing changing
the CATCH sites to look a lot more like normal C++ catch blocks.
I.e., do:

- CATCH (e, RETURN_MASK_ERROR)
+ CATCH (const gdb_error &e)

And:

- CATCH (ex, RETURN_MASK_ALL)
+ CATCH (const gdb_exception &ex)

Note this simplifies the TRY_SJLJ/CATCH_SJLJ implementation, by no
longer supporting filter masks. The places where we need this will
always want to catch all exceptions, so nothing is missed.

Since the exception types used to filter errors vs QUITs are exposed
to current code, and, we no longer need to play macro tricks, we
rename them to something more sensible:

-struct gdb_exception_RETURN_MASK_ERROR : public gdb_exception_RETURN_MASK_ALL
+struct gdb_error : public gdb_exception
-struct gdb_exception_RETURN_MASK_QUIT : public gdb_exception_RETURN_MASK_ALL
+struct gdb_quit : public gdb_exception

and "struct gdb_exception_RETURN_MASK_ALL" is gone.

The logic is now:

- Code that wants to catch Ctrl-C as well as gdb errors can can
simply catch gdb_exception, the root exception type.
- Code that wants to only intercept errors while ignoring Ctrl-C
catches gdb_error instead.

Adding more exception types that inherit gdb_error so that catching
code wouldn't have to rethrow if it catches a gdb_error of the "wrong"
error type would be possible, though not done here.

The next patch adjusts the whole codebase to use the new CATCH form.

Change Summary

Incremental Difference

--- a/gdb/common/common-exceptions.c
+++ b/gdb/common/common-exceptions.c
@@ -55,26 +55,6 @@ struct catcher
5555 /* Where to go for throw_exception(). */
5656 static struct catcher *current_catcher;
5757
58-#if GDB_XCPT == GDB_XCPT_SJMP
59-
60-/* Return length of current_catcher list. */
61-
62-static int
63-catcher_list_size (void)
64-{
65- int size;
66- struct catcher *catcher;
67-
68- for (size = 0, catcher = current_catcher;
69- catcher != NULL;
70- catcher = catcher->prev)
71- ++size;
72-
73- return size;
74-}
75-
76-#endif
77-
7858 jmp_buf *
7959 exceptions_state_mc_init (void)
8060 {
@@ -178,29 +158,13 @@ exceptions_state_mc (enum catcher_action action)
178158 }
179159 }
180160
181-int
182-exceptions_state_mc_catch (struct gdb_exception *exception,
183- int mask)
161+struct gdb_exception
162+exceptions_state_mc_catch ()
184163 {
185- *exception = current_catcher->exception;
186- catcher_pop ();
164+ struct gdb_exception res = current_catcher->exception;
187165
188- if (exception->reason < 0)
189- {
190- if (mask & RETURN_MASK (exception->reason))
191- {
192- /* Exit normally and let the caller handle the
193- exception. */
194- return 1;
195- }
196-
197- /* The caller didn't request that the event be caught, relay the
198- event to the next exception_catch/CATCH_SJLJ. */
199- throw_exception_sjlj (*exception);
200- }
201-
202- /* No exception was thrown. */
203- return 0;
166+ catcher_pop ();
167+ return res;
204168 }
205169
206170 int
@@ -215,8 +179,6 @@ exceptions_state_mc_action_iter_1 (void)
215179 return exceptions_state_mc (CATCH_ITER_1);
216180 }
217181
218-#if GDB_XCPT != GDB_XCPT_SJMP
219-
220182 /* How many nested TRY blocks we have. See exception_messages and
221183 throw_it. */
222184
@@ -262,8 +224,6 @@ gdb_exception_sliced_copy (struct gdb_exception *to, const struct gdb_exception
262224 *to = *from;
263225 }
264226
265-#endif /* !GDB_XCPT_SJMP */
266-
267227 /* Return EXCEPTION to the nearest containing catch_errors(). */
268228
269229 void
@@ -279,25 +239,23 @@ throw_exception_sjlj (struct gdb_exception exception)
279239 longjmp (current_catcher->buf, exception.reason);
280240 }
281241
282-#if GDB_XCPT != GDB_XCPT_SJMP
283-
284242 /* Implementation of throw_exception that uses C++ try/catch. */
285243
286-static ATTRIBUTE_NORETURN void
287-throw_exception_cxx (struct gdb_exception exception)
244+ATTRIBUTE_NORETURN void
245+throw_exception (struct gdb_exception exception)
288246 {
289247 do_cleanups (all_cleanups ());
290248
291249 if (exception.reason == RETURN_QUIT)
292250 {
293- gdb_exception_RETURN_MASK_QUIT ex;
251+ gdb_quit ex;
294252
295253 gdb_exception_sliced_copy (&ex, &exception);
296254 throw ex;
297255 }
298256 else if (exception.reason == RETURN_ERROR)
299257 {
300- gdb_exception_RETURN_MASK_ERROR ex;
258+ gdb_error ex;
301259
302260 gdb_exception_sliced_copy (&ex, &exception);
303261 throw ex;
@@ -306,18 +264,6 @@ throw_exception_cxx (struct gdb_exception exception)
306264 gdb_assert_not_reached ("invalid return reason");
307265 }
308266
309-#endif
310-
311-void
312-throw_exception (struct gdb_exception exception)
313-{
314-#if GDB_XCPT == GDB_XCPT_SJMP
315- throw_exception_sjlj (exception);
316-#else
317- throw_exception_cxx (exception);
318-#endif
319-}
320-
321267 /* A stack of exception messages.
322268 This is needed to handle nested calls to throw_it: we don't want to
323269 xfree space for a message before it's used.
@@ -339,11 +285,7 @@ throw_it (enum return_reason reason, enum errors error, const char *fmt,
339285 {
340286 struct gdb_exception e;
341287 char *new_message;
342-#if GDB_XCPT == GDB_XCPT_SJMP
343- int depth = catcher_list_size ();
344-#else
345288 int depth = try_scope_depth;
346-#endif
347289
348290 gdb_assert (depth > 0);
349291
--- a/gdb/common/common-exceptions.h
+++ b/gdb/common/common-exceptions.h
@@ -119,10 +119,6 @@ struct gdb_exception
119119
120120 /* The different exception mechanisms that TRY/CATCH can map to. */
121121
122-/* Make GDB exceptions use setjmp/longjmp behind the scenes. This is
123- the only mode supported when GDB is built as a C program. */
124-#define GDB_XCPT_SJMP 1
125-
126122 /* Make GDB exceptions use try/catch behind the scenes. */
127123 #define GDB_XCPT_TRY 2
128124
@@ -132,11 +128,7 @@ struct gdb_exception
132128 spurious code between the TRY and the CATCH block. */
133129 #define GDB_XCPT_RAW_TRY 3
134130
135-#ifdef __cplusplus
136-# define GDB_XCPT GDB_XCPT_TRY
137-#else
138-# define GDB_XCPT GDB_XCPT_SJMP
139-#endif
131+#define GDB_XCPT GDB_XCPT_TRY
140132
141133 /* Functions to drive the sjlj-based exceptions state machine. Though
142134 declared here by necessity, these functions should be considered
@@ -146,15 +138,13 @@ struct gdb_exception
146138 extern jmp_buf *exceptions_state_mc_init (void);
147139 extern int exceptions_state_mc_action_iter (void);
148140 extern int exceptions_state_mc_action_iter_1 (void);
149-extern int exceptions_state_mc_catch (struct gdb_exception *, int);
141+extern struct gdb_exception exceptions_state_mc_catch ();
150142
151143 /* Same, but for the C++ try/catch-based TRY/CATCH mechanism. */
152144
153-#if GDB_XCPT != GDB_XCPT_SJMP
154145 extern void *exception_try_scope_entry (void);
155146 extern void exception_try_scope_exit (void *saved_state);
156147 extern void exception_rethrow (void);
157-#endif
158148
159149 /* Macro to wrap up standard try/catch behavior.
160150
@@ -184,7 +174,7 @@ extern void exception_rethrow (void);
184174 when TRY/CATCH are mapped to C++ try/catch. The SJLJ variants are
185175 needed in some cases where gdb exceptions need to cross third-party
186176 library code compiled without exceptions support (e.g.,
187- readline). */
177+ readline). Also, the SJLJ versions don't support a mask */
188178
189179 #define TRY_SJLJ \
190180 { \
@@ -195,27 +185,21 @@ extern void exception_rethrow (void);
195185 while (exceptions_state_mc_action_iter ()) \
196186 while (exceptions_state_mc_action_iter_1 ())
197187
198-#define CATCH_SJLJ(EXCEPTION, MASK) \
199- { \
200- struct gdb_exception EXCEPTION; \
201- if (exceptions_state_mc_catch (&(EXCEPTION), MASK))
188+/* Note: we create a local named temporary object instead of assigning
189+ EXCEPTION directly to the result of exceptions_state_mc_catch()
190+ directly, in order to allow catching by non-const reference, just
191+ like C++ try/catch. */
192+#define CATCH_SJLJ(EXCEPTION) \
193+ { \
194+ gdb_exception sjlj_exception_object = exceptions_state_mc_catch (); \
195+ if (sjlj_exception_object.reason < 0) \
196+ { \
197+ EXCEPTION = sjlj_exception_object;
202198
203199 #define END_CATCH_SJLJ \
200+ } \
204201 }
205202
206-#if GDB_XCPT == GDB_XCPT_SJMP
207-
208-/* If using SJLJ-based exceptions for all exceptions, then provide
209- standard aliases. */
210-
211-#define TRY TRY_SJLJ
212-#define CATCH CATCH_SJLJ
213-#define END_CATCH END_CATCH_SJLJ
214-
215-#endif /* GDB_XCPT_SJMP */
216-
217-#if GDB_XCPT == GDB_XCPT_TRY || GDB_XCPT == GDB_XCPT_RAW_TRY
218-
219203 /* Prevent error/quit during TRY from calling cleanups established
220204 prior to here. This pops out the scope in either case of normal
221205 exit or exception exit. */
@@ -236,54 +220,42 @@ struct exception_try_scope
236220 #if GDB_XCPT == GDB_XCPT_TRY
237221
238222 /* We still need to wrap TRY/CATCH in C++ so that cleanups and C++
239- exceptions can coexist. The TRY blocked is wrapped in a
240- do/while(0) so that break/continue within the block works the same
241- as in C. */
223+ exceptions can coexist. */
242224 #define TRY \
243225 try \
244226 { \
245- exception_try_scope exception_try_scope_instance; \
246- do \
247- {
227+ exception_try_scope exception_try_scope_instance;
248228
249-#define CATCH(EXCEPTION, MASK) \
250- } while (0); \
229+#define CATCH(EXCEPTION) \
251230 } \
252- catch (struct gdb_exception ## _ ## MASK &EXCEPTION)
231+ catch (EXCEPTION)
253232
254-#define END_CATCH \
255- catch (...) \
256- { \
257- exception_rethrow (); \
258- }
233+#define END_CATCH \
234+ catch (...) \
235+ { \
236+ exception_rethrow (); \
237+ }
259238
260239 #else
261240
262241 #define TRY try
263-#define CATCH(EXCEPTION, MASK) \
264- catch (struct gdb_exception ## _ ## MASK &EXCEPTION)
242+#define CATCH(EXCEPTION) \
243+ catch (EXCEPTION)
265244 #define END_CATCH
266245
267246 #endif
268247
269248 /* The exception types client code may catch. They're just shims
270- around gdb_exception that add nothing but type info. Which is used
271- is selected depending on the MASK argument passed to CATCH. */
249+ around gdb_exception that add nothing but type info. */
272250
273-struct gdb_exception_RETURN_MASK_ALL : public gdb_exception
251+struct gdb_error : public gdb_exception
274252 {
275253 };
276254
277-struct gdb_exception_RETURN_MASK_ERROR : public gdb_exception_RETURN_MASK_ALL
255+struct gdb_quit : public gdb_exception
278256 {
279257 };
280258
281-struct gdb_exception_RETURN_MASK_QUIT : public gdb_exception_RETURN_MASK_ALL
282-{
283-};
284-
285-#endif /* GDB_XCPT_TRY || GDB_XCPT_RAW_TRY */
286-
287259 /* An exception type that inherits from both std::bad_alloc and a gdb
288260 exception. This is necessary because operator new can only throw
289261 std::bad_alloc, and OTOH, we want exceptions thrown due to memory
@@ -291,7 +263,7 @@ struct gdb_exception_RETURN_MASK_QUIT : public gdb_exception_RETURN_MASK_ALL
291263 spread around the codebase. */
292264
293265 struct gdb_quit_bad_alloc
294- : public gdb_exception_RETURN_MASK_QUIT,
266+ : public gdb_quit,
295267 public std::bad_alloc
296268 {
297269 explicit gdb_quit_bad_alloc (gdb_exception ex)
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -162,8 +162,6 @@ void (*after_char_processing_hook) (void);
162162 static void
163163 gdb_rl_callback_read_char_wrapper (gdb_client_data client_data)
164164 {
165- struct gdb_exception gdb_expt = exception_none;
166-
167165 /* C++ exceptions can't normally be thrown across readline (unless
168166 it is built with -fexceptions, but it won't by default on many
169167 ABIs). So we instead wrap the readline call with a sjlj-based
@@ -174,15 +172,12 @@ gdb_rl_callback_read_char_wrapper (gdb_client_data client_data)
174172 if (after_char_processing_hook)
175173 (*after_char_processing_hook) ();
176174 }
177- CATCH_SJLJ (ex, RETURN_MASK_ALL)
175+ CATCH_SJLJ (const gdb_exception &ex)
178176 {
179- gdb_expt = ex;
177+ /* Rethrow using the normal EH mechanism. */
178+ throw_exception (ex);
180179 }
181180 END_CATCH_SJLJ
182-
183- /* Rethrow using the normal EH mechanism. */
184- if (gdb_expt.reason < 0)
185- throw_exception (gdb_expt);
186181 }
187182
188183 /* GDB's readline callback handler. Calls the current INPUT_HANDLER,