diff options
-rw-r--r-- | gdb/ChangeLog | 16 | ||||
-rw-r--r-- | gdb/exceptions.c | 76 | ||||
-rw-r--r-- | gdb/exceptions.h | 57 |
3 files changed, 110 insertions, 39 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 637ac3e..0d49be8 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,21 @@ 2005-02-08 Andrew Cagney <cagney@gnu.org> + * exceptions.c: Do not include <setjmp.h>. + (SIGJMP_BUF, SIGSETJMP, SIGLONGJMP): Delete macros. + (catch_exception, catch_exceptions_with_msg, catch_errors) + (catch_command_errors): Use TRY_CATCH. + (struct catcher): Use EXCEPTIONS_SIGJMP_BUF. + (exceptions_state_mc_init): Rename catcher_init. + (exceptions_state_mc): Rename catcher_state_machine. + (exceptions_state_mc_action_iter) + (exceptions_state_mc_action_iter_1): New functions. + * exceptions.h: Include <setjmp.h>. + (EXCEPTIONS_SIGJMP_BUF, EXCEPTIONS_SIGSETJMP) + (EXCEPTIONS_SIGLONGJMP): Define. + (exceptions_state_mc_init, exceptions_state_mc_action_iter) + (exceptions_state_mc_action_iter_1): Declare. + (TRY_CATCH): Define. + * ppc-linux-tdep.c (ppc_linux_init_abi): Do not set malloc name, no longer needed. diff --git a/gdb/exceptions.c b/gdb/exceptions.c index fae2372..610f168 100644 --- a/gdb/exceptions.c +++ b/gdb/exceptions.c @@ -23,7 +23,6 @@ #include "defs.h" #include "exceptions.h" -#include <setjmp.h> #include "breakpoint.h" #include "target.h" #include "inferior.h" @@ -35,18 +34,6 @@ const struct exception exception_none = { 0, NO_ERROR, NULL }; -/* One should use catch_errors rather than manipulating these - directly. */ -#if defined(HAVE_SIGSETJMP) -#define SIGJMP_BUF sigjmp_buf -#define SIGSETJMP(buf) sigsetjmp((buf), 1) -#define SIGLONGJMP(buf,val) siglongjmp((buf), (val)) -#else -#define SIGJMP_BUF jmp_buf -#define SIGSETJMP(buf) setjmp(buf) -#define SIGLONGJMP(buf,val) longjmp((buf), (val)) -#endif - /* Possible catcher states. */ enum catcher_state { /* Initial state, a new catcher has just been created. */ @@ -69,7 +56,7 @@ struct catcher { enum catcher_state state; /* Jump buffer pointing back at the exception handler. */ - SIGJMP_BUF buf; + EXCEPTIONS_SIGJMP_BUF buf; /* Status buffer belonging to the exception handler. */ volatile struct exception *exception; /* Saved/current state. */ @@ -83,10 +70,10 @@ struct catcher /* Where to go for throw_exception(). */ static struct catcher *current_catcher; -static SIGJMP_BUF * -catcher_init (struct ui_out *func_uiout, - volatile struct exception *exception, - return_mask mask) +EXCEPTIONS_SIGJMP_BUF * +exceptions_state_mc_init (struct ui_out *func_uiout, + volatile struct exception *exception, + return_mask mask) { struct catcher *new_catcher = XZALLOC (struct catcher); @@ -133,8 +120,8 @@ catcher_pop (void) /* Catcher state machine. Returns non-zero if the m/c should be run again, zero if it should abort. */ -int -catcher_state_machine (enum catcher_action action) +static int +exceptions_state_mc (enum catcher_action action) { switch (current_catcher->state) { @@ -210,6 +197,18 @@ catcher_state_machine (enum catcher_action action) } } +int +exceptions_state_mc_action_iter (void) +{ + return exceptions_state_mc (CATCH_ITER); +} + +int +exceptions_state_mc_action_iter_1 (void) +{ + return exceptions_state_mc (CATCH_ITER_1); +} + /* Return EXCEPTION to the nearest containing catch_errors(). */ NORETURN void @@ -232,9 +231,9 @@ throw_exception (struct exception exception) /* Jump to the containing catch_errors() call, communicating REASON to that call via setjmp's return value. Note that REASON can't be zero, by definition in defs.h. */ - catcher_state_machine (CATCH_THROWING); + exceptions_state_mc (CATCH_THROWING); *current_catcher->exception = exception; - SIGLONGJMP (current_catcher->buf, exception.reason); + EXCEPTIONS_SIGLONGJMP (current_catcher->buf, exception.reason); } static char *last_message; @@ -465,11 +464,10 @@ catch_exception (struct ui_out *uiout, return_mask mask) { volatile struct exception exception; - SIGJMP_BUF *catch; - catch = catcher_init (uiout, &exception, mask); - for (SIGSETJMP ((*catch)); - catcher_state_machine (CATCH_ITER);) - (*func) (uiout, func_args); + TRY_CATCH (exception, mask) + { + (*func) (uiout, func_args); + } return exception; } @@ -482,9 +480,10 @@ catch_exceptions_with_msg (struct ui_out *uiout, { volatile struct exception exception; volatile int val = 0; - SIGJMP_BUF *catch = catcher_init (uiout, &exception, mask); - for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);) - val = (*func) (uiout, func_args); + TRY_CATCH (exception, mask) + { + val = (*func) (uiout, func_args); + } print_any_exception (gdb_stderr, NULL, exception); gdb_assert (val >= 0); gdb_assert (exception.reason <= 0); @@ -511,12 +510,10 @@ catch_errors (catch_errors_ftype *func, void *func_args, char *errstring, { volatile int val = 0; volatile struct exception exception; - SIGJMP_BUF *catch = catcher_init (uiout, &exception, mask); - /* This illustrates how it is possible to nest the mechanism and - hence catch "break". Of course this doesn't address the need to - also catch "return". */ - for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);) - val = func (func_args); + TRY_CATCH (exception, mask) + { + val = func (func_args); + } print_any_exception (gdb_stderr, errstring, exception); if (exception.reason != 0) return 0; @@ -528,9 +525,10 @@ catch_command_errors (catch_command_errors_ftype * command, char *arg, int from_tty, return_mask mask) { volatile struct exception e; - SIGJMP_BUF *catch = catcher_init (uiout, &e, mask); - for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);) - command (arg, from_tty); + TRY_CATCH (e, mask) + { + command (arg, from_tty); + } print_any_exception (gdb_stderr, NULL, e); if (e.reason < 0) return 0; diff --git a/gdb/exceptions.h b/gdb/exceptions.h index fe19ecd..a47742a 100644 --- a/gdb/exceptions.h +++ b/gdb/exceptions.h @@ -24,6 +24,10 @@ #ifndef EXCEPTIONS_H #define EXCEPTIONS_H +struct ui_out; + +#include <setjmp.h> + /* Reasons for calling throw_exceptions(). NOTE: all reason values must be less than zero. enum value 0 is reserved for internal use as the return value from an initial setjmp(). The function @@ -66,6 +70,59 @@ struct exception /* A pre-defined non-exception. */ extern const struct exception exception_none; +/* Wrap set/long jmp so that it's more portable (internal to + exceptions). */ + +#if defined(HAVE_SIGSETJMP) +#define EXCEPTIONS_SIGJMP_BUF sigjmp_buf +#define EXCEPTIONS_SIGSETJMP(buf) sigsetjmp((buf), 1) +#define EXCEPTIONS_SIGLONGJMP(buf,val) siglongjmp((buf), (val)) +#else +#define EXCEPTIONS_SIGJMP_BUF jmp_buf +#define EXCEPTIONS_SIGSETJMP(buf) setjmp(buf) +#define EXCEPTIONS_SIGLONGJMP(buf,val) longjmp((buf), (val)) +#endif + +/* Functions to drive the exceptions state m/c (internal to + exceptions). */ +EXCEPTIONS_SIGJMP_BUF *exceptions_state_mc_init (struct ui_out *func_uiout, + volatile struct exception * + exception, + return_mask mask); +int exceptions_state_mc_action_iter (void); +int exceptions_state_mc_action_iter_1 (void); + +/* Macro to wrap up standard try/catch behavior. + + The double loop lets us correctly handle code "break"ing out of the + try catch block. (It works as the "break" only exits the inner + "while" loop, the outer for loop detects this handling it + correctly.) Of course "return" and "goto" are not so lucky. + + For instance: + + *INDENT-OFF* + + volatile struct exception e; + TRY_CATCH (e, RETURN_MASK_ERROR) + { + } + switch (e.reason) + { + case RETURN_ERROR: ... + } + + */ + +#define TRY_CATCH(EXCEPTION,MASK) \ + for (EXCEPTIONS_SIGSETJMP \ + (*exceptions_state_mc_init (uiout, &(EXCEPTION), (MASK))); \ + exceptions_state_mc_action_iter (); ) \ + while (exceptions_state_mc_action_iter_1 ()) + +/* *INDENT-ON* */ + + /* If E is an exception, print it's error message on the specified stream. for _fprintf, prefix the message with PREFIX... */ extern void exception_print (struct ui_file *file, struct exception e); |