Export "finish" return value to Python

This patch changes the Python "stop" event emission code to also add
the function return value, if it is known.  This happens when the stop
comes from a "finish" command and when the value can be fetched.

The test is in the next patch.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
This commit is contained in:
Tom Tromey
2024-02-12 08:12:02 -07:00
parent 03fa0c63d3
commit 99761c5ab5
4 changed files with 47 additions and 18 deletions

View File

@@ -3813,6 +3813,12 @@ corresponding MI output (@pxref{GDB/MI Async Records}).
A dictionary was used for this (rather than adding attributes directly
to the event object) so that the MI keys could be used unchanged.
When a @code{StopEvent} results from a @code{finish} command, it will
also hold the return value from the function, if that is available.
This will be an entry named @samp{return-value} in the @code{details}
dictionary. The value of this entry will be a @code{gdb.Value}
object.
@end defvar
Emits @code{gdb.SignalEvent}, which extends @code{gdb.StopEvent}.

View File

@@ -1484,23 +1484,6 @@ get_return_value (struct symbol *func_symbol, struct value *function)
return value;
}
/* The captured function return value/type and its position in the
value history. */
struct return_value_info
{
/* The captured return value. May be NULL if we weren't able to
retrieve it. See get_return_value. */
struct value *value;
/* The return type. In some cases, we'll not be able extract the
return value, but we always know the type. */
struct type *type;
/* If we captured a value, this is the value history index. */
int value_history_index;
};
/* Helper for print_return_value. */
static void

View File

@@ -20,6 +20,7 @@
#include "defs.h"
#include "py-stopevent.h"
#include "py-uiout.h"
#include "thread-fsm.h"
gdbpy_ref<>
create_stop_event_object (PyTypeObject *py_type, const gdbpy_ref<> &dict)
@@ -45,6 +46,7 @@ static gdbpy_ref<>
py_print_bpstat (bpstat *bs, enum gdb_signal stop_signal)
{
py_ui_out uiout;
struct value *return_value = nullptr;
try
{
@@ -55,6 +57,10 @@ py_print_bpstat (bpstat *bs, enum gdb_signal stop_signal)
{
async_reply_reason reason = tp->thread_fsm ()->async_reply_reason ();
uiout.field_string ("reason", async_reason_lookup (reason));
return_value_info *rvinfo = tp->thread_fsm ()->return_value ();
if (rvinfo != nullptr && rvinfo->value != nullptr)
return_value = rvinfo->value;
}
if (stop_signal != GDB_SIGNAL_0 && stop_signal != GDB_SIGNAL_TRAP)
@@ -73,7 +79,22 @@ py_print_bpstat (bpstat *bs, enum gdb_signal stop_signal)
return nullptr;
}
return uiout.result ();
gdbpy_ref<> dict = uiout.result ();
if (dict == nullptr)
return nullptr;
/* This has to be done separately to avoid error issues, and because
there's no API to add generic Python objects to a py_ui_out. */
if (return_value != nullptr)
{
gdbpy_ref<> val (value_to_value_object (return_value));
if (val == nullptr)
return nullptr;
if (PyDict_SetItemString (dict.get (), "finish-value", val.get ()) < 0)
return nullptr;
}
return dict;
}
/* Callback observers when a stop event occurs. This function will create a

View File

@@ -23,6 +23,25 @@
struct return_value_info;
struct thread_fsm_ops;
struct type;
struct value;
/* The captured function return value/type and its position in the
value history. */
struct return_value_info
{
/* The captured return value. May be NULL if we weren't able to
retrieve it. See get_return_value. */
struct value *value;
/* The return type. In some cases, we'll not be able extract the
return value, but we always know the type. */
struct type *type;
/* If we captured a value, this is the value history index. */
int value_history_index;
};
/* A thread finite-state machine structure contains the necessary info
and callbacks to manage the state machine protocol of a thread's