Normalize TRY_CATCH exception handling block

This normalizes some exception catch blocks that check for ex.reason
to look like this:

~~~
  volatile gdb_exception ex;

  TRY_CATCH (ex, RETURN_MASK_ALL)
    {
      ...
    }
  if (ex.reason < 0)
    {
      ...
    }
~~~

This is a preparation step for running a script that converts all
TRY_CATCH uses to look like this instead:

~~~
  TRY
    {
      ...
    }
  CATCH (ex, RETURN_MASK_ALL)
    {
      ...
    }
  END_CATCH
~~~

The motivation for that change is being able to reimplent TRY/CATCH in
terms of C++ try/catch.

This commit makes it so that:

 - no condition other than ex.reason < 0 is checked in the if
   predicate

 - there's no "else" block to check whether no exception was caught

 - there's no code between the TRY_CATCH (TRY) block and the
   'if (ex.reason < 0)' block (CATCH).

 - the exception object is no longer referred to outside the if/catch
   block.  Note the local volatile exception objects that are
   currently defined inside functions that use TRY_CATCH will
   disappear.  In cases it's more convenient to still refer to the
   exception outside the catch block, a new non-volatile local is
   added and copy to that object is made within the catch block.

The following patches should make this all clearer.

gdb/ChangeLog:
2015-03-07  Pedro Alves  <palves@redhat.com>

	* amd64-tdep.c (amd64_frame_cache, amd64_sigtramp_frame_cache)
	(amd64_epilogue_frame_cache): Normal exception handling code.
	* break-catch-throw.c (check_status_exception_catchpoint)
	(re_set_exception_catchpoint): Ditto.
	* cli/cli-interp.c (safe_execute_command):
	* cli/cli-script.c (script_from_file): Ditto.
	* compile/compile-c-symbols.c (generate_c_for_for_one_variable):
	Ditto.
	* compile/compile-object-run.c (compile_object_run): Ditto.
	* cp-abi.c (baseclass_offset): Ditto.
	* cp-valprint.c (cp_print_value): Ditto.
	* exceptions.c (catch_exceptions_with_msg):
	* frame-unwind.c (frame_unwind_try_unwinder): Ditto.
	* frame.c (get_frame_address_in_block_if_available): Ditto.
	* i386-tdep.c (i386_frame_cache, i386_epilogue_frame_cache)
	(i386_sigtramp_frame_cache): Ditto.
	* infcmd.c (post_create_inferior): Ditto.
	* linespec.c (parse_linespec, find_linespec_symbols):
	* p-valprint.c (pascal_object_print_value): Ditto.
	* parse.c (parse_expression_for_completion): Ditto.
	* python/py-finishbreakpoint.c (bpfinishpy_init): Ditto.
	* remote.c (remote_get_noisy_reply): Ditto.
	* s390-linux-tdep.c (s390_frame_unwind_cache): Ditto.
	* solib-svr4.c (solib_svr4_r_map): Ditto.
This commit is contained in:
Pedro Alves 2015-03-07 14:50:04 +00:00
parent f873665f44
commit 7556d4a4f6
22 changed files with 219 additions and 120 deletions

View File

@ -1,3 +1,30 @@
2015-03-07 Pedro Alves <palves@redhat.com>
* amd64-tdep.c (amd64_frame_cache, amd64_sigtramp_frame_cache)
(amd64_epilogue_frame_cache): Normal exception handling code.
* break-catch-throw.c (check_status_exception_catchpoint)
(re_set_exception_catchpoint): Ditto.
* cli/cli-interp.c (safe_execute_command):
* cli/cli-script.c (script_from_file): Ditto.
* compile/compile-c-symbols.c (generate_c_for_for_one_variable):
Ditto.
* compile/compile-object-run.c (compile_object_run): Ditto.
* cp-abi.c (baseclass_offset): Ditto.
* cp-valprint.c (cp_print_value): Ditto.
* exceptions.c (catch_exceptions_with_msg):
* frame-unwind.c (frame_unwind_try_unwinder): Ditto.
* frame.c (get_frame_address_in_block_if_available): Ditto.
* i386-tdep.c (i386_frame_cache, i386_epilogue_frame_cache)
(i386_sigtramp_frame_cache): Ditto.
* infcmd.c (post_create_inferior): Ditto.
* linespec.c (parse_linespec, find_linespec_symbols):
* p-valprint.c (pascal_object_print_value): Ditto.
* parse.c (parse_expression_for_completion): Ditto.
* python/py-finishbreakpoint.c (bpfinishpy_init): Ditto.
* remote.c (remote_get_noisy_reply): Ditto.
* s390-linux-tdep.c (s390_frame_unwind_cache): Ditto.
* solib-svr4.c (solib_svr4_r_map): Ditto.
2015-03-06 Gary Benson <gbenson@redhat.com>
* common/common-utils.h (startswith): New inline function.

