GDB (API)
|
00001 /* Exception (throw catch) mechanism, for GDB, the GNU debugger. 00002 00003 Copyright (C) 1986-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #ifndef EXCEPTIONS_H 00021 #define EXCEPTIONS_H 00022 00023 #include "ui-out.h" 00024 #include <setjmp.h> 00025 00026 /* Reasons for calling throw_exceptions(). NOTE: all reason values 00027 must be less than zero. enum value 0 is reserved for internal use 00028 as the return value from an initial setjmp(). The function 00029 catch_exceptions() reserves values >= 0 as legal results from its 00030 wrapped function. */ 00031 00032 enum return_reason 00033 { 00034 /* User interrupt. */ 00035 RETURN_QUIT = -2, 00036 /* Any other error. */ 00037 RETURN_ERROR 00038 }; 00039 00040 #define RETURN_MASK(reason) (1 << (int)(-reason)) 00041 00042 typedef enum 00043 { 00044 RETURN_MASK_QUIT = RETURN_MASK (RETURN_QUIT), 00045 RETURN_MASK_ERROR = RETURN_MASK (RETURN_ERROR), 00046 RETURN_MASK_ALL = (RETURN_MASK_QUIT | RETURN_MASK_ERROR) 00047 } return_mask; 00048 00049 /* Describe all exceptions. */ 00050 00051 enum errors { 00052 GDB_NO_ERROR, 00053 00054 /* Any generic error, the corresponding text is in 00055 exception.message. */ 00056 GENERIC_ERROR, 00057 00058 /* Something requested was not found. */ 00059 NOT_FOUND_ERROR, 00060 00061 /* Thread library lacks support necessary for finding thread local 00062 storage. */ 00063 TLS_NO_LIBRARY_SUPPORT_ERROR, 00064 00065 /* Load module not found while attempting to find thread local storage. */ 00066 TLS_LOAD_MODULE_NOT_FOUND_ERROR, 00067 00068 /* Thread local storage has not been allocated yet. */ 00069 TLS_NOT_ALLOCATED_YET_ERROR, 00070 00071 /* Something else went wrong while attempting to find thread local 00072 storage. The ``struct gdb_exception'' message field provides 00073 more detail. */ 00074 TLS_GENERIC_ERROR, 00075 00076 /* Problem parsing an XML document. */ 00077 XML_PARSE_ERROR, 00078 00079 /* Error accessing memory. */ 00080 MEMORY_ERROR, 00081 00082 /* Feature is not supported in this copy of GDB. */ 00083 UNSUPPORTED_ERROR, 00084 00085 /* Value not available. E.g., a register was not collected in a 00086 traceframe. */ 00087 NOT_AVAILABLE_ERROR, 00088 00089 /* DW_OP_GNU_entry_value resolving failed. */ 00090 NO_ENTRY_VALUE_ERROR, 00091 00092 /* Target throwing an error has been closed. Current command should be 00093 aborted as the inferior state is no longer valid. */ 00094 TARGET_CLOSE_ERROR, 00095 00096 /* Add more errors here. */ 00097 NR_ERRORS 00098 }; 00099 00100 struct gdb_exception 00101 { 00102 enum return_reason reason; 00103 enum errors error; 00104 const char *message; 00105 }; 00106 00107 /* A pre-defined non-exception. */ 00108 extern const struct gdb_exception exception_none; 00109 00110 /* Wrap set/long jmp so that it's more portable (internal to 00111 exceptions). */ 00112 00113 #if defined(HAVE_SIGSETJMP) 00114 #define EXCEPTIONS_SIGJMP_BUF sigjmp_buf 00115 #define EXCEPTIONS_SIGSETJMP(buf) sigsetjmp((buf), 1) 00116 #define EXCEPTIONS_SIGLONGJMP(buf,val) siglongjmp((buf), (val)) 00117 #else 00118 #define EXCEPTIONS_SIGJMP_BUF jmp_buf 00119 #define EXCEPTIONS_SIGSETJMP(buf) setjmp(buf) 00120 #define EXCEPTIONS_SIGLONGJMP(buf,val) longjmp((buf), (val)) 00121 #endif 00122 00123 /* Functions to drive the exceptions state m/c (internal to 00124 exceptions). */ 00125 EXCEPTIONS_SIGJMP_BUF *exceptions_state_mc_init (volatile struct 00126 gdb_exception *exception, 00127 return_mask mask); 00128 int exceptions_state_mc_action_iter (void); 00129 int exceptions_state_mc_action_iter_1 (void); 00130 00131 /* Macro to wrap up standard try/catch behavior. 00132 00133 The double loop lets us correctly handle code "break"ing out of the 00134 try catch block. (It works as the "break" only exits the inner 00135 "while" loop, the outer for loop detects this handling it 00136 correctly.) Of course "return" and "goto" are not so lucky. 00137 00138 For instance: 00139 00140 *INDENT-OFF* 00141 00142 volatile struct gdb_exception e; 00143 TRY_CATCH (e, RETURN_MASK_ERROR) 00144 { 00145 } 00146 switch (e.reason) 00147 { 00148 case RETURN_ERROR: ... 00149 } 00150 00151 */ 00152 00153 #define TRY_CATCH(EXCEPTION,MASK) \ 00154 { \ 00155 EXCEPTIONS_SIGJMP_BUF *buf = \ 00156 exceptions_state_mc_init (&(EXCEPTION), (MASK)); \ 00157 EXCEPTIONS_SIGSETJMP (*buf); \ 00158 } \ 00159 while (exceptions_state_mc_action_iter ()) \ 00160 while (exceptions_state_mc_action_iter_1 ()) 00161 00162 /* *INDENT-ON* */ 00163 00164 00165 /* If E is an exception, print it's error message on the specified 00166 stream. For _fprintf, prefix the message with PREFIX... */ 00167 extern void exception_print (struct ui_file *file, struct gdb_exception e); 00168 extern void exception_fprintf (struct ui_file *file, struct gdb_exception e, 00169 const char *prefix, 00170 ...) ATTRIBUTE_PRINTF (3, 4); 00171 00172 /* Throw an exception (as described by "struct gdb_exception"). Will 00173 execute a LONG JUMP to the inner most containing exception handler 00174 established using catch_exceptions() (or similar). 00175 00176 Code normally throws an exception using error() et.al. For various 00177 reaons, GDB also contains code that throws an exception directly. 00178 For instance, the remote*.c targets contain CNTRL-C signal handlers 00179 that propogate the QUIT event up the exception chain. ``This could 00180 be a good thing or a dangerous thing.'' -- the Existential 00181 Wombat. */ 00182 00183 extern void throw_exception (struct gdb_exception exception) 00184 ATTRIBUTE_NORETURN; 00185 extern void throw_verror (enum errors, const char *fmt, va_list ap) 00186 ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0); 00187 extern void throw_vfatal (const char *fmt, va_list ap) 00188 ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0); 00189 extern void throw_error (enum errors error, const char *fmt, ...) 00190 ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3); 00191 00192 /* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception 00193 handler. If an exception (enum return_reason) is thrown using 00194 throw_exception() than all cleanups installed since 00195 catch_exceptions() was entered are invoked, the (-ve) exception 00196 value is then returned by catch_exceptions. If FUNC() returns 00197 normally (with a positive or zero return value) then that value is 00198 returned by catch_exceptions(). It is an internal_error() for 00199 FUNC() to return a negative value. 00200 00201 For the period of the FUNC() call: UIOUT is installed as the output 00202 builder; ERRSTRING is installed as the error/quit message; and a 00203 new cleanup_chain is established. The old values are restored 00204 before catch_exceptions() returns. 00205 00206 The variant catch_exceptions_with_msg() is the same as 00207 catch_exceptions() but adds the ability to return an allocated 00208 copy of the gdb error message. This is used when a silent error is 00209 issued and the caller wants to manually issue the error message. 00210 00211 MASK specifies what to catch; it is normally set to 00212 RETURN_MASK_ALL, if for no other reason than that the code which 00213 calls catch_errors might not be set up to deal with a quit which 00214 isn't caught. But if the code can deal with it, it generally 00215 should be RETURN_MASK_ERROR, unless for some reason it is more 00216 useful to abort only the portion of the operation inside the 00217 catch_errors. Note that quit should return to the command line 00218 fairly quickly, even if some further processing is being done. 00219 00220 FIXME; cagney/2001-08-13: The need to override the global UIOUT 00221 builder variable should just go away. 00222 00223 This function supersedes catch_errors(). 00224 00225 This function uses SETJMP() and LONGJUMP(). */ 00226 00227 struct ui_out; 00228 typedef int (catch_exceptions_ftype) (struct ui_out *ui_out, void *args); 00229 extern int catch_exceptions (struct ui_out *uiout, 00230 catch_exceptions_ftype *func, void *func_args, 00231 return_mask mask); 00232 typedef void (catch_exception_ftype) (struct ui_out *ui_out, void *args); 00233 extern int catch_exceptions_with_msg (struct ui_out *uiout, 00234 catch_exceptions_ftype *func, 00235 void *func_args, 00236 char **gdberrmsg, 00237 return_mask mask); 00238 00239 /* If CATCH_ERRORS_FTYPE throws an error, catch_errors() returns zero 00240 otherwize the result from CATCH_ERRORS_FTYPE is returned. It is 00241 probably useful for CATCH_ERRORS_FTYPE to always return a non-zero 00242 value. It's unfortunate that, catch_errors() does not return an 00243 indication of the exact exception that it caught - quit_flag might 00244 help. 00245 00246 This function is superseded by catch_exceptions(). */ 00247 00248 typedef int (catch_errors_ftype) (void *); 00249 extern int catch_errors (catch_errors_ftype *, void *, char *, return_mask); 00250 00251 /* Template to catch_errors() that wraps calls to command 00252 functions. */ 00253 00254 typedef void (catch_command_errors_ftype) (char *, int); 00255 extern int catch_command_errors (catch_command_errors_ftype *func, 00256 char *arg, int from_tty, return_mask); 00257 00258 /* Like catch_command_errors, but works with const command and args. */ 00259 00260 typedef void (catch_command_errors_const_ftype) (const char *, int); 00261 extern int catch_command_errors_const (catch_command_errors_const_ftype *func, 00262 const char *arg, int from_tty, return_mask); 00263 00264 #endif