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