Add gdb.Frame.static_link method
authorTom Tromey <tromey@adacore.com>
Tue, 24 Oct 2023 14:05:06 +0000 (08:05 -0600)
committerTom Tromey <tromey@adacore.com>
Tue, 14 Nov 2023 15:44:30 +0000 (08:44 -0700)
This adds a new gdb.Frame.static_link method to the gdb Python layer.
This can be used to find the static link frame for a given frame.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
gdb/NEWS
gdb/doc/python.texi
gdb/python/py-frame.c

index 96aba256dbbf804d96a0465cf686fd4281edf0e7..93fbcf1c13e69db0507bef206a7a403a893b7d77 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -424,6 +424,9 @@ show tui mouse-events
 
   ** gdb.LazyString now implements the __str__ method.
 
+  ** New method gdb.Frame.static_link that returns the outer frame
+     of a nested function frame.
+
 *** Changes in GDB 13
 
 * MI version 1 is deprecated, and will be removed in GDB 14.
index c26949e051080c5771e268eb58f15dec116b3fca..c3dfc7ae0faaa499da4cce29b33db9f1c15a282a 100644 (file)
@@ -5739,6 +5739,16 @@ Set this frame to be the selected frame.  @xref{Stack, ,Examining the
 Stack}.
 @end defun
 
+@defun Frame.static_link ()
+In some languages (e.g., Ada, but also a GNU C extension), a nested
+function can access the variables in the outer scope.  This is done
+via a ``static link'', which is a reference from the nested frame to
+the appropriate outer frame.
+
+This method returns this frame's static link frame, if one exists.  If
+there is no static link, this method returns @code{None}.
+@end defun
+
 @defun Frame.level ()
 Return an integer, the stack frame level for this frame.  @xref{Frames, ,Stack Frames}.
 @end defun
index 1a55e514e3964acb3aa601b23f6c732fd24c6bb4..0a7e10f09ff2493faaa3c4c6a61cff70ed75ff99 100644 (file)
@@ -622,6 +622,30 @@ frapy_language (PyObject *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+/* The static link for this frame.  */
+
+static PyObject *
+frapy_static_link (PyObject *self, PyObject *args)
+{
+  frame_info_ptr link;
+
+  try
+    {
+      FRAPY_REQUIRE_VALID (self, link);
+
+      link = frame_follow_static_link (link);
+    }
+  catch (const gdb_exception &except)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+
+  if (link == nullptr)
+    Py_RETURN_NONE;
+
+  return frame_info_to_frame_object (link);
+}
+
 /* Implementation of gdb.newest_frame () -> gdb.Frame.
    Returns the newest frame object.  */
 
@@ -800,6 +824,8 @@ Return the value of the variable in this frame." },
     "The stack level of this frame." },
   { "language", frapy_language, METH_NOARGS,
     "The language of this frame." },
+  { "static_link", frapy_static_link, METH_NOARGS,
+    "The static link of this frame, or None." },
   {NULL}  /* Sentinel */
 };