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*cf7f2e2dSJohn Marino 2009, 2010 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, 525796c8dcSSimon Schubert /* Any generic error, the corresponding text is in 535796c8dcSSimon Schubert exception.message. */ 545796c8dcSSimon Schubert GENERIC_ERROR, 555796c8dcSSimon Schubert NOT_FOUND_ERROR, 565796c8dcSSimon Schubert 575796c8dcSSimon Schubert /* Thread library lacks support necessary for finding thread local 585796c8dcSSimon Schubert storage. */ 595796c8dcSSimon Schubert TLS_NO_LIBRARY_SUPPORT_ERROR, 605796c8dcSSimon Schubert 615796c8dcSSimon Schubert /* Load module not found while attempting to find thread local storage. */ 625796c8dcSSimon Schubert TLS_LOAD_MODULE_NOT_FOUND_ERROR, 635796c8dcSSimon Schubert 645796c8dcSSimon Schubert /* Thread local storage has not been allocated yet. */ 655796c8dcSSimon Schubert TLS_NOT_ALLOCATED_YET_ERROR, 665796c8dcSSimon Schubert 675796c8dcSSimon Schubert /* Something else went wrong while attempting to find thread local 685796c8dcSSimon Schubert storage. The ``struct gdb_exception'' message field provides 695796c8dcSSimon Schubert more detail. */ 705796c8dcSSimon Schubert TLS_GENERIC_ERROR, 715796c8dcSSimon Schubert 725796c8dcSSimon Schubert /* Problem parsing an XML document. */ 735796c8dcSSimon Schubert XML_PARSE_ERROR, 745796c8dcSSimon Schubert 755796c8dcSSimon Schubert /* Error accessing memory. */ 765796c8dcSSimon Schubert MEMORY_ERROR, 775796c8dcSSimon Schubert 78*cf7f2e2dSJohn Marino /* Feature is not supported in this copy of GDB. */ 79*cf7f2e2dSJohn Marino UNSUPPORTED_ERROR, 80*cf7f2e2dSJohn Marino 815796c8dcSSimon Schubert /* Add more errors here. */ 825796c8dcSSimon Schubert NR_ERRORS 835796c8dcSSimon Schubert }; 845796c8dcSSimon Schubert 855796c8dcSSimon Schubert struct gdb_exception 865796c8dcSSimon Schubert { 875796c8dcSSimon Schubert enum return_reason reason; 885796c8dcSSimon Schubert enum errors error; 895796c8dcSSimon Schubert const char *message; 905796c8dcSSimon Schubert }; 915796c8dcSSimon Schubert 925796c8dcSSimon Schubert /* A pre-defined non-exception. */ 935796c8dcSSimon Schubert extern const struct gdb_exception exception_none; 945796c8dcSSimon Schubert 955796c8dcSSimon Schubert /* Wrap set/long jmp so that it's more portable (internal to 965796c8dcSSimon Schubert exceptions). */ 975796c8dcSSimon Schubert 985796c8dcSSimon Schubert #if defined(HAVE_SIGSETJMP) 995796c8dcSSimon Schubert #define EXCEPTIONS_SIGJMP_BUF sigjmp_buf 1005796c8dcSSimon Schubert #define EXCEPTIONS_SIGSETJMP(buf) sigsetjmp((buf), 1) 1015796c8dcSSimon Schubert #define EXCEPTIONS_SIGLONGJMP(buf,val) siglongjmp((buf), (val)) 1025796c8dcSSimon Schubert #else 1035796c8dcSSimon Schubert #define EXCEPTIONS_SIGJMP_BUF jmp_buf 1045796c8dcSSimon Schubert #define EXCEPTIONS_SIGSETJMP(buf) setjmp(buf) 1055796c8dcSSimon Schubert #define EXCEPTIONS_SIGLONGJMP(buf,val) longjmp((buf), (val)) 1065796c8dcSSimon Schubert #endif 1075796c8dcSSimon Schubert 1085796c8dcSSimon Schubert /* Functions to drive the exceptions state m/c (internal to 1095796c8dcSSimon Schubert exceptions). */ 1105796c8dcSSimon Schubert EXCEPTIONS_SIGJMP_BUF *exceptions_state_mc_init (struct ui_out *func_uiout, 1115796c8dcSSimon Schubert volatile struct gdb_exception * 1125796c8dcSSimon Schubert exception, 1135796c8dcSSimon Schubert return_mask mask); 1145796c8dcSSimon Schubert int exceptions_state_mc_action_iter (void); 1155796c8dcSSimon Schubert int exceptions_state_mc_action_iter_1 (void); 1165796c8dcSSimon Schubert 1175796c8dcSSimon Schubert /* Macro to wrap up standard try/catch behavior. 1185796c8dcSSimon Schubert 1195796c8dcSSimon Schubert The double loop lets us correctly handle code "break"ing out of the 1205796c8dcSSimon Schubert try catch block. (It works as the "break" only exits the inner 1215796c8dcSSimon Schubert "while" loop, the outer for loop detects this handling it 1225796c8dcSSimon Schubert correctly.) Of course "return" and "goto" are not so lucky. 1235796c8dcSSimon Schubert 1245796c8dcSSimon Schubert For instance: 1255796c8dcSSimon Schubert 1265796c8dcSSimon Schubert *INDENT-OFF* 1275796c8dcSSimon Schubert 1285796c8dcSSimon Schubert volatile struct gdb_exception e; 1295796c8dcSSimon Schubert TRY_CATCH (e, RETURN_MASK_ERROR) 1305796c8dcSSimon Schubert { 1315796c8dcSSimon Schubert } 1325796c8dcSSimon Schubert switch (e.reason) 1335796c8dcSSimon Schubert { 1345796c8dcSSimon Schubert case RETURN_ERROR: ... 1355796c8dcSSimon Schubert } 1365796c8dcSSimon Schubert 1375796c8dcSSimon Schubert */ 1385796c8dcSSimon Schubert 1395796c8dcSSimon Schubert #define TRY_CATCH(EXCEPTION,MASK) \ 1405796c8dcSSimon Schubert { \ 1415796c8dcSSimon Schubert EXCEPTIONS_SIGJMP_BUF *buf = \ 1425796c8dcSSimon Schubert exceptions_state_mc_init (uiout, &(EXCEPTION), (MASK)); \ 1435796c8dcSSimon Schubert EXCEPTIONS_SIGSETJMP (*buf); \ 1445796c8dcSSimon Schubert } \ 1455796c8dcSSimon Schubert while (exceptions_state_mc_action_iter ()) \ 1465796c8dcSSimon Schubert while (exceptions_state_mc_action_iter_1 ()) 1475796c8dcSSimon Schubert 1485796c8dcSSimon Schubert /* *INDENT-ON* */ 1495796c8dcSSimon Schubert 1505796c8dcSSimon Schubert 1515796c8dcSSimon Schubert /* If E is an exception, print it's error message on the specified 1525796c8dcSSimon Schubert stream. for _fprintf, prefix the message with PREFIX... */ 1535796c8dcSSimon Schubert extern void exception_print (struct ui_file *file, struct gdb_exception e); 1545796c8dcSSimon Schubert extern void exception_fprintf (struct ui_file *file, struct gdb_exception e, 1555796c8dcSSimon Schubert const char *prefix, 156*cf7f2e2dSJohn Marino ...) ATTRIBUTE_PRINTF (3, 4); 1575796c8dcSSimon Schubert 1585796c8dcSSimon Schubert /* Throw an exception (as described by "struct gdb_exception"). Will 1595796c8dcSSimon Schubert execute a LONG JUMP to the inner most containing exception handler 1605796c8dcSSimon Schubert established using catch_exceptions() (or similar). 1615796c8dcSSimon Schubert 1625796c8dcSSimon Schubert Code normally throws an exception using error() et.al. For various 1635796c8dcSSimon Schubert reaons, GDB also contains code that throws an exception directly. 1645796c8dcSSimon Schubert For instance, the remote*.c targets contain CNTRL-C signal handlers 1655796c8dcSSimon Schubert that propogate the QUIT event up the exception chain. ``This could 1665796c8dcSSimon Schubert be a good thing or a dangerous thing.'' -- the Existential 1675796c8dcSSimon Schubert Wombat. */ 1685796c8dcSSimon Schubert 169*cf7f2e2dSJohn Marino extern void throw_exception (struct gdb_exception exception) ATTRIBUTE_NORETURN; 170*cf7f2e2dSJohn Marino extern void throw_verror (enum errors, const char *fmt, va_list ap) 171*cf7f2e2dSJohn Marino ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0); 172*cf7f2e2dSJohn Marino extern void throw_vfatal (const char *fmt, va_list ap) 173*cf7f2e2dSJohn Marino ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0); 174*cf7f2e2dSJohn Marino extern void throw_error (enum errors error, const char *fmt, ...) 175*cf7f2e2dSJohn Marino ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3); 1765796c8dcSSimon Schubert 1775796c8dcSSimon Schubert /* Instead of deprecated_throw_reason, code should use catch_exception 1785796c8dcSSimon Schubert and throw_exception. */ 179*cf7f2e2dSJohn Marino extern void deprecated_throw_reason (enum return_reason reason) 180*cf7f2e2dSJohn Marino ATTRIBUTE_NORETURN; 1815796c8dcSSimon Schubert 1825796c8dcSSimon Schubert /* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception 1835796c8dcSSimon Schubert handler. If an exception (enum return_reason) is thrown using 1845796c8dcSSimon Schubert throw_exception() than all cleanups installed since 1855796c8dcSSimon Schubert catch_exceptions() was entered are invoked, the (-ve) exception 1865796c8dcSSimon Schubert value is then returned by catch_exceptions. If FUNC() returns 1875796c8dcSSimon Schubert normally (with a positive or zero return value) then that value is 1885796c8dcSSimon Schubert returned by catch_exceptions(). It is an internal_error() for 1895796c8dcSSimon Schubert FUNC() to return a negative value. 1905796c8dcSSimon Schubert 1915796c8dcSSimon Schubert For the period of the FUNC() call: UIOUT is installed as the output 1925796c8dcSSimon Schubert builder; ERRSTRING is installed as the error/quit message; and a 1935796c8dcSSimon Schubert new cleanup_chain is established. The old values are restored 1945796c8dcSSimon Schubert before catch_exceptions() returns. 1955796c8dcSSimon Schubert 1965796c8dcSSimon Schubert The variant catch_exceptions_with_msg() is the same as 1975796c8dcSSimon Schubert catch_exceptions() but adds the ability to return an allocated 1985796c8dcSSimon Schubert copy of the gdb error message. This is used when a silent error is 1995796c8dcSSimon Schubert issued and the caller wants to manually issue the error message. 2005796c8dcSSimon Schubert 2015796c8dcSSimon Schubert MASK specifies what to catch; it is normally set to 2025796c8dcSSimon Schubert RETURN_MASK_ALL, if for no other reason than that the code which 2035796c8dcSSimon Schubert calls catch_errors might not be set up to deal with a quit which 2045796c8dcSSimon Schubert isn't caught. But if the code can deal with it, it generally 2055796c8dcSSimon Schubert should be RETURN_MASK_ERROR, unless for some reason it is more 2065796c8dcSSimon Schubert useful to abort only the portion of the operation inside the 2075796c8dcSSimon Schubert catch_errors. Note that quit should return to the command line 2085796c8dcSSimon Schubert fairly quickly, even if some further processing is being done. 2095796c8dcSSimon Schubert 2105796c8dcSSimon Schubert FIXME; cagney/2001-08-13: The need to override the global UIOUT 2115796c8dcSSimon Schubert builder variable should just go away. 2125796c8dcSSimon Schubert 2135796c8dcSSimon Schubert This function supersedes catch_errors(). 2145796c8dcSSimon Schubert 2155796c8dcSSimon Schubert This function uses SETJMP() and LONGJUMP(). */ 2165796c8dcSSimon Schubert 2175796c8dcSSimon Schubert struct ui_out; 2185796c8dcSSimon Schubert typedef int (catch_exceptions_ftype) (struct ui_out *ui_out, void *args); 2195796c8dcSSimon Schubert extern int catch_exceptions (struct ui_out *uiout, 2205796c8dcSSimon Schubert catch_exceptions_ftype *func, void *func_args, 2215796c8dcSSimon Schubert return_mask mask); 2225796c8dcSSimon Schubert typedef void (catch_exception_ftype) (struct ui_out *ui_out, void *args); 2235796c8dcSSimon Schubert extern int catch_exceptions_with_msg (struct ui_out *uiout, 2245796c8dcSSimon Schubert catch_exceptions_ftype *func, 2255796c8dcSSimon Schubert void *func_args, 2265796c8dcSSimon Schubert char **gdberrmsg, 2275796c8dcSSimon Schubert return_mask mask); 2285796c8dcSSimon Schubert 2295796c8dcSSimon Schubert /* This function, in addition, suppresses the printing of the captured 2305796c8dcSSimon Schubert error message. It's up to the client to print it. */ 2315796c8dcSSimon Schubert 2325796c8dcSSimon Schubert extern struct gdb_exception catch_exception (struct ui_out *uiout, 2335796c8dcSSimon Schubert catch_exception_ftype *func, 2345796c8dcSSimon Schubert void *func_args, 2355796c8dcSSimon Schubert return_mask mask); 2365796c8dcSSimon Schubert 2375796c8dcSSimon Schubert /* If CATCH_ERRORS_FTYPE throws an error, catch_errors() returns zero 2385796c8dcSSimon Schubert otherwize the result from CATCH_ERRORS_FTYPE is returned. It is 2395796c8dcSSimon Schubert probably useful for CATCH_ERRORS_FTYPE to always return a non-zero 2405796c8dcSSimon Schubert value. It's unfortunate that, catch_errors() does not return an 2415796c8dcSSimon Schubert indication of the exact exception that it caught - quit_flag might 2425796c8dcSSimon Schubert help. 2435796c8dcSSimon Schubert 2445796c8dcSSimon Schubert This function is superseded by catch_exceptions(). */ 2455796c8dcSSimon Schubert 2465796c8dcSSimon Schubert typedef int (catch_errors_ftype) (void *); 2475796c8dcSSimon Schubert extern int catch_errors (catch_errors_ftype *, void *, char *, return_mask); 2485796c8dcSSimon Schubert 2495796c8dcSSimon Schubert /* Template to catch_errors() that wraps calls to command 2505796c8dcSSimon Schubert functions. */ 2515796c8dcSSimon Schubert 2525796c8dcSSimon Schubert typedef void (catch_command_errors_ftype) (char *, int); 2535796c8dcSSimon Schubert extern int catch_command_errors (catch_command_errors_ftype *func, char *command, int from_tty, return_mask); 2545796c8dcSSimon Schubert 2555796c8dcSSimon Schubert #endif 256