OLD | NEW |
1 /* Exception (throw catch) mechanism, for GDB, the GNU debugger. | 1 /* Exception (throw catch) mechanism, for GDB, the GNU debugger. |
2 | 2 |
3 Copyright (C) 1986, 1988-2012 Free Software Foundation, Inc. | 3 Copyright (C) 1986, 1988-2012 Free Software Foundation, Inc. |
4 | 4 |
5 This file is part of GDB. | 5 This file is part of GDB. |
6 | 6 |
7 This program is free software; you can redistribute it and/or modify | 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 | 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 | 9 the Free Software Foundation; either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 /* Saved/current state. */ | 59 /* Saved/current state. */ |
60 int mask; | 60 int mask; |
61 struct cleanup *saved_cleanup_chain; | 61 struct cleanup *saved_cleanup_chain; |
62 /* Back link. */ | 62 /* Back link. */ |
63 struct catcher *prev; | 63 struct catcher *prev; |
64 }; | 64 }; |
65 | 65 |
66 /* Where to go for throw_exception(). */ | 66 /* Where to go for throw_exception(). */ |
67 static struct catcher *current_catcher; | 67 static struct catcher *current_catcher; |
68 | 68 |
| 69 /* Return length of current_catcher list. */ |
| 70 |
| 71 static int |
| 72 catcher_list_size (void) |
| 73 { |
| 74 int size; |
| 75 struct catcher *catcher; |
| 76 |
| 77 for (size = 0, catcher = current_catcher; |
| 78 catcher != NULL; |
| 79 catcher = catcher->prev) |
| 80 ++size; |
| 81 |
| 82 return size; |
| 83 } |
| 84 |
69 EXCEPTIONS_SIGJMP_BUF * | 85 EXCEPTIONS_SIGJMP_BUF * |
70 exceptions_state_mc_init (volatile struct gdb_exception *exception, | 86 exceptions_state_mc_init (volatile struct gdb_exception *exception, |
71 return_mask mask) | 87 return_mask mask) |
72 { | 88 { |
73 struct catcher *new_catcher = XZALLOC (struct catcher); | 89 struct catcher *new_catcher = XZALLOC (struct catcher); |
74 | 90 |
75 /* Start with no exception, save it's address. */ | 91 /* Start with no exception, save it's address. */ |
76 exception->reason = 0; | 92 exception->reason = 0; |
77 exception->error = GDB_NO_ERROR; | 93 exception->error = GDB_NO_ERROR; |
78 exception->message = NULL; | 94 exception->message = NULL; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 } | 217 } |
202 | 218 |
203 /* Return EXCEPTION to the nearest containing catch_errors(). */ | 219 /* Return EXCEPTION to the nearest containing catch_errors(). */ |
204 | 220 |
205 void | 221 void |
206 throw_exception (struct gdb_exception exception) | 222 throw_exception (struct gdb_exception exception) |
207 { | 223 { |
208 quit_flag = 0; | 224 quit_flag = 0; |
209 immediate_quit = 0; | 225 immediate_quit = 0; |
210 | 226 |
211 do_cleanups (ALL_CLEANUPS); | 227 do_cleanups (all_cleanups ()); |
212 | 228 |
213 /* Jump to the containing catch_errors() call, communicating REASON | 229 /* Jump to the containing catch_errors() call, communicating REASON |
214 to that call via setjmp's return value. Note that REASON can't | 230 to that call via setjmp's return value. Note that REASON can't |
215 be zero, by definition in defs.h. */ | 231 be zero, by definition in defs.h. */ |
216 exceptions_state_mc (CATCH_THROWING); | 232 exceptions_state_mc (CATCH_THROWING); |
217 *current_catcher->exception = exception; | 233 *current_catcher->exception = exception; |
218 EXCEPTIONS_SIGLONGJMP (current_catcher->buf, exception.reason); | 234 EXCEPTIONS_SIGLONGJMP (current_catcher->buf, exception.reason); |
219 } | 235 } |
220 | 236 |
221 static char *last_message; | |
222 | |
223 void | 237 void |
224 deprecated_throw_reason (enum return_reason reason) | 238 deprecated_throw_reason (enum return_reason reason) |
225 { | 239 { |
226 struct gdb_exception exception; | 240 struct gdb_exception exception; |
227 | 241 |
228 memset (&exception, 0, sizeof exception); | 242 memset (&exception, 0, sizeof exception); |
229 | 243 |
230 exception.reason = reason; | 244 exception.reason = reason; |
231 switch (reason) | 245 switch (reason) |
232 { | 246 { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 gdb_flush (gdb_stdout); | 364 gdb_flush (gdb_stdout); |
351 annotate_error_begin (); | 365 annotate_error_begin (); |
352 | 366 |
353 /* Print the prefix. */ | 367 /* Print the prefix. */ |
354 if (prefix != NULL && prefix[0] != '\0') | 368 if (prefix != NULL && prefix[0] != '\0') |
355 fputs_filtered (prefix, file); | 369 fputs_filtered (prefix, file); |
356 print_exception (file, e); | 370 print_exception (file, e); |
357 } | 371 } |
358 } | 372 } |
359 | 373 |
| 374 /* A stack of exception messages. |
| 375 This is needed to handle nested calls to throw_it: we don't want to |
| 376 xfree space for a message before it's used. |
| 377 This can happen if we throw an exception during a cleanup: |
| 378 An outer TRY_CATCH may have an exception message it wants to print, |
| 379 but while doing cleanups further calls to throw_it are made. |
| 380 |
| 381 This is indexed by the size of the current_catcher list. |
| 382 It is a dynamically allocated array so that we don't care how deeply |
| 383 GDB nests its TRY_CATCHs. */ |
| 384 static char **exception_messages; |
| 385 |
| 386 /* The number of currently allocated entries in exception_messages. */ |
| 387 static int exception_messages_size; |
| 388 |
360 static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0) | 389 static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0) |
361 throw_it (enum return_reason reason, enum errors error, const char *fmt, | 390 throw_it (enum return_reason reason, enum errors error, const char *fmt, |
362 va_list ap) | 391 va_list ap) |
363 { | 392 { |
364 struct gdb_exception e; | 393 struct gdb_exception e; |
365 char *new_message; | 394 char *new_message; |
| 395 int depth = catcher_list_size (); |
366 | 396 |
367 /* Save the message. Create the new message before deleting the | 397 gdb_assert (depth > 0); |
368 old, the new message may include the old message text. */ | 398 |
| 399 /* Note: The new message may use an old message's text. */ |
369 new_message = xstrvprintf (fmt, ap); | 400 new_message = xstrvprintf (fmt, ap); |
370 xfree (last_message); | 401 |
371 last_message = new_message; | 402 if (depth > exception_messages_size) |
| 403 { |
| 404 int old_size = exception_messages_size; |
| 405 |
| 406 exception_messages_size = depth + 10; |
| 407 exception_messages = (char **) xrealloc (exception_messages, |
| 408 » » » » » exception_messages_size |
| 409 » » » » » * sizeof (char *)); |
| 410 memset (exception_messages + old_size, 0, |
| 411 » (exception_messages_size - old_size) * sizeof (char *)); |
| 412 } |
| 413 |
| 414 xfree (exception_messages[depth - 1]); |
| 415 exception_messages[depth - 1] = new_message; |
372 | 416 |
373 /* Create the exception. */ | 417 /* Create the exception. */ |
374 e.reason = reason; | 418 e.reason = reason; |
375 e.error = error; | 419 e.error = error; |
376 e.message = last_message; | 420 e.message = new_message; |
377 | 421 |
378 /* Throw the exception. */ | 422 /* Throw the exception. */ |
379 throw_exception (e); | 423 throw_exception (e); |
380 } | 424 } |
381 | 425 |
382 void | 426 void |
383 throw_verror (enum errors error, const char *fmt, va_list ap) | 427 throw_verror (enum errors error, const char *fmt, va_list ap) |
384 { | 428 { |
385 throw_it (RETURN_ERROR, error, fmt, ap); | 429 throw_it (RETURN_ERROR, error, fmt, ap); |
386 } | 430 } |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 | 570 |
527 TRY_CATCH (e, mask) | 571 TRY_CATCH (e, mask) |
528 { | 572 { |
529 command (arg, from_tty); | 573 command (arg, from_tty); |
530 } | 574 } |
531 print_any_exception (gdb_stderr, NULL, e); | 575 print_any_exception (gdb_stderr, NULL, e); |
532 if (e.reason < 0) | 576 if (e.reason < 0) |
533 return 0; | 577 return 0; |
534 return 1; | 578 return 1; |
535 } | 579 } |
OLD | NEW |