OSDN Git Service

2005-01-12 Andrew Cagney <cagney@gnu.org>
[pf3gnuchains/pf3gnuchains3x.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 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"
33 #include "gdb_string.h"
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
47 /* Possible catcher states.  */
48 enum 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.  */
59 enum catcher_action {
60   CATCH_ITER,
61   CATCH_ITER_1,
62   CATCH_THROWING
63 };
64
65 struct catcher
66 {
67   enum catcher_state state;
68   /* Jump buffer pointing back at the exception handler.  */
69   SIGJMP_BUF buf;
70   /* Status buffer belonging to that exception handler.  */
71   volatile struct exception *exception;
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;
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               char *errstring,
88               volatile struct exception *exception,
89               return_mask mask)
90 {
91   struct catcher *new_catcher = XZALLOC (struct catcher);
92
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
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
125 static void
126 catcher_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
147 int
148 catcher_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           {
201             struct exception exception = *current_catcher->exception;
202             if (current_catcher->mask & RETURN_MASK (exception.reason))
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 ();
214             throw_exception (exception);
215           }
216         default:
217           internal_error (__FILE__, __LINE__, "bad state");
218         }
219     default:
220       internal_error (__FILE__, __LINE__, "bad switch");
221     }
222 }
223
224 /* Return EXCEPTION to the nearest containing catch_errors().  */
225
226 NORETURN void
227 throw_exception (struct exception exception)
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)
244     switch (exception.reason)
245       {
246       case RETURN_QUIT:
247         annotate_quit ();
248         break;
249       case RETURN_ERROR:
250         /* Assume that these are all errors.  */
251         annotate_error ();
252         break;
253       default:
254         internal_error (__FILE__, __LINE__, "Bad switch.");
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. */
260   catcher_state_machine (CATCH_THROWING);
261   *current_catcher->exception = exception;
262   SIGLONGJMP (current_catcher->buf, exception.reason);
263 }
264
265 NORETURN void
266 throw_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);
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
319 int
320 catch_exceptions (struct ui_out *uiout,
321                   catch_exceptions_ftype *func,
322                   void *func_args,
323                   char *errstring,
324                   return_mask mask)
325 {
326   return catch_exceptions_with_msg (uiout, func, func_args, errstring,
327                                     NULL, mask);
328 }
329
330 struct exception
331 catch_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
345 int
346 catch_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 {
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);)
357     val = (*func) (uiout, func_args);
358   gdb_assert (val >= 0);
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     }
369   return val;
370 }
371
372 int
373 catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
374               return_mask mask)
375 {
376   volatile int val = 0;
377   volatile struct exception exception;
378   SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask);
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".  */
382   for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
383     val = func (func_args);
384   if (exception.reason != 0)
385     return 0;
386   return val;
387 }
388
389 struct captured_command_args
390   {
391     catch_command_errors_ftype *command;
392     char *arg;
393     int from_tty;
394   };
395
396 static int
397 do_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
412 int
413 catch_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 }