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 Free Software
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 that exception handler. */
73 volatile struct exception *exception;
74 /* Saved/current state. */
76 char *saved_error_pre_print;
77 char *saved_quit_pre_print;
78 struct ui_out *saved_uiout;
79 struct cleanup *saved_cleanup_chain;
84 /* Where to go for throw_exception(). */
85 static struct catcher *current_catcher;
88 catcher_init (struct ui_out *func_uiout,
90 volatile struct exception *exception,
93 struct catcher *new_catcher = XZALLOC (struct catcher);
95 /* Start with no exception, save it's address. */
96 exception->reason = 0;
97 exception->error = NO_ERROR;
98 exception->message = NULL;
99 new_catcher->exception = exception;
101 new_catcher->mask = mask;
103 /* Override error/quit messages during FUNC. */
104 new_catcher->saved_error_pre_print = error_pre_print;
105 new_catcher->saved_quit_pre_print = quit_pre_print;
106 if (mask & RETURN_MASK_ERROR)
107 error_pre_print = errstring;
108 if (mask & RETURN_MASK_QUIT)
109 quit_pre_print = errstring;
111 /* Override the global ``struct ui_out'' builder. */
112 new_catcher->saved_uiout = uiout;
115 /* Prevent error/quit during FUNC from calling cleanups established
117 new_catcher->saved_cleanup_chain = save_cleanups ();
119 /* Push this new catcher on the top. */
120 new_catcher->prev = current_catcher;
121 current_catcher = new_catcher;
122 new_catcher->state = CATCHER_CREATED;
124 return &new_catcher->buf;
130 struct catcher *old_catcher = current_catcher;
131 current_catcher = old_catcher->prev;
133 /* Restore the cleanup chain, the error/quit messages, and the uiout
134 builder, to their original states. */
136 restore_cleanups (old_catcher->saved_cleanup_chain);
138 uiout = old_catcher->saved_uiout;
140 quit_pre_print = old_catcher->saved_quit_pre_print;
141 error_pre_print = old_catcher->saved_error_pre_print;
146 /* Catcher state machine. Returns non-zero if the m/c should be run
147 again, zero if it should abort. */
150 catcher_state_machine (enum catcher_action action)
152 switch (current_catcher->state)
154 case CATCHER_CREATED:
158 /* Allow the code to run the catcher. */
159 current_catcher->state = CATCHER_RUNNING;
162 internal_error (__FILE__, __LINE__, "bad state");
164 case CATCHER_RUNNING:
168 /* No error/quit has occured. Just clean up. */
172 current_catcher->state = CATCHER_RUNNING_1;
175 current_catcher->state = CATCHER_ABORTING;
176 /* See also throw_exception. */
179 internal_error (__FILE__, __LINE__, "bad switch");
181 case CATCHER_RUNNING_1:
185 /* The did a "break" from the inner while loop. */
189 current_catcher->state = CATCHER_RUNNING;
192 current_catcher->state = CATCHER_ABORTING;
193 /* See also throw_exception. */
196 internal_error (__FILE__, __LINE__, "bad switch");
198 case CATCHER_ABORTING:
203 struct exception exception = *current_catcher->exception;
204 if (current_catcher->mask & RETURN_MASK (exception.reason))
206 /* Exit normally if this catcher can handle this
207 exception. The caller analyses the func return
212 /* The caller didn't request that the event be caught,
213 relay the event to the next containing
216 throw_exception (exception);
219 internal_error (__FILE__, __LINE__, "bad state");
222 internal_error (__FILE__, __LINE__, "bad switch");
226 /* Return EXCEPTION to the nearest containing catch_errors(). */
229 throw_exception (struct exception exception)
234 /* Perhaps it would be cleaner to do this via the cleanup chain (not sure
235 I can think of a reason why that is vital, though). */
236 bpstat_clear_actions (stop_bpstat); /* Clear queued breakpoint commands */
238 disable_current_display ();
239 do_cleanups (ALL_CLEANUPS);
240 if (target_can_async_p () && !target_executing)
241 do_exec_cleanups (ALL_CLEANUPS);
243 do_exec_error_cleanups (ALL_CLEANUPS);
245 if (annotation_level > 1)
246 switch (exception.reason)
252 /* Assume that these are all errors. */
256 internal_error (__FILE__, __LINE__, "Bad switch.");
259 /* Jump to the containing catch_errors() call, communicating REASON
260 to that call via setjmp's return value. Note that REASON can't
261 be zero, by definition in defs.h. */
262 catcher_state_machine (CATCH_THROWING);
263 *current_catcher->exception = exception;
264 SIGLONGJMP (current_catcher->buf, exception.reason);
268 throw_reason (enum return_reason reason)
270 struct exception exception;
271 memset (&exception, 0, sizeof exception);
273 exception.reason = reason;
279 exception.error = GENERIC_ERROR;
280 exception.message = error_last_message ();
283 internal_error (__FILE__, __LINE__, "bad switch");
286 throw_exception (exception);
289 /* Call FUNC() with args FUNC_UIOUT and FUNC_ARGS, catching any
290 errors. Set FUNC_CAUGHT to an ``enum return_reason'' if the
291 function is aborted (using throw_exception() or zero if the
292 function returns normally. Set FUNC_VAL to the value returned by
293 the function or 0 if the function was aborted.
295 Must not be called with immediate_quit in effect (bad things might
296 happen, say we got a signal in the middle of a memcpy to quit_return).
297 This is an OK restriction; with very few exceptions immediate_quit can
298 be replaced by judicious use of QUIT.
300 MASK specifies what to catch; it is normally set to
301 RETURN_MASK_ALL, if for no other reason than that the code which
302 calls catch_errors might not be set up to deal with a quit which
303 isn't caught. But if the code can deal with it, it generally
304 should be RETURN_MASK_ERROR, unless for some reason it is more
305 useful to abort only the portion of the operation inside the
306 catch_errors. Note that quit should return to the command line
307 fairly quickly, even if some further processing is being done. */
309 /* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
310 error() et.al. could maintain a set of flags that indicate the the
311 current state of each of the longjmp buffers. This would give the
312 longjmp code the chance to detect a longjmp botch (before it gets
313 to longjmperror()). Prior to 1999-11-05 this wasn't possible as
314 code also randomly used a SET_TOP_LEVEL macro that directly
315 initialize the longjmp buffers. */
317 /* MAYBE: cagney/1999-11-05: Should the catch_errors and cleanups code
318 be consolidated into a single file instead of being distributed
319 between utils.c and top.c? */
322 catch_exceptions (struct ui_out *uiout,
323 catch_exceptions_ftype *func,
328 return catch_exceptions_with_msg (uiout, func, func_args, errstring,
333 catch_exception (struct ui_out *uiout,
334 catch_exception_ftype *func,
338 volatile struct exception exception;
340 catch = catcher_init (uiout, NULL, &exception, mask);
341 for (SIGSETJMP ((*catch));
342 catcher_state_machine (CATCH_ITER);)
343 (*func) (uiout, func_args);
348 catch_exceptions_with_msg (struct ui_out *uiout,
349 catch_exceptions_ftype *func,
355 volatile struct exception exception;
356 volatile int val = 0;
357 SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask);
358 for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
359 val = (*func) (uiout, func_args);
360 gdb_assert (val >= 0);
361 gdb_assert (exception.reason <= 0);
362 if (exception.reason < 0)
364 /* If caller wants a copy of the low-level error message, make
365 one. This is used in the case of a silent error whereby the
366 caller may optionally want to issue the message. */
367 if (gdberrmsg != NULL)
368 *gdberrmsg = exception.message;
369 return exception.reason;
375 catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
378 volatile int val = 0;
379 volatile struct exception exception;
380 SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask);
381 /* This illustrates how it is possible to nest the mechanism and
382 hence catch "break". Of course this doesn't address the need to
383 also catch "return". */
384 for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
385 val = func (func_args);
386 if (exception.reason != 0)
391 struct captured_command_args
393 catch_command_errors_ftype *command;
399 do_captured_command (void *data)
401 struct captured_command_args *context = data;
402 context->command (context->arg, context->from_tty);
403 /* FIXME: cagney/1999-11-07: Technically this do_cleanups() call
404 isn't needed. Instead an assertion check could be made that
405 simply confirmed that the called function correctly cleaned up
406 after itself. Unfortunately, old code (prior to 1999-11-04) in
407 main.c was calling SET_TOP_LEVEL(), calling the command function,
408 and then *always* calling do_cleanups(). For the moment we
409 remain ``bug compatible'' with that old code.. */
410 do_cleanups (ALL_CLEANUPS);
415 catch_command_errors (catch_command_errors_ftype * command,
416 char *arg, int from_tty, return_mask mask)
418 struct captured_command_args args;
419 args.command = command;
421 args.from_tty = from_tty;
422 return catch_errors (do_captured_command, &args, "", mask);