1 /* Exception (throw catch) mechanism, for GDB, the GNU debugger.
3 Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
4 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
5 Software Foundation, Inc.
7 This file is part of GDB.
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
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
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.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
25 #include "exceptions.h"
27 #include "breakpoint.h"
32 #include "gdb_assert.h"
33 #include "gdb_string.h"
35 const struct exception exception_none
= { 0, NO_ERROR
, NULL
};
37 /* One should use catch_errors rather than manipulating these
39 #if defined(HAVE_SIGSETJMP)
40 #define SIGJMP_BUF sigjmp_buf
41 #define SIGSETJMP(buf) sigsetjmp((buf), 1)
42 #define SIGLONGJMP(buf,val) siglongjmp((buf), (val))
44 #define SIGJMP_BUF jmp_buf
45 #define SIGSETJMP(buf) setjmp(buf)
46 #define SIGLONGJMP(buf,val) longjmp((buf), (val))
49 /* Possible catcher states. */
51 /* Initial state, a new catcher has just been created. */
53 /* The catch code is running. */
56 /* The catch code threw an exception. */
60 /* Possible catcher actions. */
69 enum catcher_state state
;
70 /* Jump buffer pointing back at the exception handler. */
72 /* Status buffer belonging to the exception handler. */
73 volatile struct exception
*exception
;
74 /* Should the error / quit message be printed? Old code assumes
75 that this file prints the error/quit message when first reported.
76 New code instead directly handles the printing of error/quit
79 /* Saved/current state. */
81 char *saved_error_pre_print
;
82 char *saved_quit_pre_print
;
83 struct ui_out
*saved_uiout
;
84 struct cleanup
*saved_cleanup_chain
;
89 /* Where to go for throw_exception(). */
90 static struct catcher
*current_catcher
;
93 catcher_init (struct ui_out
*func_uiout
,
95 volatile struct exception
*exception
,
99 struct catcher
*new_catcher
= XZALLOC (struct catcher
);
101 /* Start with no exception, save it's address. */
102 exception
->reason
= 0;
103 exception
->error
= NO_ERROR
;
104 exception
->message
= NULL
;
105 new_catcher
->exception
= exception
;
107 new_catcher
->mask
= mask
;
108 new_catcher
->print_message
= print_message
;
110 /* Override error/quit messages during FUNC. */
111 new_catcher
->saved_error_pre_print
= error_pre_print
;
112 new_catcher
->saved_quit_pre_print
= quit_pre_print
;
113 if (mask
& RETURN_MASK_ERROR
)
114 error_pre_print
= errstring
;
115 if (mask
& RETURN_MASK_QUIT
)
116 quit_pre_print
= errstring
;
118 /* Override the global ``struct ui_out'' builder. */
119 new_catcher
->saved_uiout
= uiout
;
122 /* Prevent error/quit during FUNC from calling cleanups established
124 new_catcher
->saved_cleanup_chain
= save_cleanups ();
126 /* Push this new catcher on the top. */
127 new_catcher
->prev
= current_catcher
;
128 current_catcher
= new_catcher
;
129 new_catcher
->state
= CATCHER_CREATED
;
131 return &new_catcher
->buf
;
137 struct catcher
*old_catcher
= current_catcher
;
138 current_catcher
= old_catcher
->prev
;
140 /* Restore the cleanup chain, the error/quit messages, and the uiout
141 builder, to their original states. */
143 restore_cleanups (old_catcher
->saved_cleanup_chain
);
145 uiout
= old_catcher
->saved_uiout
;
147 quit_pre_print
= old_catcher
->saved_quit_pre_print
;
148 error_pre_print
= old_catcher
->saved_error_pre_print
;
153 /* Catcher state machine. Returns non-zero if the m/c should be run
154 again, zero if it should abort. */
157 catcher_state_machine (enum catcher_action action
)
159 switch (current_catcher
->state
)
161 case CATCHER_CREATED
:
165 /* Allow the code to run the catcher. */
166 current_catcher
->state
= CATCHER_RUNNING
;
169 internal_error (__FILE__
, __LINE__
, "bad state");
171 case CATCHER_RUNNING
:
175 /* No error/quit has occured. Just clean up. */
179 current_catcher
->state
= CATCHER_RUNNING_1
;
182 current_catcher
->state
= CATCHER_ABORTING
;
183 /* See also throw_exception. */
186 internal_error (__FILE__
, __LINE__
, "bad switch");
188 case CATCHER_RUNNING_1
:
192 /* The did a "break" from the inner while loop. */
196 current_catcher
->state
= CATCHER_RUNNING
;
199 current_catcher
->state
= CATCHER_ABORTING
;
200 /* See also throw_exception. */
203 internal_error (__FILE__
, __LINE__
, "bad switch");
205 case CATCHER_ABORTING
:
210 struct exception exception
= *current_catcher
->exception
;
211 if (current_catcher
->mask
& RETURN_MASK (exception
.reason
))
213 /* Exit normally if this catcher can handle this
214 exception. The caller analyses the func return
219 /* The caller didn't request that the event be caught,
220 relay the event to the next containing
223 throw_exception (exception
);
226 internal_error (__FILE__
, __LINE__
, "bad state");
229 internal_error (__FILE__
, __LINE__
, "bad switch");
233 /* Return EXCEPTION to the nearest containing catch_errors(). */
236 throw_exception (struct exception exception
)
241 /* Perhaps it would be cleaner to do this via the cleanup chain (not sure
242 I can think of a reason why that is vital, though). */
243 bpstat_clear_actions (stop_bpstat
); /* Clear queued breakpoint commands */
245 disable_current_display ();
246 do_cleanups (ALL_CLEANUPS
);
247 if (target_can_async_p () && !target_executing
)
248 do_exec_cleanups (ALL_CLEANUPS
);
250 do_exec_error_cleanups (ALL_CLEANUPS
);
252 if (annotation_level
> 1)
253 switch (exception
.reason
)
259 /* Assume that these are all errors. */
263 internal_error (__FILE__
, __LINE__
, "Bad switch.");
266 /* Jump to the containing catch_errors() call, communicating REASON
267 to that call via setjmp's return value. Note that REASON can't
268 be zero, by definition in defs.h. */
269 catcher_state_machine (CATCH_THROWING
);
270 *current_catcher
->exception
= exception
;
271 SIGLONGJMP (current_catcher
->buf
, exception
.reason
);
274 static char *last_message
;
277 throw_reason (enum return_reason reason
)
279 struct exception exception
;
280 memset (&exception
, 0, sizeof exception
);
282 exception
.reason
= reason
;
288 exception
.error
= GENERIC_ERROR
;
289 exception
.message
= last_message
;
292 internal_error (__FILE__
, __LINE__
, "bad switch");
295 throw_exception (exception
);
299 do_write (void *data
, const char *buffer
, long length_buffer
)
301 ui_file_write (data
, buffer
, length_buffer
);
306 print_exception (struct ui_file
*file
, struct exception e
)
308 /* KLUGE: cagney/2005-01-13: Write the string out one line at a time
309 as that way the MI's behavior is preserved. */
312 for (start
= e
.message
; start
!= NULL
; start
= end
)
314 end
= strchr (start
, '\n');
316 fputs_filtered (start
, file
);
320 ui_file_write (file
, start
, end
- start
);
326 exception_print (struct ui_file
*file
, struct exception e
)
328 if (e
.reason
< 0 && e
.message
!= NULL
)
330 target_terminal_ours ();
331 wrap_here (""); /* Force out any buffered output */
333 annotate_error_begin ();
334 print_exception (file
, e
);
335 fprintf_filtered (file
, "\n");
340 exception_fprintf (struct ui_file
*file
, struct exception e
,
341 const char *prefix
, ...)
343 if (e
.reason
< 0 && e
.message
!= NULL
)
346 target_terminal_ours ();
347 wrap_here (""); /* Force out any buffered output */
349 annotate_error_begin ();
351 /* Print the prefix. */
352 va_start (args
, prefix
);
353 vfprintf_filtered (file
, prefix
, args
);
356 print_exception (file
, e
);
357 fprintf_filtered (file
, "\n");
362 print_and_throw (enum return_reason reason
, enum errors error
,
363 const char *prefix
, const char *fmt
,
364 va_list ap
) ATTR_NORETURN
;
366 print_and_throw (enum return_reason reason
, enum errors error
,
367 const char *prefix
, const char *fmt
, va_list ap
)
369 /* FIXME: cagney/2005-01-13: While xstrvprintf is simpler it alters
370 GDB's output. Instead of the message being printed
371 line-at-a-time the message comes out all at once. The problem is
372 that the MI testsuite is checks for line-at-a-time messages and
373 changing this behavior means updating the testsuite. */
376 struct ui_file
*tmp_stream
;
379 /* Convert the message into a print stream. */
380 tmp_stream
= mem_fileopen ();
381 make_cleanup_ui_file_delete (tmp_stream
);
382 vfprintf_unfiltered (tmp_stream
, fmt
, ap
);
384 /* Save the message. */
385 xfree (last_message
);
386 last_message
= ui_file_xstrdup (tmp_stream
, &len
);
388 /* Print the mesage to stderr, but only if the catcher isn't going
389 to handle/print it locally. */
390 if (current_catcher
->print_message
)
392 if (deprecated_error_begin_hook
)
393 deprecated_error_begin_hook ();
395 /* Write the message plus any pre_print to gdb_stderr. */
396 target_terminal_ours ();
397 wrap_here (""); /* Force out any buffered output */
398 gdb_flush (gdb_stdout
);
399 annotate_error_begin ();
401 fputs_filtered (error_pre_print
, gdb_stderr
);
402 ui_file_put (tmp_stream
, do_write
, gdb_stderr
);
403 fprintf_filtered (gdb_stderr
, "\n");
406 /* Throw the exception. */
409 e
.message
= last_message
;
414 throw_verror (enum errors error
, const char *fmt
, va_list ap
)
416 print_and_throw (RETURN_ERROR
, error
, error_pre_print
, fmt
, ap
);
420 throw_vfatal (const char *fmt
, va_list ap
)
422 print_and_throw (RETURN_QUIT
, NO_ERROR
, quit_pre_print
, fmt
, ap
);
426 throw_error (enum errors error
, const char *fmt
, ...)
429 va_start (args
, fmt
);
430 print_and_throw (RETURN_ERROR
, error
, error_pre_print
, fmt
, args
);
434 /* Call FUNC() with args FUNC_UIOUT and FUNC_ARGS, catching any
435 errors. Set FUNC_CAUGHT to an ``enum return_reason'' if the
436 function is aborted (using throw_exception() or zero if the
437 function returns normally. Set FUNC_VAL to the value returned by
438 the function or 0 if the function was aborted.
440 Must not be called with immediate_quit in effect (bad things might
441 happen, say we got a signal in the middle of a memcpy to quit_return).
442 This is an OK restriction; with very few exceptions immediate_quit can
443 be replaced by judicious use of QUIT.
445 MASK specifies what to catch; it is normally set to
446 RETURN_MASK_ALL, if for no other reason than that the code which
447 calls catch_errors might not be set up to deal with a quit which
448 isn't caught. But if the code can deal with it, it generally
449 should be RETURN_MASK_ERROR, unless for some reason it is more
450 useful to abort only the portion of the operation inside the
451 catch_errors. Note that quit should return to the command line
452 fairly quickly, even if some further processing is being done. */
454 /* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
455 error() et.al. could maintain a set of flags that indicate the the
456 current state of each of the longjmp buffers. This would give the
457 longjmp code the chance to detect a longjmp botch (before it gets
458 to longjmperror()). Prior to 1999-11-05 this wasn't possible as
459 code also randomly used a SET_TOP_LEVEL macro that directly
460 initialize the longjmp buffers. */
462 /* MAYBE: cagney/1999-11-05: Should the catch_errors and cleanups code
463 be consolidated into a single file instead of being distributed
464 between utils.c and top.c? */
467 catch_exceptions (struct ui_out
*uiout
,
468 catch_exceptions_ftype
*func
,
473 return catch_exceptions_with_msg (uiout
, func
, func_args
, errstring
,
478 catch_exception (struct ui_out
*uiout
,
479 catch_exception_ftype
*func
,
483 volatile struct exception exception
;
485 catch = catcher_init (uiout
, NULL
, &exception
, mask
, 0);
486 for (SIGSETJMP ((*catch));
487 catcher_state_machine (CATCH_ITER
);)
488 (*func
) (uiout
, func_args
);
493 catch_exceptions_with_msg (struct ui_out
*uiout
,
494 catch_exceptions_ftype
*func
,
500 volatile struct exception exception
;
501 volatile int val
= 0;
502 SIGJMP_BUF
*catch = catcher_init (uiout
, errstring
, &exception
, mask
, 1);
503 for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER
);)
504 val
= (*func
) (uiout
, func_args
);
505 gdb_assert (val
>= 0);
506 gdb_assert (exception
.reason
<= 0);
507 if (exception
.reason
< 0)
509 /* If caller wants a copy of the low-level error message, make
510 one. This is used in the case of a silent error whereby the
511 caller may optionally want to issue the message. */
512 if (gdberrmsg
!= NULL
)
514 if (exception
.message
!= NULL
)
515 *gdberrmsg
= xstrdup (exception
.message
);
519 return exception
.reason
;
525 catch_errors (catch_errors_ftype
*func
, void *func_args
, char *errstring
,
528 volatile int val
= 0;
529 volatile struct exception exception
;
530 SIGJMP_BUF
*catch = catcher_init (uiout
, errstring
, &exception
, mask
, 1);
531 /* This illustrates how it is possible to nest the mechanism and
532 hence catch "break". Of course this doesn't address the need to
533 also catch "return". */
534 for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER
);)
535 val
= func (func_args
);
536 if (exception
.reason
!= 0)
541 struct captured_command_args
543 catch_command_errors_ftype
*command
;
549 do_captured_command (void *data
)
551 struct captured_command_args
*context
= data
;
552 context
->command (context
->arg
, context
->from_tty
);
553 /* FIXME: cagney/1999-11-07: Technically this do_cleanups() call
554 isn't needed. Instead an assertion check could be made that
555 simply confirmed that the called function correctly cleaned up
556 after itself. Unfortunately, old code (prior to 1999-11-04) in
557 main.c was calling SET_TOP_LEVEL(), calling the command function,
558 and then *always* calling do_cleanups(). For the moment we
559 remain ``bug compatible'' with that old code.. */
560 do_cleanups (ALL_CLEANUPS
);
565 catch_command_errors (catch_command_errors_ftype
* command
,
566 char *arg
, int from_tty
, return_mask mask
)
568 struct captured_command_args args
;
569 args
.command
= command
;
571 args
.from_tty
= from_tty
;
572 return catch_errors (do_captured_command
, &args
, "", mask
);