| 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 |