Eliminate most remaining cleanups under gdb/guile/

The main complication with the Guile code is that we have two types of
exceptions to consider.  GDB/C++ exceptions, and Guile/SJLJ
exceptions.  Code that is facing the Guile interpreter must not throw
GDB exceptions, instead Scheme exceptions must be thrown.  Also,
because Guile exceptions are SJLJ based, Guile-facing code must not
use local objects with dtors, unless wrapped in a scope with a
TRY/CATCH, because the dtors won't otherwise be run when a Guile
exceptions is thrown.

This commit adds a new gdbscm_wrap wrapper function than encapsulates
a pattern I noticed in many of the functions using
GDBSCM_HANDLE_GDB_EXCEPTION_WITH_CLEANUPS.  The wrapper is written
such that you can pass either a lambda to it, or a function plus a
variable number of forwarded args.  I used a lambda when its body
would be reasonably short, and a separate function in the larger
cases.

This also convers a few functions that were using
GDBSCM_HANDLE_GDB_EXCEPTION to use gdbscm_wrap too because they
followed a similar pattern.

A few cases of make_cleanup calls are replaced with explicit xfree
calls.  The make_cleanup/do_cleanups calls in those cases are
pointless, because do_cleanups won't be called when a Scheme exception
is thrown.

We also have a couple cases of Guile-facing code using RAII-type
objects to manage memory, but those are incorrect, exactly because
their dtor won't be called if a Guile exception is thrown.

gdb/ChangeLog:
2018-07-18  Pedro Alves  <palves@redhat.com>

	* guile/guile-internal.h: Add comment about mixing GDB and Scheme
	exceptions.
	(GDBSCM_HANDLE_GDB_EXCEPTION_WITH_CLEANUPS): Delete.
	(gdbscm_wrap): New.
	* guile/scm-frame.c (gdbscm_frame_read_register): Use xfree
	directly instead of a cleanup.
	* guile/scm-math.c (vlscm_unop_gdbthrow): New, factored out from ...
	(vlscm_unop): ... this.  Reimplement using gdbscm_wrap.
	(vlscm_binop_gdbthrow): New, factored out from ...
	(vlscm_binop): ... this.  Reimplement using gdbscm_wrap.
	(vlscm_rich_compare): Use gdbscm_wrap.
	* guile/scm-symbol.c (gdbscm_lookup_symbol): Use xfree directly
	instead of a cleanup.
	(gdbscm_lookup_global_symbol): Use xfree directly instead of a
	cleanup.
	* guile/scm-type.c (gdbscm_type_field, gdbscm_type_has_field_p):
	Use xfree directly instead of a cleanup.
	* guile/scm-value.c (gdbscm_make_value, gdbscm_make_lazy_value):
	Adjust to use gdbscm_wrap and scoped_value_mark.
	(gdbscm_value_optimized_out_p): Adjust to use gdbscm_wrap.
	(gdbscm_value_address, gdbscm_value_dereference)
	(gdbscm_value_referenced_value): Adjust to use gdbscm_wrap and
	scoped_value_mark.
	(gdbscm_value_dynamic_type): Use scoped_value_mark.
	(vlscm_do_cast, gdbscm_value_field): Adjust to use gdbscm_wrap and
	scoped_value_mark.
	(gdbscm_value_subscript, gdbscm_value_call): Adjust to use
	gdbscm_wrap and scoped_value_mark.
	(gdbscm_value_to_string): Use xfree directly instead of a
	cleanup.  Move 'buffer' unique_ptr to TRY scope.
	(gdbscm_value_to_lazy_string): Use xfree directly instead of a
	cleanup.  Move 'buffer' unique_ptr to TRY scope.  Use
	scoped_value_mark.
	(gdbscm_value_fetch_lazy_x): Use gdbscm_wrap.
	(gdbscm_parse_and_eval): Adjust to use gdbscm_wrap and
	scoped_value_mark.
	(gdbscm_history_ref, gdbscm_history_append_x): Adjust to use
	gdbscm_wrap.
This commit is contained in:
Pedro Alves 2018-07-18 22:55:59 +01:00
parent 42dc7699a2
commit 557e56be26
7 changed files with 412 additions and 575 deletions

View file

@ -977,7 +977,6 @@ gdbscm_type_field (SCM self, SCM field_scm)
struct type *type = t_smob->type;
char *field;
int i;
struct cleanup *cleanups;
SCM_ASSERT_TYPE (scm_is_string (field_scm), field_scm, SCM_ARG2, FUNC_NAME,
_("string"));
@ -992,7 +991,6 @@ gdbscm_type_field (SCM self, SCM field_scm)
_(not_composite_error));
field = gdbscm_scm_to_c_string (field_scm);
cleanups = make_cleanup (xfree, field);
for (i = 0; i < TYPE_NFIELDS (type); i++)
{
@ -1000,12 +998,12 @@ gdbscm_type_field (SCM self, SCM field_scm)
if (t_field_name && (strcmp_iw (t_field_name, field) == 0))
{
do_cleanups (cleanups);
return tyscm_make_field_smob (self, i);
xfree (field);
return tyscm_make_field_smob (self, i);
}
}
do_cleanups (cleanups);
xfree (field);
gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, field_scm,
_("Unknown field"));
@ -1022,7 +1020,6 @@ gdbscm_type_has_field_p (SCM self, SCM field_scm)
struct type *type = t_smob->type;
char *field;
int i;
struct cleanup *cleanups;
SCM_ASSERT_TYPE (scm_is_string (field_scm), field_scm, SCM_ARG2, FUNC_NAME,
_("string"));
@ -1037,7 +1034,6 @@ gdbscm_type_has_field_p (SCM self, SCM field_scm)
_(not_composite_error));
field = gdbscm_scm_to_c_string (field_scm);
cleanups = make_cleanup (xfree, field);
for (i = 0; i < TYPE_NFIELDS (type); i++)
{
@ -1045,12 +1041,12 @@ gdbscm_type_has_field_p (SCM self, SCM field_scm)
if (t_field_name && (strcmp_iw (t_field_name, field) == 0))
{
do_cleanups (cleanups);
return SCM_BOOL_T;
xfree (field);
return SCM_BOOL_T;
}
}
do_cleanups (cleanups);
xfree (field);
return SCM_BOOL_F;
}