xref: /dflybsd-src/contrib/gdb-7/gdb/exceptions.h (revision 5796c8dc12c637f18a1740c26afd8d40ffa9b719)
1*5796c8dcSSimon Schubert /* Exception (throw catch) mechanism, for GDB, the GNU debugger.
2*5796c8dcSSimon Schubert 
3*5796c8dcSSimon Schubert    Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
4*5796c8dcSSimon Schubert    1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
5*5796c8dcSSimon Schubert    2009 Free Software Foundation, Inc.
6*5796c8dcSSimon Schubert 
7*5796c8dcSSimon Schubert    This file is part of GDB.
8*5796c8dcSSimon Schubert 
9*5796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
10*5796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
11*5796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
12*5796c8dcSSimon Schubert    (at your option) any later version.
13*5796c8dcSSimon Schubert 
14*5796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
15*5796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
16*5796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17*5796c8dcSSimon Schubert    GNU General Public License for more details.
18*5796c8dcSSimon Schubert 
19*5796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
20*5796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21*5796c8dcSSimon Schubert 
22*5796c8dcSSimon Schubert #ifndef EXCEPTIONS_H
23*5796c8dcSSimon Schubert #define EXCEPTIONS_H
24*5796c8dcSSimon Schubert 
25*5796c8dcSSimon Schubert #include "ui-out.h"
26*5796c8dcSSimon Schubert #include <setjmp.h>
27*5796c8dcSSimon Schubert 
28*5796c8dcSSimon Schubert /* Reasons for calling throw_exceptions().  NOTE: all reason values
29*5796c8dcSSimon Schubert    must be less than zero.  enum value 0 is reserved for internal use
30*5796c8dcSSimon Schubert    as the return value from an initial setjmp().  The function
31*5796c8dcSSimon Schubert    catch_exceptions() reserves values >= 0 as legal results from its
32*5796c8dcSSimon Schubert    wrapped function.  */
33*5796c8dcSSimon Schubert 
34*5796c8dcSSimon Schubert enum return_reason
35*5796c8dcSSimon Schubert   {
36*5796c8dcSSimon Schubert     /* User interrupt.  */
37*5796c8dcSSimon Schubert     RETURN_QUIT = -2,
38*5796c8dcSSimon Schubert     /* Any other error.  */
39*5796c8dcSSimon Schubert     RETURN_ERROR
40*5796c8dcSSimon Schubert   };
41*5796c8dcSSimon Schubert 
42*5796c8dcSSimon Schubert #define RETURN_MASK(reason)	(1 << (int)(-reason))
43*5796c8dcSSimon Schubert #define RETURN_MASK_QUIT	RETURN_MASK (RETURN_QUIT)
44*5796c8dcSSimon Schubert #define RETURN_MASK_ERROR	RETURN_MASK (RETURN_ERROR)
45*5796c8dcSSimon Schubert #define RETURN_MASK_ALL		(RETURN_MASK_QUIT | RETURN_MASK_ERROR)
46*5796c8dcSSimon Schubert typedef int return_mask;
47*5796c8dcSSimon Schubert 
48*5796c8dcSSimon Schubert /* Describe all exceptions.  */
49*5796c8dcSSimon Schubert 
50*5796c8dcSSimon Schubert enum errors {
51*5796c8dcSSimon Schubert   GDB_NO_ERROR,
52*5796c8dcSSimon Schubert   /* Any generic error, the corresponding text is in
53*5796c8dcSSimon Schubert      exception.message.  */
54*5796c8dcSSimon Schubert   GENERIC_ERROR,
55*5796c8dcSSimon Schubert   NOT_FOUND_ERROR,
56*5796c8dcSSimon Schubert 
57*5796c8dcSSimon Schubert   /* Thread library lacks support necessary for finding thread local
58*5796c8dcSSimon Schubert      storage.  */
59*5796c8dcSSimon Schubert   TLS_NO_LIBRARY_SUPPORT_ERROR,
60*5796c8dcSSimon Schubert 
61*5796c8dcSSimon Schubert   /* Load module not found while attempting to find thread local storage.  */
62*5796c8dcSSimon Schubert   TLS_LOAD_MODULE_NOT_FOUND_ERROR,
63*5796c8dcSSimon Schubert 
64*5796c8dcSSimon Schubert   /* Thread local storage has not been allocated yet.  */
65*5796c8dcSSimon Schubert   TLS_NOT_ALLOCATED_YET_ERROR,
66*5796c8dcSSimon Schubert 
67*5796c8dcSSimon Schubert   /* Something else went wrong while attempting to find thread local
68*5796c8dcSSimon Schubert      storage.  The ``struct gdb_exception'' message field provides
69*5796c8dcSSimon Schubert      more detail.  */
70*5796c8dcSSimon Schubert   TLS_GENERIC_ERROR,
71*5796c8dcSSimon Schubert 
72*5796c8dcSSimon Schubert   /* Problem parsing an XML document.  */
73*5796c8dcSSimon Schubert   XML_PARSE_ERROR,
74*5796c8dcSSimon Schubert 
75*5796c8dcSSimon Schubert   /* Error accessing memory.  */
76*5796c8dcSSimon Schubert   MEMORY_ERROR,
77*5796c8dcSSimon Schubert 
78*5796c8dcSSimon Schubert   /* Add more errors here.  */
79*5796c8dcSSimon Schubert   NR_ERRORS
80*5796c8dcSSimon Schubert };
81*5796c8dcSSimon Schubert 
82*5796c8dcSSimon Schubert struct gdb_exception
83*5796c8dcSSimon Schubert {
84*5796c8dcSSimon Schubert   enum return_reason reason;
85*5796c8dcSSimon Schubert   enum errors error;
86*5796c8dcSSimon Schubert   const char *message;
87*5796c8dcSSimon Schubert };
88*5796c8dcSSimon Schubert 
89*5796c8dcSSimon Schubert /* A pre-defined non-exception.  */
90*5796c8dcSSimon Schubert extern const struct gdb_exception exception_none;
91*5796c8dcSSimon Schubert 
92*5796c8dcSSimon Schubert /* Wrap set/long jmp so that it's more portable (internal to
93*5796c8dcSSimon Schubert    exceptions).  */
94*5796c8dcSSimon Schubert 
95*5796c8dcSSimon Schubert #if defined(HAVE_SIGSETJMP)
96*5796c8dcSSimon Schubert #define EXCEPTIONS_SIGJMP_BUF		sigjmp_buf
97*5796c8dcSSimon Schubert #define EXCEPTIONS_SIGSETJMP(buf)	sigsetjmp((buf), 1)
98*5796c8dcSSimon Schubert #define EXCEPTIONS_SIGLONGJMP(buf,val)	siglongjmp((buf), (val))
99*5796c8dcSSimon Schubert #else
100*5796c8dcSSimon Schubert #define EXCEPTIONS_SIGJMP_BUF		jmp_buf
101*5796c8dcSSimon Schubert #define EXCEPTIONS_SIGSETJMP(buf)	setjmp(buf)
102*5796c8dcSSimon Schubert #define EXCEPTIONS_SIGLONGJMP(buf,val)	longjmp((buf), (val))
103*5796c8dcSSimon Schubert #endif
104*5796c8dcSSimon Schubert 
105*5796c8dcSSimon Schubert /* Functions to drive the exceptions state m/c (internal to
106*5796c8dcSSimon Schubert    exceptions).  */
107*5796c8dcSSimon Schubert EXCEPTIONS_SIGJMP_BUF *exceptions_state_mc_init (struct ui_out *func_uiout,
108*5796c8dcSSimon Schubert 						 volatile struct gdb_exception *
109*5796c8dcSSimon Schubert 						 exception,
110*5796c8dcSSimon Schubert 						 return_mask mask);
111*5796c8dcSSimon Schubert int exceptions_state_mc_action_iter (void);
112*5796c8dcSSimon Schubert int exceptions_state_mc_action_iter_1 (void);
113*5796c8dcSSimon Schubert 
114*5796c8dcSSimon Schubert /* Macro to wrap up standard try/catch behavior.
115*5796c8dcSSimon Schubert 
116*5796c8dcSSimon Schubert    The double loop lets us correctly handle code "break"ing out of the
117*5796c8dcSSimon Schubert    try catch block.  (It works as the "break" only exits the inner
118*5796c8dcSSimon Schubert    "while" loop, the outer for loop detects this handling it
119*5796c8dcSSimon Schubert    correctly.)  Of course "return" and "goto" are not so lucky.
120*5796c8dcSSimon Schubert 
121*5796c8dcSSimon Schubert    For instance:
122*5796c8dcSSimon Schubert 
123*5796c8dcSSimon Schubert    *INDENT-OFF*
124*5796c8dcSSimon Schubert 
125*5796c8dcSSimon Schubert    volatile struct gdb_exception e;
126*5796c8dcSSimon Schubert    TRY_CATCH (e, RETURN_MASK_ERROR)
127*5796c8dcSSimon Schubert      {
128*5796c8dcSSimon Schubert      }
129*5796c8dcSSimon Schubert    switch (e.reason)
130*5796c8dcSSimon Schubert      {
131*5796c8dcSSimon Schubert      case RETURN_ERROR: ...
132*5796c8dcSSimon Schubert      }
133*5796c8dcSSimon Schubert 
134*5796c8dcSSimon Schubert   */
135*5796c8dcSSimon Schubert 
136*5796c8dcSSimon Schubert #define TRY_CATCH(EXCEPTION,MASK) \
137*5796c8dcSSimon Schubert      { \
138*5796c8dcSSimon Schubert        EXCEPTIONS_SIGJMP_BUF *buf = \
139*5796c8dcSSimon Schubert 	 exceptions_state_mc_init (uiout, &(EXCEPTION), (MASK)); \
140*5796c8dcSSimon Schubert        EXCEPTIONS_SIGSETJMP (*buf); \
141*5796c8dcSSimon Schubert      } \
142*5796c8dcSSimon Schubert      while (exceptions_state_mc_action_iter ()) \
143*5796c8dcSSimon Schubert        while (exceptions_state_mc_action_iter_1 ())
144*5796c8dcSSimon Schubert 
145*5796c8dcSSimon Schubert /* *INDENT-ON* */
146*5796c8dcSSimon Schubert 
147*5796c8dcSSimon Schubert 
148*5796c8dcSSimon Schubert /* If E is an exception, print it's error message on the specified
149*5796c8dcSSimon Schubert    stream. for _fprintf, prefix the message with PREFIX...  */
150*5796c8dcSSimon Schubert extern void exception_print (struct ui_file *file, struct gdb_exception e);
151*5796c8dcSSimon Schubert extern void exception_fprintf (struct ui_file *file, struct gdb_exception e,
152*5796c8dcSSimon Schubert 			       const char *prefix,
153*5796c8dcSSimon Schubert 			       ...) ATTR_FORMAT (printf, 3, 4);
154*5796c8dcSSimon Schubert 
155*5796c8dcSSimon Schubert /* Throw an exception (as described by "struct gdb_exception").  Will
156*5796c8dcSSimon Schubert    execute a LONG JUMP to the inner most containing exception handler
157*5796c8dcSSimon Schubert    established using catch_exceptions() (or similar).
158*5796c8dcSSimon Schubert 
159*5796c8dcSSimon Schubert    Code normally throws an exception using error() et.al.  For various
160*5796c8dcSSimon Schubert    reaons, GDB also contains code that throws an exception directly.
161*5796c8dcSSimon Schubert    For instance, the remote*.c targets contain CNTRL-C signal handlers
162*5796c8dcSSimon Schubert    that propogate the QUIT event up the exception chain.  ``This could
163*5796c8dcSSimon Schubert    be a good thing or a dangerous thing.'' -- the Existential
164*5796c8dcSSimon Schubert    Wombat.  */
165*5796c8dcSSimon Schubert 
166*5796c8dcSSimon Schubert extern NORETURN void throw_exception (struct gdb_exception exception) ATTR_NORETURN;
167*5796c8dcSSimon Schubert extern NORETURN void throw_verror (enum errors, const char *fmt, va_list ap)
168*5796c8dcSSimon Schubert      ATTR_NORETURN ATTR_FORMAT (printf, 2, 0);
169*5796c8dcSSimon Schubert extern NORETURN void throw_vfatal (const char *fmt, va_list ap)
170*5796c8dcSSimon Schubert      ATTR_NORETURN ATTR_FORMAT (printf, 1, 0);
171*5796c8dcSSimon Schubert extern NORETURN void throw_error (enum errors error, const char *fmt,
172*5796c8dcSSimon Schubert 				  ...) ATTR_NORETURN ATTR_FORMAT (printf, 2, 3);
173*5796c8dcSSimon Schubert 
174*5796c8dcSSimon Schubert /* Instead of deprecated_throw_reason, code should use catch_exception
175*5796c8dcSSimon Schubert    and throw_exception.  */
176*5796c8dcSSimon Schubert extern NORETURN void deprecated_throw_reason (enum return_reason reason) ATTR_NORETURN;
177*5796c8dcSSimon Schubert 
178*5796c8dcSSimon Schubert /* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
179*5796c8dcSSimon Schubert    handler.  If an exception (enum return_reason) is thrown using
180*5796c8dcSSimon Schubert    throw_exception() than all cleanups installed since
181*5796c8dcSSimon Schubert    catch_exceptions() was entered are invoked, the (-ve) exception
182*5796c8dcSSimon Schubert    value is then returned by catch_exceptions.  If FUNC() returns
183*5796c8dcSSimon Schubert    normally (with a positive or zero return value) then that value is
184*5796c8dcSSimon Schubert    returned by catch_exceptions().  It is an internal_error() for
185*5796c8dcSSimon Schubert    FUNC() to return a negative value.
186*5796c8dcSSimon Schubert 
187*5796c8dcSSimon Schubert    For the period of the FUNC() call: UIOUT is installed as the output
188*5796c8dcSSimon Schubert    builder; ERRSTRING is installed as the error/quit message; and a
189*5796c8dcSSimon Schubert    new cleanup_chain is established.  The old values are restored
190*5796c8dcSSimon Schubert    before catch_exceptions() returns.
191*5796c8dcSSimon Schubert 
192*5796c8dcSSimon Schubert    The variant catch_exceptions_with_msg() is the same as
193*5796c8dcSSimon Schubert    catch_exceptions() but adds the ability to return an allocated
194*5796c8dcSSimon Schubert    copy of the gdb error message.  This is used when a silent error is
195*5796c8dcSSimon Schubert    issued and the caller wants to manually issue the error message.
196*5796c8dcSSimon Schubert 
197*5796c8dcSSimon Schubert    MASK specifies what to catch; it is normally set to
198*5796c8dcSSimon Schubert    RETURN_MASK_ALL, if for no other reason than that the code which
199*5796c8dcSSimon Schubert    calls catch_errors might not be set up to deal with a quit which
200*5796c8dcSSimon Schubert    isn't caught.  But if the code can deal with it, it generally
201*5796c8dcSSimon Schubert    should be RETURN_MASK_ERROR, unless for some reason it is more
202*5796c8dcSSimon Schubert    useful to abort only the portion of the operation inside the
203*5796c8dcSSimon Schubert    catch_errors.  Note that quit should return to the command line
204*5796c8dcSSimon Schubert    fairly quickly, even if some further processing is being done.
205*5796c8dcSSimon Schubert 
206*5796c8dcSSimon Schubert    FIXME; cagney/2001-08-13: The need to override the global UIOUT
207*5796c8dcSSimon Schubert    builder variable should just go away.
208*5796c8dcSSimon Schubert 
209*5796c8dcSSimon Schubert    This function supersedes catch_errors().
210*5796c8dcSSimon Schubert 
211*5796c8dcSSimon Schubert    This function uses SETJMP() and LONGJUMP().  */
212*5796c8dcSSimon Schubert 
213*5796c8dcSSimon Schubert struct ui_out;
214*5796c8dcSSimon Schubert typedef int (catch_exceptions_ftype) (struct ui_out *ui_out, void *args);
215*5796c8dcSSimon Schubert extern int catch_exceptions (struct ui_out *uiout,
216*5796c8dcSSimon Schubert 			     catch_exceptions_ftype *func, void *func_args,
217*5796c8dcSSimon Schubert 			     return_mask mask);
218*5796c8dcSSimon Schubert typedef void (catch_exception_ftype) (struct ui_out *ui_out, void *args);
219*5796c8dcSSimon Schubert extern int catch_exceptions_with_msg (struct ui_out *uiout,
220*5796c8dcSSimon Schubert 			     	      catch_exceptions_ftype *func,
221*5796c8dcSSimon Schubert 			     	      void *func_args,
222*5796c8dcSSimon Schubert 			     	      char **gdberrmsg,
223*5796c8dcSSimon Schubert 				      return_mask mask);
224*5796c8dcSSimon Schubert 
225*5796c8dcSSimon Schubert /* This function, in addition, suppresses the printing of the captured
226*5796c8dcSSimon Schubert    error message.  It's up to the client to print it.  */
227*5796c8dcSSimon Schubert 
228*5796c8dcSSimon Schubert extern struct gdb_exception catch_exception (struct ui_out *uiout,
229*5796c8dcSSimon Schubert 					     catch_exception_ftype *func,
230*5796c8dcSSimon Schubert 					     void *func_args,
231*5796c8dcSSimon Schubert 					     return_mask mask);
232*5796c8dcSSimon Schubert 
233*5796c8dcSSimon Schubert /* If CATCH_ERRORS_FTYPE throws an error, catch_errors() returns zero
234*5796c8dcSSimon Schubert    otherwize the result from CATCH_ERRORS_FTYPE is returned. It is
235*5796c8dcSSimon Schubert    probably useful for CATCH_ERRORS_FTYPE to always return a non-zero
236*5796c8dcSSimon Schubert    value. It's unfortunate that, catch_errors() does not return an
237*5796c8dcSSimon Schubert    indication of the exact exception that it caught - quit_flag might
238*5796c8dcSSimon Schubert    help.
239*5796c8dcSSimon Schubert 
240*5796c8dcSSimon Schubert    This function is superseded by catch_exceptions().  */
241*5796c8dcSSimon Schubert 
242*5796c8dcSSimon Schubert typedef int (catch_errors_ftype) (void *);
243*5796c8dcSSimon Schubert extern int catch_errors (catch_errors_ftype *, void *, char *, return_mask);
244*5796c8dcSSimon Schubert 
245*5796c8dcSSimon Schubert /* Template to catch_errors() that wraps calls to command
246*5796c8dcSSimon Schubert    functions. */
247*5796c8dcSSimon Schubert 
248*5796c8dcSSimon Schubert typedef void (catch_command_errors_ftype) (char *, int);
249*5796c8dcSSimon Schubert extern int catch_command_errors (catch_command_errors_ftype *func, char *command, int from_tty, return_mask);
250*5796c8dcSSimon Schubert 
251*5796c8dcSSimon Schubert #endif
252