gdb:
[deliverable/binutils-gdb.git] / gdb / exceptions.c
CommitLineData
60250e8b
AC
1/* Exception (throw catch) mechanism, for GDB, the GNU debugger.
2
6aba47ca 3 Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
0fb0cc75
JB
4 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
5 2009 Free Software Foundation, Inc.
60250e8b
AC
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
60250e8b
AC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
60250e8b
AC
21
22#include "defs.h"
23#include "exceptions.h"
60250e8b
AC
24#include "breakpoint.h"
25#include "target.h"
26#include "inferior.h"
27#include "annotate.h"
28#include "ui-out.h"
29#include "gdb_assert.h"
db5f402d 30#include "gdb_string.h"
e06e2353 31#include "serial.h"
347bddb7 32#include "gdbthread.h"
60250e8b 33
7b871fab 34const struct gdb_exception exception_none = { 0, GDB_NO_ERROR, NULL };
c1043fc2 35
db5f402d
AC
36/* Possible catcher states. */
37enum catcher_state {
38 /* Initial state, a new catcher has just been created. */
39 CATCHER_CREATED,
40 /* The catch code is running. */
41 CATCHER_RUNNING,
42 CATCHER_RUNNING_1,
43 /* The catch code threw an exception. */
44 CATCHER_ABORTING
45};
46
47/* Possible catcher actions. */
48enum catcher_action {
49 CATCH_ITER,
50 CATCH_ITER_1,
51 CATCH_THROWING
52};
53
54struct catcher
55{
56 enum catcher_state state;
2a78bfb5 57 /* Jump buffer pointing back at the exception handler. */
6941d02a 58 EXCEPTIONS_SIGJMP_BUF buf;
8a076db9 59 /* Status buffer belonging to the exception handler. */
71fff37b 60 volatile struct gdb_exception *exception;
db5f402d
AC
61 /* Saved/current state. */
62 int mask;
db5f402d
AC
63 struct ui_out *saved_uiout;
64 struct cleanup *saved_cleanup_chain;
db5f402d
AC
65 /* Back link. */
66 struct catcher *prev;
67};
68
60250e8b 69/* Where to go for throw_exception(). */
db5f402d
AC
70static struct catcher *current_catcher;
71
6941d02a
AC
72EXCEPTIONS_SIGJMP_BUF *
73exceptions_state_mc_init (struct ui_out *func_uiout,
71fff37b 74 volatile struct gdb_exception *exception,
6941d02a 75 return_mask mask)
db5f402d
AC
76{
77 struct catcher *new_catcher = XZALLOC (struct catcher);
78
2a78bfb5
AC
79 /* Start with no exception, save it's address. */
80 exception->reason = 0;
7b871fab 81 exception->error = GDB_NO_ERROR;
2a78bfb5
AC
82 exception->message = NULL;
83 new_catcher->exception = exception;
84
db5f402d
AC
85 new_catcher->mask = mask;
86
db5f402d
AC
87 /* Override the global ``struct ui_out'' builder. */
88 new_catcher->saved_uiout = uiout;
89 uiout = func_uiout;
90
91 /* Prevent error/quit during FUNC from calling cleanups established
92 prior to here. */
93 new_catcher->saved_cleanup_chain = save_cleanups ();
94
95 /* Push this new catcher on the top. */
96 new_catcher->prev = current_catcher;
97 current_catcher = new_catcher;
98 new_catcher->state = CATCHER_CREATED;
99
100 return &new_catcher->buf;
101}
102
103static void
104catcher_pop (void)
105{
106 struct catcher *old_catcher = current_catcher;
107 current_catcher = old_catcher->prev;
108
109 /* Restore the cleanup chain, the error/quit messages, and the uiout
110 builder, to their original states. */
111
112 restore_cleanups (old_catcher->saved_cleanup_chain);
113
114 uiout = old_catcher->saved_uiout;
115
db5f402d
AC
116 xfree (old_catcher);
117}
118
119/* Catcher state machine. Returns non-zero if the m/c should be run
120 again, zero if it should abort. */
121
6941d02a
AC
122static int
123exceptions_state_mc (enum catcher_action action)
db5f402d
AC
124{
125 switch (current_catcher->state)
126 {
127 case CATCHER_CREATED:
128 switch (action)
129 {
130 case CATCH_ITER:
131 /* Allow the code to run the catcher. */
132 current_catcher->state = CATCHER_RUNNING;
133 return 1;
134 default:
e2e0b3e5 135 internal_error (__FILE__, __LINE__, _("bad state"));
db5f402d
AC
136 }
137 case CATCHER_RUNNING:
138 switch (action)
139 {
140 case CATCH_ITER:
141 /* No error/quit has occured. Just clean up. */
142 catcher_pop ();
143 return 0;
144 case CATCH_ITER_1:
145 current_catcher->state = CATCHER_RUNNING_1;
146 return 1;
147 case CATCH_THROWING:
148 current_catcher->state = CATCHER_ABORTING;
149 /* See also throw_exception. */
150 return 1;
151 default:
e2e0b3e5 152 internal_error (__FILE__, __LINE__, _("bad switch"));
db5f402d
AC
153 }
154 case CATCHER_RUNNING_1:
155 switch (action)
156 {
157 case CATCH_ITER:
158 /* The did a "break" from the inner while loop. */
159 catcher_pop ();
160 return 0;
161 case CATCH_ITER_1:
162 current_catcher->state = CATCHER_RUNNING;
163 return 0;
164 case CATCH_THROWING:
165 current_catcher->state = CATCHER_ABORTING;
166 /* See also throw_exception. */
167 return 1;
168 default:
e2e0b3e5 169 internal_error (__FILE__, __LINE__, _("bad switch"));
db5f402d
AC
170 }
171 case CATCHER_ABORTING:
172 switch (action)
173 {
174 case CATCH_ITER:
175 {
71fff37b 176 struct gdb_exception exception = *current_catcher->exception;
2a78bfb5 177 if (current_catcher->mask & RETURN_MASK (exception.reason))
db5f402d
AC
178 {
179 /* Exit normally if this catcher can handle this
180 exception. The caller analyses the func return
181 values. */
182 catcher_pop ();
183 return 0;
184 }
185 /* The caller didn't request that the event be caught,
186 relay the event to the next containing
187 catch_errors(). */
188 catcher_pop ();
2a78bfb5 189 throw_exception (exception);
db5f402d
AC
190 }
191 default:
e2e0b3e5 192 internal_error (__FILE__, __LINE__, _("bad state"));
db5f402d
AC
193 }
194 default:
e2e0b3e5 195 internal_error (__FILE__, __LINE__, _("bad switch"));
db5f402d
AC
196 }
197}
60250e8b 198
6941d02a
AC
199int
200exceptions_state_mc_action_iter (void)
201{
202 return exceptions_state_mc (CATCH_ITER);
203}
204
205int
206exceptions_state_mc_action_iter_1 (void)
207{
208 return exceptions_state_mc (CATCH_ITER_1);
209}
210
2a78bfb5 211/* Return EXCEPTION to the nearest containing catch_errors(). */
60250e8b
AC
212
213NORETURN void
71fff37b 214throw_exception (struct gdb_exception exception)
60250e8b 215{
347bddb7
PA
216 struct thread_info *tp = NULL;
217
60250e8b
AC
218 quit_flag = 0;
219 immediate_quit = 0;
220
347bddb7 221 if (!ptid_equal (inferior_ptid, null_ptid))
e09875d4 222 tp = find_thread_ptid (inferior_ptid);
347bddb7 223
60250e8b
AC
224 /* Perhaps it would be cleaner to do this via the cleanup chain (not sure
225 I can think of a reason why that is vital, though). */
347bddb7
PA
226 if (tp != NULL)
227 bpstat_clear_actions (tp->stop_bpstat); /* Clear queued breakpoint commands */
60250e8b
AC
228
229 disable_current_display ();
230 do_cleanups (ALL_CLEANUPS);
60250e8b 231
60250e8b
AC
232 /* Jump to the containing catch_errors() call, communicating REASON
233 to that call via setjmp's return value. Note that REASON can't
234 be zero, by definition in defs.h. */
6941d02a 235 exceptions_state_mc (CATCH_THROWING);
2a78bfb5 236 *current_catcher->exception = exception;
6941d02a 237 EXCEPTIONS_SIGLONGJMP (current_catcher->buf, exception.reason);
2a78bfb5
AC
238}
239
6b1b7650
AC
240static char *last_message;
241
2a78bfb5 242NORETURN void
315a522e 243deprecated_throw_reason (enum return_reason reason)
2a78bfb5 244{
71fff37b 245 struct gdb_exception exception;
2a78bfb5
AC
246 memset (&exception, 0, sizeof exception);
247
248 exception.reason = reason;
249 switch (reason)
250 {
251 case RETURN_QUIT:
252 break;
253 case RETURN_ERROR:
254 exception.error = GENERIC_ERROR;
2a78bfb5
AC
255 break;
256 default:
e2e0b3e5 257 internal_error (__FILE__, __LINE__, _("bad switch"));
2a78bfb5
AC
258 }
259
260 throw_exception (exception);
60250e8b
AC
261}
262
6b1b7650 263static void
c6da7a6d 264print_flush (void)
6b1b7650 265{
e06e2353
AC
266 struct serial *gdb_stdout_serial;
267
c6da7a6d
AC
268 if (deprecated_error_begin_hook)
269 deprecated_error_begin_hook ();
270 target_terminal_ours ();
e06e2353
AC
271
272 /* We want all output to appear now, before we print the error. We
273 have 3 levels of buffering we have to flush (it's possible that
274 some of these should be changed to flush the lower-level ones
275 too): */
276
277 /* 1. The _filtered buffer. */
278 wrap_here ("");
279
280 /* 2. The stdio buffer. */
c6da7a6d 281 gdb_flush (gdb_stdout);
e06e2353
AC
282 gdb_flush (gdb_stderr);
283
284 /* 3. The system-level buffer. */
285 gdb_stdout_serial = serial_fdopen (1);
cade9e54
PB
286 if (gdb_stdout_serial)
287 {
288 serial_drain_output (gdb_stdout_serial);
289 serial_un_fdopen (gdb_stdout_serial);
290 }
e06e2353 291
c6da7a6d 292 annotate_error_begin ();
6b1b7650
AC
293}
294
9cbc821d 295static void
71fff37b 296print_exception (struct ui_file *file, struct gdb_exception e)
9cbc821d
AC
297{
298 /* KLUGE: cagney/2005-01-13: Write the string out one line at a time
299 as that way the MI's behavior is preserved. */
300 const char *start;
301 const char *end;
302 for (start = e.message; start != NULL; start = end)
303 {
304 end = strchr (start, '\n');
305 if (end == NULL)
306 fputs_filtered (start, file);
307 else
308 {
309 end++;
310 ui_file_write (file, start, end - start);
311 }
312 }
c6da7a6d 313 fprintf_filtered (file, "\n");
e48f5bee
AC
314
315 /* Now append the annotation. */
316 switch (e.reason)
317 {
318 case RETURN_QUIT:
319 annotate_quit ();
320 break;
321 case RETURN_ERROR:
322 /* Assume that these are all errors. */
323 annotate_error ();
324 break;
325 default:
326 internal_error (__FILE__, __LINE__, _("Bad switch."));
327 }
9cbc821d
AC
328}
329
8a076db9 330void
71fff37b 331exception_print (struct ui_file *file, struct gdb_exception e)
8a076db9
AC
332{
333 if (e.reason < 0 && e.message != NULL)
334 {
c6da7a6d 335 print_flush ();
9cbc821d 336 print_exception (file, e);
9cbc821d
AC
337 }
338}
8a076db9 339
9cbc821d 340void
71fff37b 341exception_fprintf (struct ui_file *file, struct gdb_exception e,
9cbc821d
AC
342 const char *prefix, ...)
343{
344 if (e.reason < 0 && e.message != NULL)
345 {
346 va_list args;
c6da7a6d
AC
347
348 print_flush ();
9cbc821d
AC
349
350 /* Print the prefix. */
351 va_start (args, prefix);
352 vfprintf_filtered (file, prefix, args);
353 va_end (args);
354
355 print_exception (file, e);
8a076db9
AC
356 }
357}
358
2c0b251b 359static void
e48f5bee 360print_any_exception (struct ui_file *file, const char *prefix,
71fff37b 361 struct gdb_exception e)
e48f5bee
AC
362{
363 if (e.reason < 0 && e.message != NULL)
364 {
365 target_terminal_ours ();
366 wrap_here (""); /* Force out any buffered output */
367 gdb_flush (gdb_stdout);
368 annotate_error_begin ();
369
370 /* Print the prefix. */
371 if (prefix != NULL && prefix[0] != '\0')
372 fputs_filtered (prefix, file);
373 print_exception (file, e);
374 }
375}
376
bee0189a 377NORETURN static void ATTR_NORETURN ATTR_FORMAT (printf, 3, 0)
3af1e0e3
AC
378throw_it (enum return_reason reason, enum errors error, const char *fmt,
379 va_list ap)
6b1b7650 380{
71fff37b 381 struct gdb_exception e;
17d92a02 382 char *new_message;
6b1b7650 383
17d92a02
AC
384 /* Save the message. Create the new message before deleting the
385 old, the new message may include the old message text. */
386 new_message = xstrvprintf (fmt, ap);
6b1b7650 387 xfree (last_message);
17d92a02 388 last_message = new_message;
c6da7a6d
AC
389
390 /* Create the exception. */
391 e.reason = reason;
392 e.error = error;
393 e.message = last_message;
6b1b7650 394
6b1b7650 395 /* Throw the exception. */
6b1b7650
AC
396 throw_exception (e);
397}
398
399NORETURN void
400throw_verror (enum errors error, const char *fmt, va_list ap)
401{
3af1e0e3 402 throw_it (RETURN_ERROR, error, fmt, ap);
6b1b7650
AC
403}
404
405NORETURN void
406throw_vfatal (const char *fmt, va_list ap)
407{
7b871fab 408 throw_it (RETURN_QUIT, GDB_NO_ERROR, fmt, ap);
6b1b7650
AC
409}
410
411NORETURN void
05ff989b 412throw_error (enum errors error, const char *fmt, ...)
6b1b7650 413{
05ff989b
AC
414 va_list args;
415 va_start (args, fmt);
3af1e0e3 416 throw_it (RETURN_ERROR, error, fmt, args);
05ff989b 417 va_end (args);
6b1b7650
AC
418}
419
787274f0
DE
420/* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
421 handler. If an exception (enum return_reason) is thrown using
422 throw_exception() than all cleanups installed since
423 catch_exceptions() was entered are invoked, the (-ve) exception
424 value is then returned by catch_exceptions. If FUNC() returns
425 normally (with a positive or zero return value) then that value is
426 returned by catch_exceptions(). It is an internal_error() for
427 FUNC() to return a negative value.
428
429 See exceptions.h for further usage details.
60250e8b
AC
430
431 Must not be called with immediate_quit in effect (bad things might
432 happen, say we got a signal in the middle of a memcpy to quit_return).
433 This is an OK restriction; with very few exceptions immediate_quit can
787274f0 434 be replaced by judicious use of QUIT. */
60250e8b
AC
435
436/* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
437 error() et.al. could maintain a set of flags that indicate the the
438 current state of each of the longjmp buffers. This would give the
439 longjmp code the chance to detect a longjmp botch (before it gets
440 to longjmperror()). Prior to 1999-11-05 this wasn't possible as
441 code also randomly used a SET_TOP_LEVEL macro that directly
442 initialize the longjmp buffers. */
443
60250e8b
AC
444int
445catch_exceptions (struct ui_out *uiout,
446 catch_exceptions_ftype *func,
447 void *func_args,
60250e8b
AC
448 return_mask mask)
449{
1c3c7ee7 450 return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
60250e8b
AC
451}
452
71fff37b 453struct gdb_exception
2a78bfb5
AC
454catch_exception (struct ui_out *uiout,
455 catch_exception_ftype *func,
456 void *func_args,
457 return_mask mask)
458{
71fff37b 459 volatile struct gdb_exception exception;
6941d02a
AC
460 TRY_CATCH (exception, mask)
461 {
462 (*func) (uiout, func_args);
463 }
2a78bfb5
AC
464 return exception;
465}
466
60250e8b
AC
467int
468catch_exceptions_with_msg (struct ui_out *uiout,
469 catch_exceptions_ftype *func,
470 void *func_args,
60250e8b
AC
471 char **gdberrmsg,
472 return_mask mask)
473{
71fff37b 474 volatile struct gdb_exception exception;
2a78bfb5 475 volatile int val = 0;
6941d02a
AC
476 TRY_CATCH (exception, mask)
477 {
478 val = (*func) (uiout, func_args);
479 }
e48f5bee 480 print_any_exception (gdb_stderr, NULL, exception);
60250e8b 481 gdb_assert (val >= 0);
2a78bfb5
AC
482 gdb_assert (exception.reason <= 0);
483 if (exception.reason < 0)
484 {
485 /* If caller wants a copy of the low-level error message, make
486 one. This is used in the case of a silent error whereby the
487 caller may optionally want to issue the message. */
488 if (gdberrmsg != NULL)
6b1b7650
AC
489 {
490 if (exception.message != NULL)
491 *gdberrmsg = xstrdup (exception.message);
492 else
493 *gdberrmsg = NULL;
494 }
2a78bfb5
AC
495 return exception.reason;
496 }
60250e8b
AC
497 return val;
498}
499
787274f0
DE
500/* This function is superseded by catch_exceptions(). */
501
60250e8b
AC
502int
503catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
504 return_mask mask)
505{
2a78bfb5 506 volatile int val = 0;
71fff37b 507 volatile struct gdb_exception exception;
6941d02a
AC
508 TRY_CATCH (exception, mask)
509 {
510 val = func (func_args);
511 }
e48f5bee 512 print_any_exception (gdb_stderr, errstring, exception);
2a78bfb5 513 if (exception.reason != 0)
60250e8b
AC
514 return 0;
515 return val;
516}
517
60250e8b
AC
518int
519catch_command_errors (catch_command_errors_ftype * command,
520 char *arg, int from_tty, return_mask mask)
521{
71fff37b 522 volatile struct gdb_exception e;
6941d02a
AC
523 TRY_CATCH (e, mask)
524 {
525 command (arg, from_tty);
526 }
5a14cc1a
AC
527 print_any_exception (gdb_stderr, NULL, e);
528 if (e.reason < 0)
529 return 0;
530 return 1;
60250e8b 531}
This page took 0.366288 seconds and 4 git commands to generate.