2005-01-16 Andrew Cagney <cagney@gnu.org>
[external/binutils.git] / gdb / exceptions.c
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, 2005 Free
5    Software 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"
33 #include "gdb_string.h"
34
35 const struct exception exception_none = { 0, NO_ERROR, NULL };
36
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
49 /* Possible catcher states.  */
50 enum 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.  */
61 enum catcher_action {
62   CATCH_ITER,
63   CATCH_ITER_1,
64   CATCH_THROWING
65 };
66
67 struct catcher
68 {
69   enum catcher_state state;
70   /* Jump buffer pointing back at the exception handler.  */
71   SIGJMP_BUF buf;
72   /* Status buffer belonging to the exception handler.  */
73   volatile struct exception *exception;
74   /* Saved/current state.  */
75   int mask;
76   struct ui_out *saved_uiout;
77   struct cleanup *saved_cleanup_chain;
78   /* Back link.  */
79   struct catcher *prev;
80 };
81
82 /* Where to go for throw_exception().  */
83 static struct catcher *current_catcher;
84
85 static SIGJMP_BUF *
86 catcher_init (struct ui_out *func_uiout,
87               volatile struct exception *exception,
88               return_mask mask)
89 {
90   struct catcher *new_catcher = XZALLOC (struct catcher);
91
92   /* Start with no exception, save it's address.  */
93   exception->reason = 0;
94   exception->error = NO_ERROR;
95   exception->message = NULL;
96   new_catcher->exception = exception;
97
98   new_catcher->mask = mask;
99
100   /* Override the global ``struct ui_out'' builder.  */
101   new_catcher->saved_uiout = uiout;
102   uiout = func_uiout;
103
104   /* Prevent error/quit during FUNC from calling cleanups established
105      prior to here. */
106   new_catcher->saved_cleanup_chain = save_cleanups ();
107
108   /* Push this new catcher on the top.  */
109   new_catcher->prev = current_catcher;
110   current_catcher = new_catcher;
111   new_catcher->state = CATCHER_CREATED;
112
113   return &new_catcher->buf;
114 }
115
116 static void
117 catcher_pop (void)
118 {
119   struct catcher *old_catcher = current_catcher;
120   current_catcher = old_catcher->prev;
121
122   /* Restore the cleanup chain, the error/quit messages, and the uiout
123      builder, to their original states. */
124
125   restore_cleanups (old_catcher->saved_cleanup_chain);
126
127   uiout = old_catcher->saved_uiout;
128
129   xfree (old_catcher);
130 }
131
132 /* Catcher state machine.  Returns non-zero if the m/c should be run
133    again, zero if it should abort.  */
134
135 int
136 catcher_state_machine (enum catcher_action action)
137 {
138   switch (current_catcher->state)
139     {
140     case CATCHER_CREATED:
141       switch (action)
142         {
143         case CATCH_ITER:
144           /* Allow the code to run the catcher.  */
145           current_catcher->state = CATCHER_RUNNING;
146           return 1;
147         default:
148           internal_error (__FILE__, __LINE__, "bad state");
149         }
150     case CATCHER_RUNNING:
151       switch (action)
152         {
153         case CATCH_ITER:
154           /* No error/quit has occured.  Just clean up.  */
155           catcher_pop ();
156           return 0;
157         case CATCH_ITER_1:
158           current_catcher->state = CATCHER_RUNNING_1;
159           return 1;
160         case CATCH_THROWING:
161           current_catcher->state = CATCHER_ABORTING;
162           /* See also throw_exception.  */
163           return 1;
164         default:
165           internal_error (__FILE__, __LINE__, "bad switch");
166         }
167     case CATCHER_RUNNING_1:
168       switch (action)
169         {
170         case CATCH_ITER:
171           /* The did a "break" from the inner while loop.  */
172           catcher_pop ();
173           return 0;
174         case CATCH_ITER_1:
175           current_catcher->state = CATCHER_RUNNING;
176           return 0;
177         case CATCH_THROWING:
178           current_catcher->state = CATCHER_ABORTING;
179           /* See also throw_exception.  */
180           return 1;
181         default:
182           internal_error (__FILE__, __LINE__, "bad switch");
183         }
184     case CATCHER_ABORTING:
185       switch (action)
186         {
187         case CATCH_ITER:
188           {
189             struct exception exception = *current_catcher->exception;
190             if (current_catcher->mask & RETURN_MASK (exception.reason))
191               {
192                 /* Exit normally if this catcher can handle this
193                    exception.  The caller analyses the func return
194                    values.  */
195                 catcher_pop ();
196                 return 0;
197               }
198             /* The caller didn't request that the event be caught,
199                relay the event to the next containing
200                catch_errors(). */
201             catcher_pop ();
202             throw_exception (exception);
203           }
204         default:
205           internal_error (__FILE__, __LINE__, "bad state");
206         }
207     default:
208       internal_error (__FILE__, __LINE__, "bad switch");
209     }
210 }
211
212 /* Return EXCEPTION to the nearest containing catch_errors().  */
213
214 NORETURN void
215 throw_exception (struct exception exception)
216 {
217   quit_flag = 0;
218   immediate_quit = 0;
219
220   /* Perhaps it would be cleaner to do this via the cleanup chain (not sure
221      I can think of a reason why that is vital, though).  */
222   bpstat_clear_actions (stop_bpstat);   /* Clear queued breakpoint commands */
223
224   disable_current_display ();
225   do_cleanups (ALL_CLEANUPS);
226   if (target_can_async_p () && !target_executing)
227     do_exec_cleanups (ALL_CLEANUPS);
228   if (sync_execution)
229     do_exec_error_cleanups (ALL_CLEANUPS);
230
231   /* Jump to the containing catch_errors() call, communicating REASON
232      to that call via setjmp's return value.  Note that REASON can't
233      be zero, by definition in defs.h. */
234   catcher_state_machine (CATCH_THROWING);
235   *current_catcher->exception = exception;
236   SIGLONGJMP (current_catcher->buf, exception.reason);
237 }
238
239 static char *last_message;
240
241 NORETURN void
242 throw_reason (enum return_reason reason)
243 {
244   struct exception exception;
245   memset (&exception, 0, sizeof exception);
246
247   exception.reason = reason;
248   switch (reason)
249     {
250     case RETURN_QUIT:
251       break;
252     case RETURN_ERROR:
253       exception.error = GENERIC_ERROR;
254       break;
255     default:
256       internal_error (__FILE__, __LINE__, "bad switch");
257     }
258   
259   throw_exception (exception);
260 }
261
262 static void
263 print_flush (void)
264 {
265   if (deprecated_error_begin_hook)
266     deprecated_error_begin_hook ();
267   target_terminal_ours ();
268   wrap_here ("");               /* Force out any buffered output */
269   gdb_flush (gdb_stdout);
270   annotate_error_begin ();
271 }
272
273 static void
274 print_exception (struct ui_file *file, struct exception e)
275 {
276   /* KLUGE: cagney/2005-01-13: Write the string out one line at a time
277      as that way the MI's behavior is preserved.  */
278   const char *start;
279   const char *end;
280   for (start = e.message; start != NULL; start = end)
281     {
282       end = strchr (start, '\n');
283       if (end == NULL)
284         fputs_filtered (start, file);
285       else
286         {
287           end++;
288           ui_file_write (file, start, end - start);
289         }
290     }                                       
291   fprintf_filtered (file, "\n");
292
293   /* Now append the annotation.  */
294   switch (e.reason)
295     {
296     case RETURN_QUIT:
297       annotate_quit ();
298       break;
299     case RETURN_ERROR:
300       /* Assume that these are all errors.  */
301       annotate_error ();
302       break;
303     default:
304       internal_error (__FILE__, __LINE__, _("Bad switch."));
305     }
306 }
307
308 void
309 exception_print (struct ui_file *file, struct exception e)
310 {
311   if (e.reason < 0 && e.message != NULL)
312     {
313       print_flush ();
314       print_exception (file, e);
315     }
316 }
317
318 void
319 exception_fprintf (struct ui_file *file, struct exception e,
320                    const char *prefix, ...)
321 {
322   if (e.reason < 0 && e.message != NULL)
323     {
324       va_list args;
325
326       print_flush ();
327
328       /* Print the prefix.  */
329       va_start (args, prefix);
330       vfprintf_filtered (file, prefix, args);
331       va_end (args);
332
333       print_exception (file, e);
334     }
335 }
336
337 void
338 print_any_exception (struct ui_file *file, const char *prefix,
339                      struct exception e)
340 {
341   if (e.reason < 0 && e.message != NULL)
342     {
343       target_terminal_ours ();
344       wrap_here ("");           /* Force out any buffered output */
345       gdb_flush (gdb_stdout);
346       annotate_error_begin ();
347
348       /* Print the prefix.  */
349       if (prefix != NULL && prefix[0] != '\0')
350         fputs_filtered (prefix, file);
351       print_exception (file, e);
352     }
353 }
354
355 NORETURN static void
356 throw_it (enum return_reason reason, enum errors error, const char *fmt,
357           va_list ap) ATTR_NORETURN;
358 NORETURN static void
359 throw_it (enum return_reason reason, enum errors error, const char *fmt,
360           va_list ap)
361 {
362   struct exception e;
363
364   /* Save the message.  */
365   xfree (last_message);
366   last_message = xstrvprintf (fmt, ap);
367
368   /* Create the exception.  */
369   e.reason = reason;
370   e.error = error;
371   e.message = last_message;
372
373   /* Throw the exception.  */
374   throw_exception (e);
375 }
376
377 NORETURN void
378 throw_verror (enum errors error, const char *fmt, va_list ap)
379 {
380   throw_it (RETURN_ERROR, error, fmt, ap);
381 }
382
383 NORETURN void
384 throw_vfatal (const char *fmt, va_list ap)
385 {
386   throw_it (RETURN_QUIT, NO_ERROR, fmt, ap);
387 }
388
389 NORETURN void
390 throw_error (enum errors error, const char *fmt, ...)
391 {
392   va_list args;
393   va_start (args, fmt);
394   throw_it (RETURN_ERROR, error, fmt, args);
395   va_end (args);
396 }
397
398 /* Call FUNC() with args FUNC_UIOUT and FUNC_ARGS, catching any
399    errors.  Set FUNC_CAUGHT to an ``enum return_reason'' if the
400    function is aborted (using throw_exception() or zero if the
401    function returns normally.  Set FUNC_VAL to the value returned by
402    the function or 0 if the function was aborted.
403
404    Must not be called with immediate_quit in effect (bad things might
405    happen, say we got a signal in the middle of a memcpy to quit_return).
406    This is an OK restriction; with very few exceptions immediate_quit can
407    be replaced by judicious use of QUIT.
408
409    MASK specifies what to catch; it is normally set to
410    RETURN_MASK_ALL, if for no other reason than that the code which
411    calls catch_errors might not be set up to deal with a quit which
412    isn't caught.  But if the code can deal with it, it generally
413    should be RETURN_MASK_ERROR, unless for some reason it is more
414    useful to abort only the portion of the operation inside the
415    catch_errors.  Note that quit should return to the command line
416    fairly quickly, even if some further processing is being done.  */
417
418 /* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
419    error() et.al. could maintain a set of flags that indicate the the
420    current state of each of the longjmp buffers.  This would give the
421    longjmp code the chance to detect a longjmp botch (before it gets
422    to longjmperror()).  Prior to 1999-11-05 this wasn't possible as
423    code also randomly used a SET_TOP_LEVEL macro that directly
424    initialize the longjmp buffers. */
425
426 /* MAYBE: cagney/1999-11-05: Should the catch_errors and cleanups code
427    be consolidated into a single file instead of being distributed
428    between utils.c and top.c? */
429
430 int
431 catch_exceptions (struct ui_out *uiout,
432                   catch_exceptions_ftype *func,
433                   void *func_args,
434                   return_mask mask)
435 {
436   return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
437 }
438
439 struct exception
440 catch_exception (struct ui_out *uiout,
441                  catch_exception_ftype *func,
442                  void *func_args,
443                  return_mask mask)
444 {
445   volatile struct exception exception;
446   SIGJMP_BUF *catch;
447   catch = catcher_init (uiout, &exception, mask);
448   for (SIGSETJMP ((*catch));
449        catcher_state_machine (CATCH_ITER);)
450     (*func) (uiout, func_args);
451   return exception;
452 }
453
454 int
455 catch_exceptions_with_msg (struct ui_out *uiout,
456                            catch_exceptions_ftype *func,
457                            void *func_args,
458                            char **gdberrmsg,
459                            return_mask mask)
460 {
461   volatile struct exception exception;
462   volatile int val = 0;
463   SIGJMP_BUF *catch = catcher_init (uiout, &exception, mask);
464   for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
465     val = (*func) (uiout, func_args);
466   print_any_exception (gdb_stderr, NULL, exception);
467   gdb_assert (val >= 0);
468   gdb_assert (exception.reason <= 0);
469   if (exception.reason < 0)
470     {
471       /* If caller wants a copy of the low-level error message, make
472          one.  This is used in the case of a silent error whereby the
473          caller may optionally want to issue the message.  */
474       if (gdberrmsg != NULL)
475         {
476           if (exception.message != NULL)
477             *gdberrmsg = xstrdup (exception.message);
478           else
479             *gdberrmsg = NULL;
480         }
481       return exception.reason;
482     }
483   return val;
484 }
485
486 int
487 catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
488               return_mask mask)
489 {
490   volatile int val = 0;
491   volatile struct exception exception;
492   SIGJMP_BUF *catch = catcher_init (uiout, &exception, mask);
493   /* This illustrates how it is possible to nest the mechanism and
494      hence catch "break".  Of course this doesn't address the need to
495      also catch "return".  */
496   for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
497     val = func (func_args);
498   print_any_exception (gdb_stderr, errstring, exception);
499   if (exception.reason != 0)
500     return 0;
501   return val;
502 }
503
504 int
505 catch_command_errors (catch_command_errors_ftype * command,
506                       char *arg, int from_tty, return_mask mask)
507 {
508   volatile struct exception e;
509   SIGJMP_BUF *catch = catcher_init (uiout, &e, mask);
510   for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
511     command (arg, from_tty);
512   print_any_exception (gdb_stderr, NULL, e);
513   if (e.reason < 0)
514     return 0;
515   return 1;
516 }