try
{
+ scoped_value_mark free_values;
+
struct symbol *func_symbol =
symbol_object_to_symbol (self_finishbp->func_symbol);
struct value *function =
/* Remember only non-void return types. */
if (ret_type->code () != TYPE_CODE_VOID)
{
+ scoped_value_mark free_values;
+
/* Ignore Python errors at this stage. */
value *func_value = read_var_value (function, NULL, frame);
self_bpfinish->function_value
frapy_read_register (PyObject *self, PyObject *args)
{
PyObject *pyo_reg_id;
- struct value *val = NULL;
+ PyObject *result = nullptr;
if (!PyArg_UnpackTuple (args, "read_register", 1, 1, &pyo_reg_id))
return NULL;
try
{
+ scoped_value_mark free_values;
frame_info_ptr frame;
int regnum;
return nullptr;
gdb_assert (regnum >= 0);
- val = value_of_register (regnum, frame);
+ struct value *val = value_of_register (regnum, frame);
if (val == NULL)
PyErr_SetString (PyExc_ValueError, _("Can't read register."));
+ else
+ result = value_to_value_object (val);
}
catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- return val == NULL ? NULL : value_to_value_object (val);
+ return result;
}
/* Implementation of gdb.Frame.block (self) -> gdb.Block.
PyObject *sym_obj, *block_obj = NULL;
struct symbol *var = NULL; /* gcc-4.3.2 false warning. */
const struct block *block = NULL;
- struct value *val = NULL;
if (!PyArg_ParseTuple (args, "O|O", &sym_obj, &block_obj))
return NULL;
return NULL;
}
+ PyObject *result = nullptr;
try
{
FRAPY_REQUIRE_VALID (self, frame);
- val = read_var_value (var, block, frame);
+ scoped_value_mark free_values;
+ struct value *val = read_var_value (var, block, frame);
+ result = value_to_value_object (val);
}
catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- return value_to_value_object (val);
+ return result;
}
/* Select this frame. */
stpy_convert_to_value (PyObject *self, PyObject *args)
{
lazy_string_object *self_string = (lazy_string_object *) self;
- struct value *val = NULL;
if (self_string->address == 0)
{
return NULL;
}
+ PyObject *result = nullptr;
try
{
+ scoped_value_mark free_values;
+
struct type *type = type_object_to_type (self_string->type);
struct type *realtype;
+ struct value *val;
gdb_assert (type != NULL);
realtype = check_typedef (type);
val = value_at_lazy (type, self_string->address);
break;
}
+
+ result = value_to_value_object (val);
}
catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- return value_to_value_object (val);
+ return result;
}
static void
gdbpy_enter enter_py (gdbarch, language);
- gdbpy_ref<> val_obj (value_to_value_object_no_release (value));
+ gdbpy_ref<> val_obj (value_to_value_object (value));
if (val_obj == NULL)
{
print_stack_unless_memory_error (stream);
struct symbol *symbol = NULL;
frame_info_ptr frame_info = NULL;
PyObject *frame_obj = NULL;
- struct value *value = NULL;
if (!PyArg_ParseTuple (args, "|O", &frame_obj))
return NULL;
return NULL;
}
+ PyObject *result = nullptr;
try
{
if (frame_obj != NULL)
was found, so we have no block to pass to read_var_value. This will
yield an incorrect value when symbol is not local to FRAME_INFO (this
can happen with nested functions). */
- value = read_var_value (symbol, NULL, frame_info);
+ scoped_value_mark free_values;
+ struct value *value = read_var_value (symbol, NULL, frame_info);
+ result = value_to_value_object (value);
}
catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- return value_to_value_object (value);
+ return result;
}
/* Given a symbol, and a symbol_object that has previously been
const struct block *block = NULL;
PyObject *block_obj = NULL;
struct symbol *sym;
- struct value *val = NULL;
if (! PyArg_ParseTuple (args, "i|O", &argno, &block_obj))
return NULL;
return NULL;
}
+ PyObject *result = nullptr;
try
{
- val = value_of_variable (sym, block);
+ scoped_value_mark free_values;
+ struct value *val = value_of_variable (sym, block);
+ result = value_to_value_object (val);
}
catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- return value_to_value_object (val);
+ return result;
}
static PyObject *
{
struct type *type = ((type_object *) self)->type;
+ scoped_value_mark free_values;
return value_to_value_object (value::allocate_optimized_out (type));
}
pending_framepy_read_register (PyObject *self, PyObject *args)
{
pending_frame_object *pending_frame = (pending_frame_object *) self;
- struct value *val = NULL;
int regnum;
PyObject *pyo_reg_id;
if (!gdbpy_parse_register_id (pending_frame->gdbarch, pyo_reg_id, ®num))
return nullptr;
+ PyObject *result = nullptr;
try
{
+ scoped_value_mark free_values;
+
/* Fetch the value associated with a register, whether it's
a real register or a so called "user" register, like "pc",
which maps to a real register. In the past,
get_frame_register_value() was used here, which did not
handle the user register case. */
- val = value_of_register (regnum, pending_frame->frame_info);
+ struct value *val = value_of_register (regnum,
+ pending_frame->frame_info);
if (val == NULL)
PyErr_Format (PyExc_ValueError,
"Cannot read register %d from frame.",
regnum);
+ else
+ result = value_to_value_object (val);
}
catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- return val == NULL ? NULL : value_to_value_object (val);
+ return result;
}
/* Implementation of
static PyObject *
valpy_invert (PyObject *self)
{
- struct value *val = NULL;
+ PyObject *result = nullptr;
try
{
- val = value_complement (((value_object *) self)->value);
+ scoped_value_mark free_values;
+ struct value *val = value_complement (((value_object *) self)->value);
+ result = value_to_value_object (val);
}
catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- return value_to_value_object (val);
+ return result;
}
/* Implements left shift for value objects. */
return PyFloat_FromDouble (d);
}
-/* Returns an object for a value which is released from the all_values chain,
- so its lifetime is not bound to the execution of a command. */
-PyObject *
-value_to_value_object (struct value *val)
-{
- value_object *val_obj;
-
- val_obj = PyObject_New (value_object, &value_object_type);
- if (val_obj != NULL)
- {
- val_obj->value = release_value (val).release ();
- val_obj->next = nullptr;
- val_obj->prev = nullptr;
- val_obj->address = NULL;
- val_obj->type = NULL;
- val_obj->dynamic_type = NULL;
- note_value (val_obj);
- }
-
- return (PyObject *) val_obj;
-}
-
-/* Returns an object for a value, but without releasing it from the
+/* Returns an object for a value, without releasing it from the
all_values chain. */
PyObject *
-value_to_value_object_no_release (struct value *val)
+value_to_value_object (struct value *val)
{
value_object *val_obj;
gdbpy_history (PyObject *self, PyObject *args)
{
int i;
- struct value *res_val = NULL; /* Initialize to appease gcc warning. */
if (!PyArg_ParseTuple (args, "i", &i))
return NULL;
+ PyObject *result = nullptr;
try
{
- res_val = access_value_history (i);
+ scoped_value_mark free_values;
+ struct value *res_val = access_value_history (i);
+ result = value_to_value_object (res_val);
}
catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- return value_to_value_object (res_val);
+ return result;
}
/* Add a gdb.Value into GDB's history, and return (as an integer) the
if (!PyArg_ParseTuple (args, "s", &varname))
return NULL;
+ PyObject *result = nullptr;
+ bool found = false;
try
{
struct internalvar *var = lookup_only_internalvar (varname);
if (var != NULL)
{
+ scoped_value_mark free_values;
res_val = value_of_internalvar (gdbpy_enter::get_gdbarch (), var);
if (res_val->type ()->code () == TYPE_CODE_VOID)
res_val = NULL;
+ else
+ {
+ found = true;
+ result = value_to_value_object (res_val);
+ }
}
}
catch (const gdb_exception &except)
GDB_PY_HANDLE_EXCEPTION (except);
}
- if (res_val == NULL)
+ if (result == nullptr && !found)
Py_RETURN_NONE;
- return value_to_value_object (res_val);
+ return result;
}
/* Set the value of a convenience variable. */
return EXT_LANG_RC_OK;
}
+ scoped_value_mark free_values;
obj_type = check_typedef (obj->type ());
this_type = check_typedef (type_object_to_type (m_this_type));
if (obj_type->code () == TYPE_CODE_PTR)
PyObject *block_to_block_object (const struct block *block,
struct objfile *objfile);
PyObject *value_to_value_object (struct value *v);
-PyObject *value_to_value_object_no_release (struct value *v);
PyObject *type_to_type_object (struct type *);
PyObject *frame_info_to_frame_object (frame_info_ptr frame);
PyObject *symtab_to_linetable_object (PyObject *symtab);
gdbpy_parse_and_eval (PyObject *self, PyObject *args)
{
const char *expr_str;
- struct value *result = NULL;
if (!PyArg_ParseTuple (args, "s", &expr_str))
return NULL;
+ PyObject *result = nullptr;
try
{
gdbpy_allow_threads allow_threads;
- result = parse_and_eval (expr_str);
+ scoped_value_mark free_values;
+ struct value *val = parse_and_eval (expr_str);
+ result = value_to_value_object (val);
}
catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- return value_to_value_object (result);
+ return result;
}
/* Implementation of gdb.invalidate_cached_frames. */
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2023 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+typedef int pp_int;
+
+int break_function()
+{
+ return 0;
+}
+
+struct container
+{
+ pp_int p_i;
+ int i;
+};
+
+int main()
+{
+ struct container c = { 10, 5 };
+ return break_function();
+}
--- /dev/null
+# Copyright (C) 2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test casting of a gdb.Value inside a pretty printer.
+
+load_lib gdb-python.exp
+
+require allow_python_tests
+
+standard_testfile
+
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
+ return -1
+}
+
+if ![runto break_function] {
+ return -1
+}
+
+set remote_python_file [gdb_remote_download host \
+ ${srcdir}/${subdir}/${testfile}.py]
+
+gdb_test_no_output "source ${remote_python_file}" \
+ "source ${testfile}.py"
+
+gdb_test "up" "#1.*main.*"
+
+gdb_test "info locals" "c = {p_i = 10p, i = 5}"
--- /dev/null
+# Copyright (C) 2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+class PpIntPrinter(object):
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ val = self.val.cast(self.val.type)
+ return "%dp" % int(val)
+
+
+pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-cast")
+pp.add_printer("pp_int", "^pp_int$", PpIntPrinter)
+gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)