View File

@ -2479,8 +2479,11 @@ amd64_frame_cache (struct frame_info *this_frame, void **this_cache)
{
amd64_frame_cache_1 (this_frame, cache);
}
if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
if (ex.reason < 0)
{
if (ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
}
return cache;
}
@ -2604,8 +2607,11 @@ amd64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
cache->base_p = 1;
}
if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
if (ex.reason < 0)
{
if (ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
}
*this_cache = cache;
return cache;
@ -2780,8 +2786,11 @@ amd64_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
cache->base_p = 1;
}
if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
if (ex.reason < 0)
{
if (ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
}
return cache;
}

View File

@ -187,13 +187,16 @@ check_status_exception_catchpoint (struct bpstats *bs)
type_name = canon;
}
}
if (e.reason < 0)
exception_print (gdb_stderr, e);
else if (regexec (self->pattern, type_name, 0, NULL, 0) != 0)
bs->stop = 0;
xfree (type_name);
if (type_name != NULL)
{
if (regexec (self->pattern, type_name, 0, NULL, 0) != 0)
bs->stop = 0;
xfree (type_name);
}
}
/* Implement the 're_set' method. */
@ -227,11 +230,13 @@ re_set_exception_catchpoint (struct breakpoint *self)
self->ops->decode_linespec (self, &spec, &sals);
}
/* NOT_FOUND_ERROR just means the breakpoint will be pending, so
let it through. */
if (ex.reason < 0 && ex.error != NOT_FOUND_ERROR)
throw_exception (ex);
if (ex.reason < 0)
{
/* NOT_FOUND_ERROR just means the breakpoint will be
pending, so let it through. */
if (ex.error != NOT_FOUND_ERROR)
throw_exception (ex);
}
}
cleanup = make_cleanup (xfree, sals.sals);

View File

@ -179,17 +179,22 @@ cli_interpreter_exec (void *data, const char *command_str)
static struct gdb_exception
safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
{
volatile struct gdb_exception e;
volatile struct gdb_exception exception;
struct gdb_exception e = exception_none;
struct ui_out *saved_uiout;
/* Save and override the global ``struct ui_out'' builder. */
saved_uiout = current_uiout;
current_uiout = command_uiout;
TRY_CATCH (e, RETURN_MASK_ALL)
TRY_CATCH (exception, RETURN_MASK_ALL)
{
execute_command (command, from_tty);
}
if (exception.reason < 0)
{
e = exception;
}
/* Restore the global builder. */
current_uiout = saved_uiout;

View File

@ -1706,18 +1706,13 @@ script_from_file (FILE *stream, const char *file)
{
read_command_file (stream);
}
switch (e.reason)
if (e.reason < 0)
{
case 0:
break;
case RETURN_ERROR:
/* Re-throw the error, but with the file name information
prepended. */
throw_error (e.error,
_("%s:%d: Error in sourced command file:\n%s"),
source_file_name, source_line_number, e.message);
default:
internal_error (__FILE__, __LINE__, _("bad reason"));
}
}

View File

