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