2005-01-12 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gdb / exceptions.c
CommitLineData
60250e8b
AC
1/* Exception (throw catch) mechanism, for GDB, the GNU debugger.
2
3 Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
4 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
5 Foundation, Inc.
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
11 the Free Software Foundation; either version 2 of the License, or
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
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. */
23
24#include "defs.h"
25#include "exceptions.h"
26#include <setjmp.h>
27#include "breakpoint.h"
28#include "target.h"
29#include "inferior.h"
30#include "annotate.h"
31#include "ui-out.h"
32#include "gdb_assert.h"
db5f402d 33#include "gdb_string.h"
60250e8b
AC
34
35/* One should use catch_errors rather than manipulating these
36 directly. */
37#if defined(HAVE_SIGSETJMP)
38#define SIGJMP_BUF sigjmp_buf
39#define SIGSETJMP(buf) sigsetjmp((buf), 1)
40#define SIGLONGJMP(buf,val) siglongjmp((buf), (val))
41#else
42#define SIGJMP_BUF jmp_buf
43#define SIGSETJMP(buf) setjmp(buf)
44#define SIGLONGJMP(buf,val) longjmp((buf), (val))
45#endif
46
db5f402d
AC
47/* Possible catcher states. */
48enum catcher_state {
49 /* Initial state, a new catcher has just been created. */
50 CATCHER_CREATED,
51 /* The catch code is running. */
52 CATCHER_RUNNING,
53 CATCHER_RUNNING_1,
54 /* The catch code threw an exception. */
55 CATCHER_ABORTING
56};
57
58/* Possible catcher actions. */
59enum catcher_action {
60 CATCH_ITER,
61 CATCH_ITER_1,
62 CATCH_THROWING
63};
64
65struct catcher
66{
67 enum catcher_state state;
2a78bfb5 68 /* Jump buffer pointing back at the exception handler. */
db5f402d 69 SIGJMP_BUF buf;
2a78bfb5
AC
70 /* Status buffer belonging to that exception handler. */
71 volatile struct exception *exception;
db5f402d
AC
72 /* Saved/current state. */
73 int mask;
74 char *saved_error_pre_print;
75 char *saved_quit_pre_print;
76 struct ui_out *saved_uiout;
77 struct cleanup *saved_cleanup_chain;
db5f402d
AC
78 /* Back link. */
79 struct catcher *prev;
80};
81
60250e8b 82/* Where to go for throw_exception(). */
db5f402d
AC
83static struct catcher *current_catcher;
84
85static SIGJMP_BUF *
86catcher_init (struct ui_out *func_uiout,
87 char *errstring,
2a78bfb5 88 volatile struct exception *exception,
db5f402d
AC
89 return_mask mask)
90{
91 struct catcher *new_catcher = XZALLOC (struct catcher);
92
2a78bfb5
AC
93 /* Start with no exception, save it's address. */
94 exception->reason = 0;
95 exception->error = NO_ERROR;
96 exception->message = NULL;
97 new_catcher->exception = exception;
98
db5f402d
AC
99 new_catcher->mask = mask;
100
101 /* Override error/quit messages during FUNC. */
102 new_catcher->saved_error_pre_print = error_pre_print;
103 new_catcher->saved_quit_pre_print = quit_pre_print;
104 if (mask & RETURN_MASK_ERROR)
105 error_pre_print = errstring;
106 if (mask & RETURN_MASK_QUIT)
107 quit_pre_print = errstring;
108
109 /* Override the global ``struct ui_out'' builder. */
110 new_catcher->saved_uiout = uiout;
111 uiout = func_uiout;
112
113 /* Prevent error/quit during FUNC from calling cleanups established
114 prior to here. */
115 new_catcher->saved_cleanup_chain = save_cleanups ();
116
117 /* Push this new catcher on the top. */
118 new_catcher->prev = current_catcher;
119 current_catcher = new_catcher;
120 new_catcher->state = CATCHER_CREATED;
121
122 return &new_catcher->buf;
123}
124
125static void
126catcher_pop (void)
127{
128 struct catcher *old_catcher = current_catcher;
129 current_catcher = old_catcher->prev;
130
131 /* Restore the cleanup chain, the error/quit messages, and the uiout
132 builder, to their original states. */
133
134 restore_cleanups (old_catcher->saved_cleanup_chain);
135
136 uiout = old_catcher->saved_uiout;
137
138 quit_pre_print = old_catcher->saved_quit_pre_print;
139 error_pre_print = old_catcher->saved_error_pre_print;
140
141 xfree (old_catcher);
142}
143
144/* Catcher state machine. Returns non-zero if the m/c should be run
145 again, zero if it should abort. */
146
147int
148catcher_state_machine (enum catcher_action action)
149{
150 switch (current_catcher->state)
151 {
152 case CATCHER_CREATED:
153 switch (action)
154 {
155 case CATCH_ITER:
156 /* Allow the code to run the catcher. */
157 current_catcher->state = CATCHER_RUNNING;
158 return 1;
159 default:
160 internal_error (__FILE__, __LINE__, "bad state");
161 }
162 case CATCHER_RUNNING:
163 switch (action)
164 {
165 case CATCH_ITER:
166 /* No error/quit has occured. Just clean up. */
167 catcher_pop ();
168 return 0;
169 case CATCH_ITER_1:
170 current_catcher->state = CATCHER_RUNNING_1;
171 return 1;
172 case CATCH_THROWING:
173 current_catcher->state = CATCHER_ABORTING;
174 /* See also throw_exception. */
175 return 1;
176 default:
177 internal_error (__FILE__, __LINE__, "bad switch");
178 }
179 case CATCHER_RUNNING_1:
180 switch (action)
181 {
182 case CATCH_ITER:
183 /* The did a "break" from the inner while loop. */
184 catcher_pop ();
185 return 0;
186 case CATCH_ITER_1:
187 current_catcher->state = CATCHER_RUNNING;
188 return 0;
189 case CATCH_THROWING:
190 current_catcher->state = CATCHER_ABORTING;
191 /* See also throw_exception. */
192 return 1;
193 default:
194 internal_error (__FILE__, __LINE__, "bad switch");
195 }
196 case CATCHER_ABORTING:
197 switch (action)
198 {
199 case CATCH_ITER:
200 {
2a78bfb5
AC
201 struct exception exception = *current_catcher->exception;
202 if (current_catcher->mask & RETURN_MASK (exception.reason))
db5f402d
AC
203 {
204 /* Exit normally if this catcher can handle this
205 exception. The caller analyses the func return
206 values. */
207 catcher_pop ();
208 return 0;
209 }
210 /* The caller didn't request that the event be caught,
211 relay the event to the next containing
212 catch_errors(). */
213 catcher_pop ();
2a78bfb5 214 throw_exception (exception);
db5f402d
AC
215 }
216 default:
217 internal_error (__FILE__, __LINE__, "bad state");
218 }
219 default:
220 internal_error (__FILE__, __LINE__, "bad switch");
221 }
222}
60250e8b 223
2a78bfb5 224/* Return EXCEPTION to the nearest containing catch_errors(). */
60250e8b
AC
225
226NORETURN void
2a78bfb5 227throw_exception (struct exception exception)
60250e8b
AC
228{
229 quit_flag = 0;
230 immediate_quit = 0;
231
232 /* Perhaps it would be cleaner to do this via the cleanup chain (not sure
233 I can think of a reason why that is vital, though). */
234 bpstat_clear_actions (stop_bpstat); /* Clear queued breakpoint commands */
235
236 disable_current_display ();
237 do_cleanups (ALL_CLEANUPS);
238 if (target_can_async_p () && !target_executing)
239 do_exec_cleanups (ALL_CLEANUPS);
240 if (sync_execution)
241 do_exec_error_cleanups (ALL_CLEANUPS);
242
243 if (annotation_level > 1)
2a78bfb5 244 switch (exception.reason)
60250e8b
AC
245 {
246 case RETURN_QUIT:
247 annotate_quit ();
248 break;
249 case RETURN_ERROR:
2a78bfb5 250 /* Assume that these are all errors. */
60250e8b
AC
251 annotate_error ();
252 break;
2a78bfb5
AC
253 default:
254 internal_error (__FILE__, __LINE__, "Bad switch.");
60250e8b
AC
255 }
256
257 /* Jump to the containing catch_errors() call, communicating REASON
258 to that call via setjmp's return value. Note that REASON can't
259 be zero, by definition in defs.h. */
db5f402d 260 catcher_state_machine (CATCH_THROWING);
2a78bfb5
AC
261 *current_catcher->exception = exception;
262 SIGLONGJMP (current_catcher->buf, exception.reason);
263}
264
265NORETURN void
266throw_reason (enum return_reason reason)
267{
268 struct exception exception;
269 memset (&exception, 0, sizeof exception);
270
271 exception.reason = reason;
272 switch (reason)
273 {
274 case RETURN_QUIT:
275 break;
276 case RETURN_ERROR:
277 exception.error = GENERIC_ERROR;
278 exception.message = error_last_message ();
279 break;
280 default:
281 internal_error (__FILE__, __LINE__, "bad switch");
282 }
283
284 throw_exception (exception);
60250e8b
AC
285}
286
287/* Call FUNC() with args FUNC_UIOUT and FUNC_ARGS, catching any
288 errors. Set FUNC_CAUGHT to an ``enum return_reason'' if the
289 function is aborted (using throw_exception() or zero if the
290 function returns normally. Set FUNC_VAL to the value returned by
291 the function or 0 if the function was aborted.
292
293 Must not be called with immediate_quit in effect (bad things might
294 happen, say we got a signal in the middle of a memcpy to quit_return).
295 This is an OK restriction; with very few exceptions immediate_quit can
296 be replaced by judicious use of QUIT.
297
298 MASK specifies what to catch; it is normally set to
299 RETURN_MASK_ALL, if for no other reason than that the code which
300 calls catch_errors might not be set up to deal with a quit which
301 isn't caught. But if the code can deal with it, it generally
302 should be RETURN_MASK_ERROR, unless for some reason it is more
303 useful to abort only the portion of the operation inside the
304 catch_errors. Note that quit should return to the command line
305 fairly quickly, even if some further processing is being done. */
306
307/* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
308 error() et.al. could maintain a set of flags that indicate the the
309 current state of each of the longjmp buffers. This would give the
310 longjmp code the chance to detect a longjmp botch (before it gets
311 to longjmperror()). Prior to 1999-11-05 this wasn't possible as
312 code also randomly used a SET_TOP_LEVEL macro that directly
313 initialize the longjmp buffers. */
314
315/* MAYBE: cagney/1999-11-05: Should the catch_errors and cleanups code
316 be consolidated into a single file instead of being distributed
317 between utils.c and top.c? */
318
60250e8b
AC
319int
320catch_exceptions (struct ui_out *uiout,
321 catch_exceptions_ftype *func,
322 void *func_args,
323 char *errstring,
324 return_mask mask)
325{
db5f402d
AC
326 return catch_exceptions_with_msg (uiout, func, func_args, errstring,
327 NULL, mask);
60250e8b
AC
328}
329
2a78bfb5
AC
330struct exception
331catch_exception (struct ui_out *uiout,
332 catch_exception_ftype *func,
333 void *func_args,
334 return_mask mask)
335{
336 volatile struct exception exception;
337 SIGJMP_BUF *catch;
338 catch = catcher_init (uiout, NULL, &exception, mask);
339 for (SIGSETJMP ((*catch));
340 catcher_state_machine (CATCH_ITER);)
341 (*func) (uiout, func_args);
342 return exception;
343}
344
60250e8b
AC
345int
346catch_exceptions_with_msg (struct ui_out *uiout,
347 catch_exceptions_ftype *func,
348 void *func_args,
349 char *errstring,
350 char **gdberrmsg,
351 return_mask mask)
352{
2a78bfb5
AC
353 volatile struct exception exception;
354 volatile int val = 0;
355 SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask);
356 for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
db5f402d 357 val = (*func) (uiout, func_args);
60250e8b 358 gdb_assert (val >= 0);
2a78bfb5
AC
359 gdb_assert (exception.reason <= 0);
360 if (exception.reason < 0)
361 {
362 /* If caller wants a copy of the low-level error message, make
363 one. This is used in the case of a silent error whereby the
364 caller may optionally want to issue the message. */
365 if (gdberrmsg != NULL)
366 *gdberrmsg = exception.message;
367 return exception.reason;
368 }
60250e8b
AC
369 return val;
370}
371
60250e8b
AC
372int
373catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
374 return_mask mask)
375{
2a78bfb5
AC
376 volatile int val = 0;
377 volatile struct exception exception;
378 SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask);
db5f402d
AC
379 /* This illustrates how it is possible to nest the mechanism and
380 hence catch "break". Of course this doesn't address the need to
381 also catch "return". */
2a78bfb5
AC
382 for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
383 val = func (func_args);
384 if (exception.reason != 0)
60250e8b
AC
385 return 0;
386 return val;
387}
388
389struct captured_command_args
390 {
391 catch_command_errors_ftype *command;
392 char *arg;
393 int from_tty;
394 };
395
396static int
397do_captured_command (void *data)
398{
399 struct captured_command_args *context = data;
400 context->command (context->arg, context->from_tty);
401 /* FIXME: cagney/1999-11-07: Technically this do_cleanups() call
402 isn't needed. Instead an assertion check could be made that
403 simply confirmed that the called function correctly cleaned up
404 after itself. Unfortunately, old code (prior to 1999-11-04) in
405 main.c was calling SET_TOP_LEVEL(), calling the command function,
406 and then *always* calling do_cleanups(). For the moment we
407 remain ``bug compatible'' with that old code.. */
408 do_cleanups (ALL_CLEANUPS);
409 return 1;
410}
411
412int
413catch_command_errors (catch_command_errors_ftype * command,
414 char *arg, int from_tty, return_mask mask)
415{
416 struct captured_command_args args;
417 args.command = command;
418 args.arg = arg;
419 args.from_tty = from_tty;
420 return catch_errors (do_captured_command, &args, "", mask);
421}
This page took 0.05214 seconds and 4 git commands to generate.