@ -699,17 +699,17 @@ generate_c_for_for_one_variable (struct compile_c_instance *compiler,
}
}
if (e.reason >= 0)
return;
if (compiler->symbol_err_map == NULL)
compiler->symbol_err_map = htab_create_alloc (10,
hash_symbol_error,
eq_symbol_error,
del_symbol_error,
xcalloc,
xfree);
insert_symbol_error (compiler->symbol_err_map, sym, e.message);
if (e.reason < 0)
{
if (compiler->symbol_err_map == NULL)
compiler->symbol_err_map = htab_create_alloc (10,
hash_symbol_error,
eq_symbol_error,
del_symbol_error,
xcalloc,
xfree);
insert_symbol_error (compiler->symbol_err_map, sym, e.message);
}
}
/* See compile-internal.h. */

View File

@ -121,18 +121,19 @@ compile_object_run (struct compile_module *module)
do_module_cleanup, data);
}
}
dtor_found = find_dummy_frame_dtor (do_module_cleanup, data);
if (!executed)
data->executedp = NULL;
if (ex.reason >= 0)
gdb_assert (!dtor_found && executed);
else
if (ex.reason < 0)
{
/* In the case od DTOR_FOUND or in the case of EXECUTED nothing
/* In the case of DTOR_FOUND or in the case of EXECUTED nothing
needs to be done. */
dtor_found = find_dummy_frame_dtor (do_module_cleanup, data);
if (!executed)
data->executedp = NULL;
gdb_assert (!(dtor_found && executed));
if (!dtor_found && !executed)
do_module_cleanup (data);
throw_exception (ex);
}
dtor_found = find_dummy_frame_dtor (do_module_cleanup, data);
gdb_assert (!dtor_found && executed);
}

View File

@ -80,15 +80,17 @@ baseclass_offset (struct type *type, int index, const gdb_byte *valaddr,
embedded_offset,
address, val);
}
if (ex.reason < 0)
{
if (ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR)
throw_error (NOT_AVAILABLE_ERROR,
_("Cannot determine virtual baseclass offset "
"of incomplete object"));
else if (ex.reason < 0)
throw_exception (ex);
else
return res;
throw_error (NOT_AVAILABLE_ERROR,
_("Cannot determine virtual baseclass offset "
"of incomplete object"));
}
return res;
}
struct value *

View File

