aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/infcmd.c11
-rw-r--r--gdb/inferior.h10
-rw-r--r--gdb/python/py-finishbreakpoint.c57
3 files changed, 44 insertions, 34 deletions
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 0e1cfcb..1dc4e36 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1444,18 +1444,17 @@ advance_command (const char *arg, int from_tty)
until_break_command (arg, from_tty, 1);
}
-/* Return the value of the result of a function at the end of a 'finish'
- command/BP. DTOR_DATA (if not NULL) can represent inferior registers
- right after an inferior call has finished. */
+/* See inferior.h. */
struct value *
-get_return_value (struct value *function, struct type *value_type)
+get_return_value (struct symbol *func_symbol, struct value *function)
{
regcache *stop_regs = get_current_regcache ();
struct gdbarch *gdbarch = stop_regs->arch ();
struct value *value;
- value_type = check_typedef (value_type);
+ struct type *value_type
+ = check_typedef (TYPE_TARGET_TYPE (func_symbol->type ()));
gdb_assert (value_type->code () != TYPE_CODE_VOID);
/* FIXME: 2003-09-27: When returning from a nested inferior function
@@ -1616,7 +1615,7 @@ finish_command_fsm::should_stop (struct thread_info *tp)
struct value *func;
func = read_var_value (function, NULL, get_current_frame ());
- rv->value = get_return_value (func, rv->type);
+ rv->value = get_return_value (function, func);
if (rv->value != NULL)
rv->value_history_index = record_latest_value (rv->value);
}
diff --git a/gdb/inferior.h b/gdb/inferior.h
index ec0fb6e..45de3c2 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -219,8 +219,14 @@ extern void detach_command (const char *, int);
extern void notice_new_inferior (struct thread_info *, bool, int);
-extern struct value *get_return_value (struct value *function,
- struct type *value_type);
+/* Return the value of the result of a function at the end of a 'finish'
+ command/BP. If the result's value cannot be retrieved, return NULL.
+
+ FUNC_SYMBOL is the symbol of the function being returned from. FUNCTION is
+ a value containing the address of the function. */
+
+extern struct value *get_return_value (struct symbol *func_symbol,
+ struct value *function);
/* Prepare for execution command. TARGET is the target that will run
the command. BACKGROUND determines whether this is a foreground
diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c
index 77e19f6..083694f 100644
--- a/gdb/python/py-finishbreakpoint.c
+++ b/gdb/python/py-finishbreakpoint.c
@@ -40,13 +40,17 @@ struct finish_breakpoint_object
{
/* gdb.Breakpoint base class. */
gdbpy_breakpoint_object py_bp;
- /* gdb.Type object of the value return by the breakpointed function.
- May be NULL if no debug information was available or return type
- was VOID. */
- PyObject *return_type;
- /* gdb.Value object of the function finished by this breakpoint. Will be
- NULL if return_type is NULL. */
+
+ /* gdb.Symbol object of the function finished by this breakpoint.
+
+ nullptr if no debug information was available or return type was VOID. */
+ PyObject *func_symbol;
+
+ /* gdb.Value object of the function finished by this breakpoint.
+
+ nullptr if no debug information was available or return type was VOID. */
PyObject *function_value;
+
/* When stopped at this FinishBreakpoint, gdb.Value object returned by
the function; Py_None if the value is not computable; NULL if GDB is
not stopped at a FinishBreakpoint. */
@@ -80,8 +84,8 @@ bpfinishpy_dealloc (PyObject *self)
struct finish_breakpoint_object *self_bpfinish =
(struct finish_breakpoint_object *) self;
+ Py_XDECREF (self_bpfinish->func_symbol);
Py_XDECREF (self_bpfinish->function_value);
- Py_XDECREF (self_bpfinish->return_type);
Py_XDECREF (self_bpfinish->return_value);
Py_TYPE (self)->tp_free (self);
}
@@ -99,16 +103,17 @@ bpfinishpy_pre_stop_hook (struct gdbpy_breakpoint_object *bp_obj)
/* Can compute return_value only once. */
gdb_assert (!self_finishbp->return_value);
- if (!self_finishbp->return_type)
+ if (self_finishbp->func_symbol == nullptr)
return;
try
{
+ struct symbol *func_symbol =
+ symbol_object_to_symbol (self_finishbp->func_symbol);
struct value *function =
value_object_to_value (self_finishbp->function_value);
- struct type *value_type =
- type_object_to_type (self_finishbp->return_type);
- struct value *ret = get_return_value (function, value_type);
+ struct value *ret =
+ get_return_value (func_symbol, function);
if (ret)
{
@@ -165,7 +170,6 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
PyObject *internal = NULL;
int internal_bp = 0;
CORE_ADDR pc;
- struct symbol *function;
if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "|OO", keywords,
&frame_obj, &internal))
@@ -239,15 +243,15 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
}
/* Find the function we will return from. */
- self_bpfinish->return_type = NULL;
- self_bpfinish->function_value = NULL;
+ self_bpfinish->func_symbol = nullptr;
+ self_bpfinish->function_value = nullptr;
try
{
if (get_frame_pc_if_available (frame, &pc))
{
- function = find_pc_function (pc);
- if (function != NULL)
+ struct symbol *function = find_pc_function (pc);
+ if (function != nullptr)
{
struct type *ret_type =
check_typedef (TYPE_TARGET_TYPE (function->type ()));
@@ -255,14 +259,14 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
/* Remember only non-void return types. */
if (ret_type->code () != TYPE_CODE_VOID)
{
- struct value *func_value;
-
/* Ignore Python errors at this stage. */
- self_bpfinish->return_type = type_to_type_object (ret_type);
+ value *func_value = read_var_value (function, NULL, frame);
+ self_bpfinish->function_value
+ = value_to_value_object (func_value);
PyErr_Clear ();
- func_value = read_var_value (function, NULL, frame);
- self_bpfinish->function_value =
- value_to_value_object (func_value);
+
+ self_bpfinish->func_symbol
+ = symbol_to_symbol_object (function);
PyErr_Clear ();
}
}
@@ -274,14 +278,15 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
remain NULL. */
}
- if (self_bpfinish->return_type == NULL || self_bpfinish->function_value == NULL)
+ if (self_bpfinish->func_symbol == nullptr
+ || self_bpfinish->function_value == nullptr)
{
/* Won't be able to compute return value. */
- Py_XDECREF (self_bpfinish->return_type);
+ Py_XDECREF (self_bpfinish->func_symbol);
Py_XDECREF (self_bpfinish->function_value);
- self_bpfinish->return_type = NULL;
- self_bpfinish->function_value = NULL;
+ self_bpfinish->func_symbol = nullptr;
+ self_bpfinish->function_value = nullptr;
}
bppy_pending_object = &self_bpfinish->py_bp;