xref: /dflybsd-src/contrib/gdb-7/gdb/exceptions.h (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Exception (throw catch) mechanism, for GDB, the GNU debugger.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 1986-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert #ifndef EXCEPTIONS_H
215796c8dcSSimon Schubert #define EXCEPTIONS_H
225796c8dcSSimon Schubert 
235796c8dcSSimon Schubert #include "ui-out.h"
245796c8dcSSimon Schubert #include <setjmp.h>
255796c8dcSSimon Schubert 
265796c8dcSSimon Schubert /* Reasons for calling throw_exceptions().  NOTE: all reason values
275796c8dcSSimon Schubert    must be less than zero.  enum value 0 is reserved for internal use
285796c8dcSSimon Schubert    as the return value from an initial setjmp().  The function
295796c8dcSSimon Schubert    catch_exceptions() reserves values >= 0 as legal results from its
305796c8dcSSimon Schubert    wrapped function.  */
315796c8dcSSimon Schubert 
325796c8dcSSimon Schubert enum return_reason
335796c8dcSSimon Schubert   {
345796c8dcSSimon Schubert     /* User interrupt.  */
355796c8dcSSimon Schubert     RETURN_QUIT = -2,
365796c8dcSSimon Schubert     /* Any other error.  */
375796c8dcSSimon Schubert     RETURN_ERROR
385796c8dcSSimon Schubert   };
395796c8dcSSimon Schubert 
405796c8dcSSimon Schubert #define RETURN_MASK(reason)	(1 << (int)(-reason))
415796c8dcSSimon Schubert #define RETURN_MASK_QUIT	RETURN_MASK (RETURN_QUIT)
425796c8dcSSimon Schubert #define RETURN_MASK_ERROR	RETURN_MASK (RETURN_ERROR)
435796c8dcSSimon Schubert #define RETURN_MASK_ALL		(RETURN_MASK_QUIT | RETURN_MASK_ERROR)
445796c8dcSSimon Schubert typedef int return_mask;
455796c8dcSSimon Schubert 
465796c8dcSSimon Schubert /* Describe all exceptions.  */
475796c8dcSSimon Schubert 
485796c8dcSSimon Schubert enum errors {
495796c8dcSSimon Schubert   GDB_NO_ERROR,
50c50c785cSJohn Marino 
515796c8dcSSimon Schubert   /* Any generic error, the corresponding text is in
525796c8dcSSimon Schubert      exception.message.  */
535796c8dcSSimon Schubert   GENERIC_ERROR,
54c50c785cSJohn Marino 
55c50c785cSJohn Marino   /* Something requested was not found.  */
565796c8dcSSimon Schubert   NOT_FOUND_ERROR,
575796c8dcSSimon Schubert 
585796c8dcSSimon Schubert   /* Thread library lacks support necessary for finding thread local
595796c8dcSSimon Schubert      storage.  */
605796c8dcSSimon Schubert   TLS_NO_LIBRARY_SUPPORT_ERROR,
615796c8dcSSimon Schubert 
625796c8dcSSimon Schubert   /* Load module not found while attempting to find thread local storage.  */
635796c8dcSSimon Schubert   TLS_LOAD_MODULE_NOT_FOUND_ERROR,
645796c8dcSSimon Schubert 
655796c8dcSSimon Schubert   /* Thread local storage has not been allocated yet.  */
665796c8dcSSimon Schubert   TLS_NOT_ALLOCATED_YET_ERROR,
675796c8dcSSimon Schubert 
685796c8dcSSimon Schubert   /* Something else went wrong while attempting to find thread local
695796c8dcSSimon Schubert      storage.  The ``struct gdb_exception'' message field provides
705796c8dcSSimon Schubert      more detail.  */
715796c8dcSSimon Schubert   TLS_GENERIC_ERROR,
725796c8dcSSimon Schubert 
735796c8dcSSimon Schubert   /* Problem parsing an XML document.  */
745796c8dcSSimon Schubert   XML_PARSE_ERROR,
755796c8dcSSimon Schubert 
765796c8dcSSimon Schubert   /* Error accessing memory.  */
775796c8dcSSimon Schubert   MEMORY_ERROR,
785796c8dcSSimon Schubert 
79cf7f2e2dSJohn Marino   /* Feature is not supported in this copy of GDB.  */
80cf7f2e2dSJohn Marino   UNSUPPORTED_ERROR,
81cf7f2e2dSJohn Marino 
82c50c785cSJohn Marino   /* Value not available.  E.g., a register was not collected in a
83c50c785cSJohn Marino      traceframe.  */
84c50c785cSJohn Marino   NOT_AVAILABLE_ERROR,
85c50c785cSJohn Marino 
86a45ae5f8SJohn Marino   /* DW_OP_GNU_entry_value resolving failed.  */
87a45ae5f8SJohn Marino   NO_ENTRY_VALUE_ERROR,
88a45ae5f8SJohn Marino 
89*ef5ccd6cSJohn Marino   /* Target throwing an error has been closed.  Current command should be
90*ef5ccd6cSJohn Marino      aborted as the inferior state is no longer valid.  */
91*ef5ccd6cSJohn Marino   TARGET_CLOSE_ERROR,
92*ef5ccd6cSJohn Marino 
935796c8dcSSimon Schubert   /* Add more errors here.  */
945796c8dcSSimon Schubert   NR_ERRORS
955796c8dcSSimon Schubert };
965796c8dcSSimon Schubert 
975796c8dcSSimon Schubert struct gdb_exception
985796c8dcSSimon Schubert {
995796c8dcSSimon Schubert   enum return_reason reason;
1005796c8dcSSimon Schubert   enum errors error;
1015796c8dcSSimon Schubert   const char *message;
1025796c8dcSSimon Schubert };
1035796c8dcSSimon Schubert 
1045796c8dcSSimon Schubert /* A pre-defined non-exception.  */
1055796c8dcSSimon Schubert extern const struct gdb_exception exception_none;
1065796c8dcSSimon Schubert 
1075796c8dcSSimon Schubert /* Wrap set/long jmp so that it's more portable (internal to
1085796c8dcSSimon Schubert    exceptions).  */
1095796c8dcSSimon Schubert 
1105796c8dcSSimon Schubert #if defined(HAVE_SIGSETJMP)
1115796c8dcSSimon Schubert #define EXCEPTIONS_SIGJMP_BUF		sigjmp_buf
1125796c8dcSSimon Schubert #define EXCEPTIONS_SIGSETJMP(buf)	sigsetjmp((buf), 1)
1135796c8dcSSimon Schubert #define EXCEPTIONS_SIGLONGJMP(buf,val)	siglongjmp((buf), (val))
1145796c8dcSSimon Schubert #else
1155796c8dcSSimon Schubert #define EXCEPTIONS_SIGJMP_BUF		jmp_buf
1165796c8dcSSimon Schubert #define EXCEPTIONS_SIGSETJMP(buf)	setjmp(buf)
1175796c8dcSSimon Schubert #define EXCEPTIONS_SIGLONGJMP(buf,val)	longjmp((buf), (val))
1185796c8dcSSimon Schubert #endif
1195796c8dcSSimon Schubert 
1205796c8dcSSimon Schubert /* Functions to drive the exceptions state m/c (internal to
1215796c8dcSSimon Schubert    exceptions).  */
122a45ae5f8SJohn Marino EXCEPTIONS_SIGJMP_BUF *exceptions_state_mc_init (volatile struct
123c50c785cSJohn Marino 						 gdb_exception *exception,
1245796c8dcSSimon Schubert 						 return_mask mask);
1255796c8dcSSimon Schubert int exceptions_state_mc_action_iter (void);
1265796c8dcSSimon Schubert int exceptions_state_mc_action_iter_1 (void);
1275796c8dcSSimon Schubert 
1285796c8dcSSimon Schubert /* Macro to wrap up standard try/catch behavior.
1295796c8dcSSimon Schubert 
1305796c8dcSSimon Schubert    The double loop lets us correctly handle code "break"ing out of the
1315796c8dcSSimon Schubert    try catch block.  (It works as the "break" only exits the inner
1325796c8dcSSimon Schubert    "while" loop, the outer for loop detects this handling it
1335796c8dcSSimon Schubert    correctly.)  Of course "return" and "goto" are not so lucky.
1345796c8dcSSimon Schubert 
1355796c8dcSSimon Schubert    For instance:
1365796c8dcSSimon Schubert 
1375796c8dcSSimon Schubert    *INDENT-OFF*
1385796c8dcSSimon Schubert 
1395796c8dcSSimon Schubert    volatile struct gdb_exception e;
1405796c8dcSSimon Schubert    TRY_CATCH (e, RETURN_MASK_ERROR)
1415796c8dcSSimon Schubert      {
1425796c8dcSSimon Schubert      }
1435796c8dcSSimon Schubert    switch (e.reason)
1445796c8dcSSimon Schubert      {
1455796c8dcSSimon Schubert      case RETURN_ERROR: ...
1465796c8dcSSimon Schubert      }
1475796c8dcSSimon Schubert 
1485796c8dcSSimon Schubert   */
1495796c8dcSSimon Schubert 
1505796c8dcSSimon Schubert #define TRY_CATCH(EXCEPTION,MASK) \
1515796c8dcSSimon Schubert      { \
1525796c8dcSSimon Schubert        EXCEPTIONS_SIGJMP_BUF *buf = \
153a45ae5f8SJohn Marino 	 exceptions_state_mc_init (&(EXCEPTION), (MASK)); \
1545796c8dcSSimon Schubert        EXCEPTIONS_SIGSETJMP (*buf); \
1555796c8dcSSimon Schubert      } \
1565796c8dcSSimon Schubert      while (exceptions_state_mc_action_iter ()) \
1575796c8dcSSimon Schubert        while (exceptions_state_mc_action_iter_1 ())
1585796c8dcSSimon Schubert 
1595796c8dcSSimon Schubert /* *INDENT-ON* */
1605796c8dcSSimon Schubert 
1615796c8dcSSimon Schubert 
1625796c8dcSSimon Schubert /* If E is an exception, print it's error message on the specified
163c50c785cSJohn Marino    stream.  For _fprintf, prefix the message with PREFIX...  */
1645796c8dcSSimon Schubert extern void exception_print (struct ui_file *file, struct gdb_exception e);
1655796c8dcSSimon Schubert extern void exception_fprintf (struct ui_file *file, struct gdb_exception e,
1665796c8dcSSimon Schubert 			       const char *prefix,
167cf7f2e2dSJohn Marino 			       ...) ATTRIBUTE_PRINTF (3, 4);
1685796c8dcSSimon Schubert 
1695796c8dcSSimon Schubert /* Throw an exception (as described by "struct gdb_exception").  Will
1705796c8dcSSimon Schubert    execute a LONG JUMP to the inner most containing exception handler
1715796c8dcSSimon Schubert    established using catch_exceptions() (or similar).
1725796c8dcSSimon Schubert 
1735796c8dcSSimon Schubert    Code normally throws an exception using error() et.al.  For various
1745796c8dcSSimon Schubert    reaons, GDB also contains code that throws an exception directly.
1755796c8dcSSimon Schubert    For instance, the remote*.c targets contain CNTRL-C signal handlers
1765796c8dcSSimon Schubert    that propogate the QUIT event up the exception chain.  ``This could
1775796c8dcSSimon Schubert    be a good thing or a dangerous thing.'' -- the Existential
1785796c8dcSSimon Schubert    Wombat.  */
1795796c8dcSSimon Schubert 
180c50c785cSJohn Marino extern void throw_exception (struct gdb_exception exception)
181c50c785cSJohn Marino      ATTRIBUTE_NORETURN;
182cf7f2e2dSJohn Marino extern void throw_verror (enum errors, const char *fmt, va_list ap)
183cf7f2e2dSJohn Marino      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0);
184cf7f2e2dSJohn Marino extern void throw_vfatal (const char *fmt, va_list ap)
185cf7f2e2dSJohn Marino      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0);
186cf7f2e2dSJohn Marino extern void throw_error (enum errors error, const char *fmt, ...)
187cf7f2e2dSJohn Marino      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3);
1885796c8dcSSimon Schubert 
189a45ae5f8SJohn Marino /* Instead of deprecated_throw_reason, code should use
190a45ae5f8SJohn Marino    throw_exception.  */
191cf7f2e2dSJohn Marino extern void deprecated_throw_reason (enum return_reason reason)
192cf7f2e2dSJohn Marino      ATTRIBUTE_NORETURN;
1935796c8dcSSimon Schubert 
1945796c8dcSSimon Schubert /* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
1955796c8dcSSimon Schubert    handler.  If an exception (enum return_reason) is thrown using
1965796c8dcSSimon Schubert    throw_exception() than all cleanups installed since
1975796c8dcSSimon Schubert    catch_exceptions() was entered are invoked, the (-ve) exception
1985796c8dcSSimon Schubert    value is then returned by catch_exceptions.  If FUNC() returns
1995796c8dcSSimon Schubert    normally (with a positive or zero return value) then that value is
2005796c8dcSSimon Schubert    returned by catch_exceptions().  It is an internal_error() for
2015796c8dcSSimon Schubert    FUNC() to return a negative value.
2025796c8dcSSimon Schubert 
2035796c8dcSSimon Schubert    For the period of the FUNC() call: UIOUT is installed as the output
2045796c8dcSSimon Schubert    builder; ERRSTRING is installed as the error/quit message; and a
2055796c8dcSSimon Schubert    new cleanup_chain is established.  The old values are restored
2065796c8dcSSimon Schubert    before catch_exceptions() returns.
2075796c8dcSSimon Schubert 
2085796c8dcSSimon Schubert    The variant catch_exceptions_with_msg() is the same as
2095796c8dcSSimon Schubert    catch_exceptions() but adds the ability to return an allocated
2105796c8dcSSimon Schubert    copy of the gdb error message.  This is used when a silent error is
2115796c8dcSSimon Schubert    issued and the caller wants to manually issue the error message.
2125796c8dcSSimon Schubert 
2135796c8dcSSimon Schubert    MASK specifies what to catch; it is normally set to
2145796c8dcSSimon Schubert    RETURN_MASK_ALL, if for no other reason than that the code which
2155796c8dcSSimon Schubert    calls catch_errors might not be set up to deal with a quit which
2165796c8dcSSimon Schubert    isn't caught.  But if the code can deal with it, it generally
2175796c8dcSSimon Schubert    should be RETURN_MASK_ERROR, unless for some reason it is more
2185796c8dcSSimon Schubert    useful to abort only the portion of the operation inside the
2195796c8dcSSimon Schubert    catch_errors.  Note that quit should return to the command line
2205796c8dcSSimon Schubert    fairly quickly, even if some further processing is being done.
2215796c8dcSSimon Schubert 
2225796c8dcSSimon Schubert    FIXME; cagney/2001-08-13: The need to override the global UIOUT
2235796c8dcSSimon Schubert    builder variable should just go away.
2245796c8dcSSimon Schubert 
2255796c8dcSSimon Schubert    This function supersedes catch_errors().
2265796c8dcSSimon Schubert 
2275796c8dcSSimon Schubert    This function uses SETJMP() and LONGJUMP().  */
2285796c8dcSSimon Schubert 
2295796c8dcSSimon Schubert struct ui_out;
2305796c8dcSSimon Schubert typedef int (catch_exceptions_ftype) (struct ui_out *ui_out, void *args);
2315796c8dcSSimon Schubert extern int catch_exceptions (struct ui_out *uiout,
2325796c8dcSSimon Schubert 			     catch_exceptions_ftype *func, void *func_args,
2335796c8dcSSimon Schubert 			     return_mask mask);
2345796c8dcSSimon Schubert typedef void (catch_exception_ftype) (struct ui_out *ui_out, void *args);
2355796c8dcSSimon Schubert extern int catch_exceptions_with_msg (struct ui_out *uiout,
2365796c8dcSSimon Schubert 			     	      catch_exceptions_ftype *func,
2375796c8dcSSimon Schubert 			     	      void *func_args,
2385796c8dcSSimon Schubert 			     	      char **gdberrmsg,
2395796c8dcSSimon Schubert 				      return_mask mask);
2405796c8dcSSimon Schubert 
2415796c8dcSSimon Schubert /* If CATCH_ERRORS_FTYPE throws an error, catch_errors() returns zero
2425796c8dcSSimon Schubert    otherwize the result from CATCH_ERRORS_FTYPE is returned.  It is
2435796c8dcSSimon Schubert    probably useful for CATCH_ERRORS_FTYPE to always return a non-zero
2445796c8dcSSimon Schubert    value.  It's unfortunate that, catch_errors() does not return an
2455796c8dcSSimon Schubert    indication of the exact exception that it caught - quit_flag might
2465796c8dcSSimon Schubert    help.
2475796c8dcSSimon Schubert 
2485796c8dcSSimon Schubert    This function is superseded by catch_exceptions().  */
2495796c8dcSSimon Schubert 
2505796c8dcSSimon Schubert typedef int (catch_errors_ftype) (void *);
2515796c8dcSSimon Schubert extern int catch_errors (catch_errors_ftype *, void *, char *, return_mask);
2525796c8dcSSimon Schubert 
2535796c8dcSSimon Schubert /* Template to catch_errors() that wraps calls to command
2545796c8dcSSimon Schubert    functions.  */
2555796c8dcSSimon Schubert 
2565796c8dcSSimon Schubert typedef void (catch_command_errors_ftype) (char *, int);
257c50c785cSJohn Marino extern int catch_command_errors (catch_command_errors_ftype *func,
258c50c785cSJohn Marino 				 char *command, int from_tty, return_mask);
2595796c8dcSSimon Schubert 
2605796c8dcSSimon Schubert #endif
261