15796c8dcSSimon Schubert /* Exception (throw catch) mechanism, for GDB, the GNU debugger. 25796c8dcSSimon Schubert 3*a45ae5f8SJohn Marino Copyright (C) 1986, 1988-2012 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 86*a45ae5f8SJohn Marino /* DW_OP_GNU_entry_value resolving failed. */ 87*a45ae5f8SJohn Marino NO_ENTRY_VALUE_ERROR, 88*a45ae5f8SJohn Marino 895796c8dcSSimon Schubert /* Add more errors here. */ 905796c8dcSSimon Schubert NR_ERRORS 915796c8dcSSimon Schubert }; 925796c8dcSSimon Schubert 935796c8dcSSimon Schubert struct gdb_exception 945796c8dcSSimon Schubert { 955796c8dcSSimon Schubert enum return_reason reason; 965796c8dcSSimon Schubert enum errors error; 975796c8dcSSimon Schubert const char *message; 985796c8dcSSimon Schubert }; 995796c8dcSSimon Schubert 1005796c8dcSSimon Schubert /* A pre-defined non-exception. */ 1015796c8dcSSimon Schubert extern const struct gdb_exception exception_none; 1025796c8dcSSimon Schubert 1035796c8dcSSimon Schubert /* Wrap set/long jmp so that it's more portable (internal to 1045796c8dcSSimon Schubert exceptions). */ 1055796c8dcSSimon Schubert 1065796c8dcSSimon Schubert #if defined(HAVE_SIGSETJMP) 1075796c8dcSSimon Schubert #define EXCEPTIONS_SIGJMP_BUF sigjmp_buf 1085796c8dcSSimon Schubert #define EXCEPTIONS_SIGSETJMP(buf) sigsetjmp((buf), 1) 1095796c8dcSSimon Schubert #define EXCEPTIONS_SIGLONGJMP(buf,val) siglongjmp((buf), (val)) 1105796c8dcSSimon Schubert #else 1115796c8dcSSimon Schubert #define EXCEPTIONS_SIGJMP_BUF jmp_buf 1125796c8dcSSimon Schubert #define EXCEPTIONS_SIGSETJMP(buf) setjmp(buf) 1135796c8dcSSimon Schubert #define EXCEPTIONS_SIGLONGJMP(buf,val) longjmp((buf), (val)) 1145796c8dcSSimon Schubert #endif 1155796c8dcSSimon Schubert 1165796c8dcSSimon Schubert /* Functions to drive the exceptions state m/c (internal to 1175796c8dcSSimon Schubert exceptions). */ 118*a45ae5f8SJohn Marino EXCEPTIONS_SIGJMP_BUF *exceptions_state_mc_init (volatile struct 119c50c785cSJohn 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 = \ 149*a45ae5f8SJohn Marino exceptions_state_mc_init (&(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 159c50c785cSJohn 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 176c50c785cSJohn Marino extern void throw_exception (struct gdb_exception exception) 177c50c785cSJohn 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 185*a45ae5f8SJohn Marino /* Instead of deprecated_throw_reason, code should use 186*a45ae5f8SJohn Marino 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 /* 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); 253c50c785cSJohn Marino extern int catch_command_errors (catch_command_errors_ftype *func, 254c50c785cSJohn Marino char *command, int from_tty, return_mask); 2555796c8dcSSimon Schubert 2565796c8dcSSimon Schubert #endif 257