diff options
-rw-r--r-- | gdb/infcmd.c | 11 | ||||
-rw-r--r-- | gdb/inferior.h | 10 | ||||
-rw-r--r-- | gdb/python/py-finishbreakpoint.c | 57 |
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; |