]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/exceptions.c
2005-01-14 Andrew Cagney <cagney@gnu.org>
[thirdparty/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,
05ff989b
AC
4 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
5 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
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 34
c1043fc2
AC
35const struct exception exception_none = { 0, NO_ERROR, NULL };
36
60250e8b
AC
37/* One should use catch_errors rather than manipulating these
38 directly. */
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))
43#else
44#define SIGJMP_BUF jmp_buf
45#define SIGSETJMP(buf) setjmp(buf)
46#define SIGLONGJMP(buf,val) longjmp((buf), (val))
47#endif
48
db5f402d
AC
49/* Possible catcher states. */
50enum catcher_state {
51 /* Initial state, a new catcher has just been created. */
52 CATCHER_CREATED,
53 /* The catch code is running. */
54 CATCHER_RUNNING,
55 CATCHER_RUNNING_1,
56 /* The catch code threw an exception. */
57 CATCHER_ABORTING
58};
59
60/* Possible catcher actions. */
61enum catcher_action {
62 CATCH_ITER,
63 CATCH_ITER_1,
64 CATCH_THROWING
65};
66
67struct catcher
68{
69 enum catcher_state state;
2a78bfb5 70 /* Jump buffer pointing back at the exception handler. */
db5f402d 71 SIGJMP_BUF buf;
8a076db9 72 /* Status buffer belonging to the exception handler. */
2a78bfb5 73 volatile struct exception *exception;
8a076db9
AC
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
77 messages. */
78 int print_message;
db5f402d
AC
79 /* Saved/current state. */
80 int mask;
81 char *saved_error_pre_print;
82 char *saved_quit_pre_print;
83 struct ui_out *saved_uiout;
84 struct cleanup *saved_cleanup_chain;
db5f402d
AC
85 /* Back link. */
86 struct catcher *prev;
87};
88
60250e8b 89/* Where to go for throw_exception(). */
db5f402d
AC
90static struct catcher *current_catcher;
91
92static SIGJMP_BUF *
93catcher_init (struct ui_out *func_uiout,
94 char *errstring,
2a78bfb5 95 volatile struct exception *exception,
8a076db9
AC
96 return_mask mask,
97 int print_message)
db5f402d
AC
98{
99 struct catcher *new_catcher = XZALLOC (struct catcher);
100
2a78bfb5
AC
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;
106
db5f402d 107 new_catcher->mask = mask;
8a076db9 108 new_catcher->print_message = print_message;
db5f402d
AC
109
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;
117
118 /* Override the global ``struct ui_out'' builder. */
119 new_catcher->saved_uiout = uiout;
120 uiout = func_uiout;
121
122 /* Prevent error/quit during FUNC from calling cleanups established
123 prior to here. */
124 new_catcher->saved_cleanup_chain = save_cleanups ();
125
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;
130
131 return &new_catcher->buf;
132}
133
134static void
135catcher_pop (void)
136{
137 struct catcher *old_catcher = current_catcher;
138 current_catcher = old_catcher->prev;
139
140 /* Restore the cleanup chain, the error/quit messages, and the uiout
141 builder, to their original states. */
142
143 restore_cleanups (old_catcher->saved_cleanup_chain);
144
145 uiout = old_catcher->saved_uiout;
146
147 quit_pre_print = old_catcher->saved_quit_pre_print;
148 error_pre_print = old_catcher->saved_error_pre_print;
149
150 xfree (old_catcher);
151}
152
153/* Catcher state machine. Returns non-zero if the m/c should be run
154 again, zero if it should abort. */
155
156int
157catcher_state_machine (enum catcher_action action)
158{
159 switch (current_catcher->state)
160 {
161 case CATCHER_CREATED:
162 switch (action)
163 {
164 case CATCH_ITER:
165 /* Allow the code to run the catcher. */
166 current_catcher->state = CATCHER_RUNNING;
167 return 1;
168 default:
169 internal_error (__FILE__, __LINE__, "bad state");
170 }
171 case CATCHER_RUNNING:
172 switch (action)
173 {
174 case CATCH_ITER:
175 /* No error/quit has occured. Just clean up. */
176 catcher_pop ();
177 return 0;
178 case CATCH_ITER_1:
179 current_catcher->state = CATCHER_RUNNING_1;
180 return 1;
181 case CATCH_THROWING:
182 current_catcher->state = CATCHER_ABORTING;
183 /* See also throw_exception. */
184 return 1;
185 default:
186 internal_error (__FILE__, __LINE__, "bad switch");
187 }
188 case CATCHER_RUNNING_1:
189 switch (action)
190 {
191 case CATCH_ITER:
192 /* The did a "break" from the inner while loop. */
193 catcher_pop ();
194 return 0;
195 case CATCH_ITER_1:
196 current_catcher->state = CATCHER_RUNNING;
197 return 0;
198 case CATCH_THROWING:
199 current_catcher->state = CATCHER_ABORTING;
200 /* See also throw_exception. */
201 return 1;
202 default:
203 internal_error (__FILE__, __LINE__, "bad switch");
204 }
205 case CATCHER_ABORTING:
206 switch (action)
207 {
208 case CATCH_ITER:
209 {
2a78bfb5
AC
210 struct exception exception = *current_catcher->exception;
211 if (current_catcher->mask & RETURN_MASK (exception.reason))
db5f402d
AC
212 {
213 /* Exit normally if this catcher can handle this
214 exception. The caller analyses the func return
215 values. */
216 catcher_pop ();
217 return 0;
218 }
219 /* The caller didn't request that the event be caught,
220 relay the event to the next containing
221 catch_errors(). */
222 catcher_pop ();
2a78bfb5 223 throw_exception (exception);
db5f402d
AC
224 }
225 default:
226 internal_error (__FILE__, __LINE__, "bad state");
227 }
228 default:
229 internal_error (__FILE__, __LINE__, "bad switch");
230 }
231}
60250e8b 232
2a78bfb5 233/* Return EXCEPTION to the nearest containing catch_errors(). */
60250e8b
AC
234
235NORETURN void
2a78bfb5 236throw_exception (struct exception exception)
60250e8b
AC
237{
238 quit_flag = 0;
239 immediate_quit = 0;
240
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 */
244
245 disable_current_display ();
246 do_cleanups (ALL_CLEANUPS);
247 if (target_can_async_p () && !target_executing)
248 do_exec_cleanups (ALL_CLEANUPS);
249 if (sync_execution)
250 do_exec_error_cleanups (ALL_CLEANUPS);
251
252 if (annotation_level > 1)
2a78bfb5 253 switch (exception.reason)
60250e8b
AC
254 {
255 case RETURN_QUIT:
256 annotate_quit ();
257 break;
258 case RETURN_ERROR:
2a78bfb5 259 /* Assume that these are all errors. */
60250e8b
AC
260 annotate_error ();
261 break;
2a78bfb5
AC
262 default:
263 internal_error (__FILE__, __LINE__, "Bad switch.");
60250e8b
AC
264 }
265
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. */
db5f402d 269 catcher_state_machine (CATCH_THROWING);
2a78bfb5
AC
270 *current_catcher->exception = exception;
271 SIGLONGJMP (current_catcher->buf, exception.reason);
272}
273
6b1b7650
AC
274static char *last_message;
275
2a78bfb5
AC
276NORETURN void
277throw_reason (enum return_reason reason)
278{
279 struct exception exception;
280 memset (&exception, 0, sizeof exception);
281
282 exception.reason = reason;
283 switch (reason)
284 {
285 case RETURN_QUIT:
286 break;
287 case RETURN_ERROR:
288 exception.error = GENERIC_ERROR;
6b1b7650 289 exception.message = last_message;
2a78bfb5
AC
290 break;
291 default:
292 internal_error (__FILE__, __LINE__, "bad switch");
293 }
294
295 throw_exception (exception);
60250e8b
AC
296}
297
6b1b7650
AC
298static void
299do_write (void *data, const char *buffer, long length_buffer)
300{
301 ui_file_write (data, buffer, length_buffer);
302}
303
304
9cbc821d
AC
305static void
306print_exception (struct ui_file *file, struct exception e)
307{
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. */
310 const char *start;
311 const char *end;
312 for (start = e.message; start != NULL; start = end)
313 {
314 end = strchr (start, '\n');
315 if (end == NULL)
316 fputs_filtered (start, file);
317 else
318 {
319 end++;
320 ui_file_write (file, start, end - start);
321 }
322 }
323}
324
8a076db9 325void
9cbc821d 326exception_print (struct ui_file *file, struct exception e)
8a076db9
AC
327{
328 if (e.reason < 0 && e.message != NULL)
329 {
330 target_terminal_ours ();
331 wrap_here (""); /* Force out any buffered output */
332 gdb_flush (file);
333 annotate_error_begin ();
9cbc821d
AC
334 print_exception (file, e);
335 fprintf_filtered (file, "\n");
336 }
337}
8a076db9 338
9cbc821d
AC
339void
340exception_fprintf (struct ui_file *file, struct exception e,
341 const char *prefix, ...)
342{
343 if (e.reason < 0 && e.message != NULL)
344 {
345 va_list args;
346 target_terminal_ours ();
347 wrap_here (""); /* Force out any buffered output */
348 gdb_flush (file);
349 annotate_error_begin ();
350
351 /* Print the prefix. */
352 va_start (args, prefix);
353 vfprintf_filtered (file, prefix, args);
354 va_end (args);
355
356 print_exception (file, e);
8a076db9
AC
357 fprintf_filtered (file, "\n");
358 }
359}
360
6b1b7650
AC
361NORETURN static void
362print_and_throw (enum return_reason reason, enum errors error,
363 const char *prefix, const char *fmt,
364 va_list ap) ATTR_NORETURN;
365NORETURN static void
366print_and_throw (enum return_reason reason, enum errors error,
367 const char *prefix, const char *fmt, va_list ap)
368{
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. */
374
375 struct exception e;
376 struct ui_file *tmp_stream;
377 long len;
378
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);
383
384 /* Save the message. */
385 xfree (last_message);
386 last_message = ui_file_xstrdup (tmp_stream, &len);
387
8a076db9
AC
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)
391 {
392 if (deprecated_error_begin_hook)
393 deprecated_error_begin_hook ();
394
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 ();
400 if (error_pre_print)
401 fputs_filtered (error_pre_print, gdb_stderr);
402 ui_file_put (tmp_stream, do_write, gdb_stderr);
403 fprintf_filtered (gdb_stderr, "\n");
404 }
6b1b7650
AC
405
406 /* Throw the exception. */
407 e.reason = reason;
408 e.error = error;
409 e.message = last_message;
410 throw_exception (e);
411}
412
413NORETURN void
414throw_verror (enum errors error, const char *fmt, va_list ap)
415{
416 print_and_throw (RETURN_ERROR, error, error_pre_print, fmt, ap);
417}
418
419NORETURN void
420throw_vfatal (const char *fmt, va_list ap)
421{
422 print_and_throw (RETURN_QUIT, NO_ERROR, quit_pre_print, fmt, ap);
423}
424
425NORETURN void
05ff989b 426throw_error (enum errors error, const char *fmt, ...)
6b1b7650 427{
05ff989b
AC
428 va_list args;
429 va_start (args, fmt);
430 print_and_throw (RETURN_ERROR, error, error_pre_print, fmt, args);
431 va_end (args);
6b1b7650
AC
432}
433
60250e8b
AC
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.
439
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.
444
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. */
453
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. */
461
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? */
465
60250e8b
AC
466int
467catch_exceptions (struct ui_out *uiout,
468 catch_exceptions_ftype *func,
469 void *func_args,
60250e8b
AC
470 return_mask mask)
471{
1c3c7ee7 472 return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
60250e8b
AC
473}
474
2a78bfb5
AC
475struct exception
476catch_exception (struct ui_out *uiout,
477 catch_exception_ftype *func,
478 void *func_args,
479 return_mask mask)
480{
481 volatile struct exception exception;
482 SIGJMP_BUF *catch;
8a076db9 483 catch = catcher_init (uiout, NULL, &exception, mask, 0);
2a78bfb5
AC
484 for (SIGSETJMP ((*catch));
485 catcher_state_machine (CATCH_ITER);)
486 (*func) (uiout, func_args);
487 return exception;
488}
489
60250e8b
AC
490int
491catch_exceptions_with_msg (struct ui_out *uiout,
492 catch_exceptions_ftype *func,
493 void *func_args,
60250e8b
AC
494 char **gdberrmsg,
495 return_mask mask)
496{
2a78bfb5
AC
497 volatile struct exception exception;
498 volatile int val = 0;
1c3c7ee7 499 SIGJMP_BUF *catch = catcher_init (uiout, NULL, &exception, mask, 1);
2a78bfb5 500 for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
db5f402d 501 val = (*func) (uiout, func_args);
60250e8b 502 gdb_assert (val >= 0);
2a78bfb5
AC
503 gdb_assert (exception.reason <= 0);
504 if (exception.reason < 0)
505 {
506 /* If caller wants a copy of the low-level error message, make
507 one. This is used in the case of a silent error whereby the
508 caller may optionally want to issue the message. */
509 if (gdberrmsg != NULL)
6b1b7650
AC
510 {
511 if (exception.message != NULL)
512 *gdberrmsg = xstrdup (exception.message);
513 else
514 *gdberrmsg = NULL;
515 }
2a78bfb5
AC
516 return exception.reason;
517 }
60250e8b
AC
518 return val;
519}
520
60250e8b
AC
521int
522catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
523 return_mask mask)
524{
2a78bfb5
AC
525 volatile int val = 0;
526 volatile struct exception exception;
8a076db9 527 SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask, 1);
db5f402d
AC
528 /* This illustrates how it is possible to nest the mechanism and
529 hence catch "break". Of course this doesn't address the need to
530 also catch "return". */
2a78bfb5
AC
531 for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
532 val = func (func_args);
533 if (exception.reason != 0)
60250e8b
AC
534 return 0;
535 return val;
536}
537
538struct captured_command_args
539 {
540 catch_command_errors_ftype *command;
541 char *arg;
542 int from_tty;
543 };
544
545static int
546do_captured_command (void *data)
547{
548 struct captured_command_args *context = data;
549 context->command (context->arg, context->from_tty);
550 /* FIXME: cagney/1999-11-07: Technically this do_cleanups() call
551 isn't needed. Instead an assertion check could be made that
552 simply confirmed that the called function correctly cleaned up
553 after itself. Unfortunately, old code (prior to 1999-11-04) in
554 main.c was calling SET_TOP_LEVEL(), calling the command function,
555 and then *always* calling do_cleanups(). For the moment we
556 remain ``bug compatible'' with that old code.. */
557 do_cleanups (ALL_CLEANUPS);
558 return 1;
559}
560
561int
562catch_command_errors (catch_command_errors_ftype * command,
563 char *arg, int from_tty, return_mask mask)
564{
565 struct captured_command_args args;
566 args.command = command;
567 args.arg = arg;
568 args.from_tty = from_tty;
569 return catch_errors (do_captured_command, &args, "", mask);
570}