From 888fe1e1d88e4398256a07ae5f0e8f98c8607c3c Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 3 Jan 2012 19:27:52 +0000 Subject: PR python/12533: * python/py-value.c (valpy_dereference, valpy_get_address valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) (valpy_getitem, valpy_call, valpy_binop, valpy_negative) (valpy_absolute, valpy_richcompare): Free intermediate values. --- gdb/ChangeLog | 8 ++++ gdb/python/py-value.c | 102 ++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 86 insertions(+), 24 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8bd6f7e..266f387 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2012-01-03 Tom Tromey + + PR python/12533: + * python/py-value.c (valpy_dereference, valpy_get_address + valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast) + (valpy_getitem, valpy_call, valpy_binop, valpy_negative) + (valpy_absolute, valpy_richcompare): Free intermediate values. + 2011-01-03 Joel Brobecker * ada-lang.c: Reformat the copyright notice. diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index 04e355a..66e65c4 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -1,6 +1,6 @@ /* Python interface to values. - Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of GDB. @@ -174,23 +174,27 @@ preserve_python_values (struct objfile *objfile, htab_t copied_types) static PyObject * valpy_dereference (PyObject *self, PyObject *args) { - struct value *res_val = NULL; /* Initialize to appease gcc warning. */ volatile struct gdb_exception except; + PyObject *result = NULL; TRY_CATCH (except, RETURN_MASK_ALL) { + struct value *res_val; + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + res_val = value_ind (((value_object *) self)->value); + result = value_to_value_object (res_val); + do_cleanups (cleanup); } GDB_PY_HANDLE_EXCEPTION (except); - return value_to_value_object (res_val); + return result; } /* Return "&value". */ static PyObject * valpy_get_address (PyObject *self, void *closure) { - struct value *res_val = NULL; /* Initialize to appease gcc warning. */ value_object *val_obj = (value_object *) self; volatile struct gdb_exception except; @@ -198,15 +202,19 @@ valpy_get_address (PyObject *self, void *closure) { TRY_CATCH (except, RETURN_MASK_ALL) { + struct value *res_val; + struct cleanup *cleanup + = make_cleanup_value_free_to_mark (value_mark ()); + res_val = value_addr (val_obj->value); + val_obj->address = value_to_value_object (res_val); + do_cleanups (cleanup); } if (except.reason < 0) { val_obj->address = Py_None; Py_INCREF (Py_None); } - else - val_obj->address = value_to_value_object (res_val); } Py_XINCREF (val_obj->address); @@ -248,6 +256,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure) TRY_CATCH (except, RETURN_MASK_ALL) { struct value *val = obj->value; + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); type = value_type (val); CHECK_TYPEDEF (type); @@ -277,6 +286,8 @@ valpy_get_dynamic_type (PyObject *self, void *closure) /* Re-use object's static type. */ type = NULL; } + + do_cleanups (cleanup); } GDB_PY_HANDLE_EXCEPTION (except); @@ -311,7 +322,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw) struct value *value = ((value_object *) self)->value; const char *user_encoding = NULL; static char *keywords[] = { "encoding", "length", NULL }; - PyObject *str_obj; + PyObject *str_obj = NULL; volatile struct gdb_exception except; if (!PyArg_ParseTupleAndKeywords (args, kw, "|s" GDB_PY_LL_ARG, keywords, @@ -320,16 +331,20 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw) TRY_CATCH (except, RETURN_MASK_ALL) { + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR) value = value_ind (value); + + str_obj = gdbpy_create_lazy_string_object (value_address (value), length, + user_encoding, + value_type (value)); + + do_cleanups (cleanup); } GDB_PY_HANDLE_EXCEPTION (except); - str_obj = gdbpy_create_lazy_string_object (value_address (value), length, - user_encoding, - value_type (value)); - - return (PyObject *) str_obj; + return str_obj; } /* Implementation of gdb.Value.string ([encoding] [, errors] @@ -376,9 +391,8 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw) static PyObject * valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op) { - PyObject *type_obj; + PyObject *type_obj, *result = NULL; struct type *type; - struct value *res_val = NULL; /* Initialize to appease gcc warning. */ volatile struct gdb_exception except; if (! PyArg_ParseTuple (args, "O", &type_obj)) @@ -395,6 +409,8 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op) TRY_CATCH (except, RETURN_MASK_ALL) { struct value *val = ((value_object *) self)->value; + struct value *res_val; + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); if (op == UNOP_DYNAMIC_CAST) res_val = value_dynamic_cast (type, val); @@ -405,10 +421,13 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op) gdb_assert (op == UNOP_CAST); res_val = value_cast (type, val); } + + result = value_to_value_object (res_val); + do_cleanups (cleanup); } GDB_PY_HANDLE_EXCEPTION (except); - return value_to_value_object (res_val); + return result; } /* Implementation of the "cast" method. */ @@ -451,8 +470,8 @@ valpy_getitem (PyObject *self, PyObject *key) { value_object *self_value = (value_object *) self; char *field = NULL; - struct value *res_val = NULL; volatile struct gdb_exception except; + PyObject *result = NULL; if (gdbpy_is_string (key)) { @@ -464,6 +483,8 @@ valpy_getitem (PyObject *self, PyObject *key) TRY_CATCH (except, RETURN_MASK_ALL) { struct value *tmp = self_value->value; + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + struct value *res_val = NULL; if (field) res_val = value_struct_elt (&tmp, NULL, field, 0, NULL); @@ -489,12 +510,16 @@ valpy_getitem (PyObject *self, PyObject *key) res_val = value_subscript (tmp, value_as_long (idx)); } } + + if (res_val) + result = value_to_value_object (res_val); + do_cleanups (cleanup); } xfree (field); GDB_PY_HANDLE_EXCEPTION (except); - return res_val ? value_to_value_object (res_val) : NULL; + return result; } static int @@ -510,12 +535,13 @@ valpy_setitem (PyObject *self, PyObject *key, PyObject *value) static PyObject * valpy_call (PyObject *self, PyObject *args, PyObject *keywords) { - struct value *return_value = NULL; Py_ssize_t args_count; volatile struct gdb_exception except; struct value *function = ((value_object *) self)->value; struct value **vargs = NULL; struct type *ftype = NULL; + struct value *mark = value_mark (); + PyObject *result = NULL; TRY_CATCH (except, RETURN_MASK_ALL) { @@ -558,11 +584,16 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords) TRY_CATCH (except, RETURN_MASK_ALL) { + struct cleanup *cleanup = make_cleanup_value_free_to_mark (mark); + struct value *return_value; + return_value = call_function_by_hand (function, args_count, vargs); + result = value_to_value_object (return_value); + do_cleanups (cleanup); } GDB_PY_HANDLE_EXCEPTION (except); - return value_to_value_object (return_value); + return result; } /* Called by the Python interpreter to obtain string representation @@ -687,12 +718,14 @@ enum valpy_opcode static PyObject * valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other) { - struct value *res_val = NULL; /* Initialize to appease gcc warning. */ volatile struct gdb_exception except; + PyObject *result = NULL; TRY_CATCH (except, RETURN_MASK_ALL) { struct value *arg1, *arg2; + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + struct value *res_val; /* If the gdb.Value object is the second operand, then it will be passed to us as the OTHER argument, and SELF will be an entirely different @@ -778,10 +811,15 @@ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other) res_val = value_binop (arg1, arg2, BINOP_BITWISE_XOR); break; } + + if (res_val) + result = value_to_value_object (res_val); + + do_cleanups (cleanup); } GDB_PY_HANDLE_EXCEPTION (except); - return res_val ? value_to_value_object (res_val) : NULL; + return result; } static PyObject * @@ -833,16 +871,22 @@ valpy_power (PyObject *self, PyObject *other, PyObject *unused) static PyObject * valpy_negative (PyObject *self) { - struct value *val = NULL; volatile struct gdb_exception except; + PyObject *result = NULL; TRY_CATCH (except, RETURN_MASK_ALL) { + /* Perhaps overkill, but consistency has some virtue. */ + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + struct value *val; + val = value_neg (((value_object *) self)->value); + result = value_to_value_object (val); + do_cleanups (cleanup); } GDB_PY_HANDLE_EXCEPTION (except); - return value_to_value_object (val); + return result; } static PyObject * @@ -860,8 +904,12 @@ valpy_absolute (PyObject *self) TRY_CATCH (except, RETURN_MASK_ALL) { + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + if (value_less (value, value_zero (value_type (value), not_lval))) isabs = 0; + + do_cleanups (cleanup); } GDB_PY_HANDLE_EXCEPTION (except); @@ -961,7 +1009,6 @@ static PyObject * valpy_richcompare (PyObject *self, PyObject *other, int op) { int result = 0; - struct value *value_other; volatile struct gdb_exception except; if (other == Py_None) @@ -985,6 +1032,9 @@ valpy_richcompare (PyObject *self, PyObject *other, int op) TRY_CATCH (except, RETURN_MASK_ALL) { + struct value *value_other, *mark = value_mark (); + struct cleanup *cleanup; + value_other = convert_value_from_python (other); if (value_other == NULL) { @@ -992,6 +1042,8 @@ valpy_richcompare (PyObject *self, PyObject *other, int op) break; } + cleanup = make_cleanup_value_free_to_mark (mark); + switch (op) { case Py_LT: result = value_less (((value_object *) self)->value, value_other); @@ -1020,6 +1072,8 @@ valpy_richcompare (PyObject *self, PyObject *other, int op) result = -1; break; } + + do_cleanups (cleanup); } GDB_PY_HANDLE_EXCEPTION (except); -- cgit v1.1