diff options
Diffstat (limited to 'gdb/common')
-rw-r--r-- | gdb/common/common-exceptions.c | 64 | ||||
-rw-r--r-- | gdb/common/common-exceptions.h | 32 |
2 files changed, 56 insertions, 40 deletions
diff --git a/gdb/common/common-exceptions.c b/gdb/common/common-exceptions.c index b65f259..2ad0ce1 100644 --- a/gdb/common/common-exceptions.c +++ b/gdb/common/common-exceptions.c @@ -46,9 +46,7 @@ struct catcher /* Jump buffer pointing back at the exception handler. */ SIGJMP_BUF buf; /* Status buffer belonging to the exception handler. */ - volatile struct gdb_exception *exception; - /* Saved/current state. */ - int mask; + struct gdb_exception exception; struct cleanup *saved_cleanup_chain; /* Back link. */ struct catcher *prev; @@ -74,16 +72,12 @@ catcher_list_size (void) } SIGJMP_BUF * -exceptions_state_mc_init (volatile struct gdb_exception *exception, - return_mask mask) +exceptions_state_mc_init (void) { struct catcher *new_catcher = XCNEW (struct catcher); - /* Start with no exception, save it's address. */ - *exception = exception_none; - new_catcher->exception = exception; - - new_catcher->mask = mask; + /* Start with no exception. */ + new_catcher->exception = exception_none; /* Prevent error/quit during FUNC from calling cleanups established prior to here. */ @@ -134,8 +128,7 @@ exceptions_state_mc (enum catcher_action action) switch (action) { case CATCH_ITER: - /* No error/quit has occured. Just clean up. */ - catcher_pop (); + /* No error/quit has occured. */ return 0; case CATCH_ITER_1: current_catcher->state = CATCHER_RUNNING_1; @@ -152,7 +145,6 @@ exceptions_state_mc (enum catcher_action action) { case CATCH_ITER: /* The did a "break" from the inner while loop. */ - catcher_pop (); return 0; case CATCH_ITER_1: current_catcher->state = CATCHER_RUNNING; @@ -169,21 +161,10 @@ exceptions_state_mc (enum catcher_action action) { case CATCH_ITER: { - struct gdb_exception exception = *current_catcher->exception; - - if (current_catcher->mask & RETURN_MASK (exception.reason)) - { - /* Exit normally if this catcher can handle this - exception. The caller analyses the func return - values. */ - catcher_pop (); - return 0; - } - /* The caller didn't request that the event be caught, - relay the event to the next containing - catch_errors(). */ - catcher_pop (); - throw_exception (exception); + /* Exit normally if this catcher can handle this + exception. The caller analyses the func return + values. */ + return 0; } default: internal_error (__FILE__, __LINE__, _("bad state")); @@ -194,6 +175,31 @@ exceptions_state_mc (enum catcher_action action) } int +exceptions_state_mc_catch (struct gdb_exception *exception, + int mask) +{ + *exception = current_catcher->exception; + catcher_pop (); + + if (exception->reason < 0) + { + if (mask & RETURN_MASK (exception->reason)) + { + /* Exit normally and let the called handle the + exception. */ + return 1; + } + + /* The caller didn't request that the event be caught, relay the + event to the next exception_catch/CATCH. */ + throw_exception (*exception); + } + + /* No exception was thrown. */ + return 0; +} + +int exceptions_state_mc_action_iter (void) { return exceptions_state_mc (CATCH_ITER); @@ -218,7 +224,7 @@ throw_exception (struct gdb_exception exception) to that call via setjmp's return value. Note that REASON can't be zero, by definition in defs.h. */ exceptions_state_mc (CATCH_THROWING); - *current_catcher->exception = exception; + current_catcher->exception = exception; SIGLONGJMP (current_catcher->buf, exception.reason); } diff --git a/gdb/common/common-exceptions.h b/gdb/common/common-exceptions.h index a32e6f9..d2c0bee 100644 --- a/gdb/common/common-exceptions.h +++ b/gdb/common/common-exceptions.h @@ -118,14 +118,13 @@ struct gdb_exception /* Functions to drive the exceptions state machine. Though declared here by necessity, these functions should be considered internal to - the exceptions subsystem and not used other than via the TRY_CATCH - macro defined below. */ + the exceptions subsystem and not used other than via the TRY/CATCH + macros defined below. */ -extern SIGJMP_BUF *exceptions_state_mc_init (volatile struct - gdb_exception *exception, - return_mask mask); +extern SIGJMP_BUF *exceptions_state_mc_init (void); extern int exceptions_state_mc_action_iter (void); extern int exceptions_state_mc_action_iter_1 (void); +extern int exceptions_state_mc_catch (struct gdb_exception *, int); /* Macro to wrap up standard try/catch behavior. @@ -138,26 +137,37 @@ extern int exceptions_state_mc_action_iter_1 (void); *INDENT-OFF* - volatile struct gdb_exception e; - TRY_CATCH (e, RETURN_MASK_ERROR) + TRY { } - switch (e.reason) + CATCH (e, RETURN_MASK_ERROR) { - case RETURN_ERROR: ... + switch (e.reason) + { + case RETURN_ERROR: ... + } } + END_CATCH */ -#define TRY_CATCH(EXCEPTION,MASK) \ +#define TRY \ { \ SIGJMP_BUF *buf = \ - exceptions_state_mc_init (&(EXCEPTION), (MASK)); \ + exceptions_state_mc_init (); \ SIGSETJMP (*buf); \ } \ while (exceptions_state_mc_action_iter ()) \ while (exceptions_state_mc_action_iter_1 ()) +#define CATCH(EXCEPTION, MASK) \ + { \ + struct gdb_exception EXCEPTION; \ + if (exceptions_state_mc_catch (&(EXCEPTION), MASK)) + +#define END_CATCH \ + } + /* *INDENT-ON* */ /* Hook to allow client-specific actions to be performed prior to |