@ -481,7 +481,7 @@ cp_print_value (struct type *type, struct type *real_type,
for (i = 0; i < n_baseclasses; i++)
{
int boffset = 0;
int skip;
int skip = 0;
struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
const char *basename = TYPE_NAME (baseclass);
const gdb_byte *base_valaddr = NULL;
@ -510,14 +510,16 @@ cp_print_value (struct type *type, struct type *real_type,
{
boffset = baseclass_offset (type, i, valaddr, offset, address, val);
}
if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR)
skip = -1;
else if (ex.reason < 0)
skip = 1;
else
{
skip = 0;
if (ex.reason < 0)
{
if (ex.error == NOT_AVAILABLE_ERROR)
skip = -1;
else
skip = 1;
}
if (skip == 0)
{
if (BASETYPE_VIA_VIRTUAL (type, i))
{
/* The virtual base class pointer might have been

View File

@ -174,7 +174,8 @@ catch_exceptions_with_msg (struct ui_out *func_uiout,
char **gdberrmsg,
return_mask mask)
{
volatile struct gdb_exception exception;
volatile struct gdb_exception ex;
struct gdb_exception exception = exception_none;
volatile int val = 0;
struct ui_out *saved_uiout;
@ -182,10 +183,14 @@ catch_exceptions_with_msg (struct ui_out *func_uiout,
saved_uiout = current_uiout;
current_uiout = func_uiout;
TRY_CATCH (exception, RETURN_MASK_ALL)
TRY_CATCH (ex, RETURN_MASK_ALL)
{
val = (*func) (current_uiout, func_args);
}
if (ex.reason < 0)
{
exception = ex;
}
/* Restore the global builder. */
current_uiout = saved_uiout;

View File

@ -105,18 +105,21 @@ frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache,
{
res = unwinder->sniffer (unwinder, this_frame, this_cache);
}
if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR)
if (ex.reason < 0)
{
/* This usually means that not even the PC is available,
thus most unwinders aren't able to determine if they're
the best fit. Keep trying. Fallback prologue unwinders
should always accept the frame. */
do_cleanups (old_cleanup);
return 0;
if (ex.error == NOT_AVAILABLE_ERROR)
{
/* This usually means that not even the PC is available,
thus most unwinders aren't able to determine if they're
the best fit. Keep trying. Fallback prologue unwinders
should always accept the frame. */
do_cleanups (old_cleanup);
return 0;
}
throw_exception (ex);
}
else if (ex.reason < 0)
throw_exception (ex);
else if (res)
if (res)
{
discard_cleanups (old_cleanup);
return 1;

View File

@ -2313,12 +2313,14 @@ get_frame_address_in_block_if_available (struct frame_info *this_frame,
{
*pc = get_frame_address_in_block (this_frame);
}
if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR)
return 0;
else if (ex.reason < 0)
throw_exception (ex);
else
return 1;
if (ex.reason < 0)
{
if (ex.error == NOT_AVAILABLE_ERROR)
return 0;
throw_exception (ex);
}
return 1;
}
void

View File

@ -2062,8 +2062,11 @@ i386_frame_cache (struct frame_info *this_frame, void **this_cache)
{
i386_frame_cache_1 (this_frame, cache);
}
if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
if (ex.reason < 0)
{
if (ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
}
return cache;
}
@ -2237,8 +2240,11 @@ i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
cache->base_p = 1;
}
if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
if (ex.reason < 0)
{
if (ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
}
return cache;
}
@ -2430,8 +2436,11 @@ i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
cache->base_p = 1;
}
if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
if (ex.reason < 0)
{
if (ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
}
*this_cache = cache;
return cache;

View File

@ -430,8 +430,11 @@ post_create_inferior (struct target_ops *target, int from_tty)
{
stop_pc = regcache_read_pc (get_current_regcache ());
}
if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
if (ex.reason < 0)
{
if (ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
}
if (exec_bfd)
{

View File

@ -2153,7 +2153,7 @@ parse_linespec (linespec_parser *parser, const char **argptr)
{
linespec_token token;
struct symtabs_and_lines values;
volatile struct gdb_exception file_exception;
struct gdb_exception file_exception = exception_none;
struct cleanup *cleanup;
/* A special case to start. It has become quite popular for
@ -2181,7 +2181,6 @@ parse_linespec (linespec_parser *parser, const char **argptr)
parser->lexer.saved_arg = *argptr;
parser->lexer.stream = argptr;
file_exception.reason = 0;
/* Initialize the default symtab and line offset. */
initialize_defaults (&PARSER_STATE (parser)->default_symtab,
@ -2261,17 +2260,22 @@ parse_linespec (linespec_parser *parser, const char **argptr)
if (token.type == LSTOKEN_COLON)
{
char *user_filename;
volatile struct gdb_exception ex;
/* Get the current token again and extract the filename. */
token = linespec_lexer_lex_one (parser);
user_filename = copy_token_string (token);
/* Check if the input is a filename. */
TRY_CATCH (file_exception, RETURN_MASK_ERROR)
TRY_CATCH (ex, RETURN_MASK_ERROR)
{
PARSER_RESULT (parser)->file_symtabs
= symtabs_from_filename (user_filename);
}
if (ex.reason < 0)
{
file_exception = ex;
}
if (file_exception.reason >= 0)
{
@ -3198,8 +3202,11 @@ find_linespec_symbols (struct linespec_state *state,
/* If successful, we're done. If NOT_FOUND_ERROR
was not thrown, rethrow the exception that we did get. */
if (except.reason < 0 && except.error != NOT_FOUND_ERROR)
throw_exception (except);
if (except.reason < 0)
{
if (except.error != NOT_FOUND_ERROR)
throw_exception (except);
}
}
}

View File

@ -749,14 +749,16 @@ pascal_object_print_value (struct type *type, const gdb_byte *valaddr,
{
boffset = baseclass_offset (type, i, valaddr, offset, address, val);
}
if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR)
skip = -1;
else if (ex.reason < 0)
skip = 1;
else
if (ex.reason < 0)
{
skip = 0;
if (ex.error == NOT_AVAILABLE_ERROR)
skip = -1;
else
skip = 1;
}
if (skip == 0)
{
/* The virtual base class pointer might have been clobbered by the
user program. Make sure that it still points to a valid memory
location. */

View File

@ -1290,8 +1290,13 @@ parse_expression_for_completion (const char *string, char **name,
parse_completion = 1;
exp = parse_exp_in_context (&string, 0, 0, 0, 0, &subexp);
}
if (except.reason < 0)
{
/* Nothing, EXP remains NULL. */
}
parse_completion = 0;
if (except.reason < 0 || ! exp)
if (exp == NULL)
return NULL;
if (expout_tag_completion_type != TYPE_CODE_UNDEF)

View File

@ -269,8 +269,13 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
}
}
}
if (except.reason < 0
|| !self_bpfinish->return_type || !self_bpfinish->function_value)
if (except.reason < 0)
{
/* Just swallow. Either the return type or the function value
remain NULL. */
}
if (self_bpfinish->return_type == NULL || self_bpfinish->function_value == NULL)
{
/* Won't be able to compute return value. */
Py_XDECREF (self_bpfinish->return_type);

View File

@ -498,6 +498,7 @@ remote_get_noisy_reply (char **buf_p,
char *p, *pp;
int adjusted_size = 0;
volatile struct gdb_exception ex;
int relocated = 0;
p = buf + strlen ("qRelocInsn:");
pp = unpack_varlen_hex (p, &ul);
@ -514,31 +515,35 @@ remote_get_noisy_reply (char **buf_p,
TRY_CATCH (ex, RETURN_MASK_ALL)
{
gdbarch_relocate_instruction (target_gdbarch (), &to, from);
relocated = 1;
}
if (ex.reason >= 0)
if (ex.reason < 0)
{
if (ex.error == MEMORY_ERROR)
{
/* Propagate memory errors silently back to the
target. The stub may have limited the range of
addresses we can write to, for example. */
}
else
{
/* Something unexpectedly bad happened. Be verbose
so we can tell what, and propagate the error back
to the stub, so it doesn't get stuck waiting for
a response. */
exception_fprintf (gdb_stderr, ex,
_("warning: relocating instruction: "));
}
putpkt ("E01");
}
if (relocated)
{
adjusted_size = to - org_to;
xsnprintf (buf, *sizeof_buf, "qRelocInsn:%x", adjusted_size);
putpkt (buf);
}
else if (ex.reason < 0 && ex.error == MEMORY_ERROR)
{
/* Propagate memory errors silently back to the target.
The stub may have limited the range of addresses we
can write to, for example. */
putpkt ("E01");
}
else
{
/* Something unexpectedly bad happened. Be verbose so
we can tell what, and propagate the error back to the
stub, so it doesn't get stuck waiting for a
response. */
exception_fprintf (gdb_stderr, ex,
_("warning: relocating instruction: "));
putpkt ("E01");
}
}
else if (buf[0] == 'O' && buf[1] != 'K')
remote_console_output (buf + 1); /* 'O' message from stub */

View File

@ -3382,8 +3382,11 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
trad_frame_set_value (cache->saved_regs,
gdbarch_pc_regnum (gdbarch), lr);
}
if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
if (ex.reason < 0)
{
if (ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
}
return cache;
}

View File

@ -1970,8 +1970,11 @@ s390_frame_unwind_cache (struct frame_info *this_frame,
if (!s390_prologue_frame_unwind_cache (this_frame, info))
s390_backchain_frame_unwind_cache (this_frame, info);
}
if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
if (ex.reason < 0)
{
if (ex.error != NOT_AVAILABLE_ERROR)
throw_exception (ex);
}
return info;
}

View File

@ -881,7 +881,8 @@ solib_svr4_r_map (struct svr4_info *info)
addr = read_memory_typed_address (info->debug_base + lmo->r_map_offset,
ptr_type);
}
exception_print (gdb_stderr, ex);
if (ex.reason < 0)
exception_print (gdb_stderr, ex);
return addr;
}