public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] Export "finish" return value to Python
@ 2024-03-08 17:56 Tom Tromey
  0 siblings, 0 replies; only message in thread
From: Tom Tromey @ 2024-03-08 17:56 UTC (permalink / raw)
  To: gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=99761c5ab53e11105b6067bc4314e74bb066006c

commit 99761c5ab53e11105b6067bc4314e74bb066006c
Author: Tom Tromey <tromey@adacore.com>
Date:   Mon Feb 12 08:12:02 2024 -0700

    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>

Diff:
---
 gdb/doc/python.texi       |  6 ++++++
 gdb/infcmd.c              | 17 -----------------
 gdb/python/py-stopevent.c | 23 ++++++++++++++++++++++-
 gdb/thread-fsm.h          | 19 +++++++++++++++++++
 4 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 4ae72716f56..4ca3ae4eca4 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -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}.
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index c1fdbb300c6..ac41ebf11b4 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -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
diff --git a/gdb/python/py-stopevent.c b/gdb/python/py-stopevent.c
index 61d93727b31..fcaebe26f13 100644
--- a/gdb/python/py-stopevent.c
+++ b/gdb/python/py-stopevent.c
@@ -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
diff --git a/gdb/thread-fsm.h b/gdb/thread-fsm.h
index 90abb5c27f6..ed117719c0d 100644
--- a/gdb/thread-fsm.h
+++ b/gdb/thread-fsm.h
@@ -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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-03-08 17:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-08 17:56 [binutils-gdb] Export "finish" return value to Python Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).