aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2021-05-26 22:01:59 +0100
committerAndrew Burgess <andrew.burgess@embecosm.com>2021-06-21 16:20:08 +0100
commitd52b8007213eea4d1f33e3a604481f390d37b52a (patch)
tree07158fe01e4d4d0edc2bf3e043d13198cb21d96e /gdb/python
parent8b9c48b287d42d1c816f441e4273dcb8c7af1876 (diff)
downloadbinutils-d52b8007213eea4d1f33e3a604481f390d37b52a.zip
binutils-d52b8007213eea4d1f33e3a604481f390d37b52a.tar.gz
binutils-d52b8007213eea4d1f33e3a604481f390d37b52a.tar.bz2
gdb/python: add PendingFrame.level and Frame.level methods
Add new methods to the PendingFrame and Frame classes to obtain the stack frame level for each object. The use of 'level' as the method name is consistent with the existing attribute RecordFunctionSegment.level (though this is an attribute rather than a method). For Frame/PendingFrame I went with methods as these classes currently only use methods, including for simple data like architecture, so I want to be consistent with this interface. gdb/ChangeLog: * NEWS: Mention the two new methods. * python/py-frame.c (frapy_level): New function. (frame_object_methods): Register 'level' method. * python/py-unwind.c (pending_framepy_level): New function. (pending_frame_object_methods): Register 'level' method. gdb/doc/ChangeLog: * python.texi (Unwinding Frames in Python): Mention PendingFrame.level. (Frames In Python): Mention Frame.level. gdb/testsuite/ChangeLog: * gdb.python/py-frame.exp: Add Frame.level tests. * gdb.python/py-pending-frame-level.c: New file. * gdb.python/py-pending-frame-level.exp: New file. * gdb.python/py-pending-frame-level.py: New file.
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/py-frame.c23
-rw-r--r--gdb/python/py-unwind.c19
2 files changed, 42 insertions, 0 deletions
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index c8eab52..ee57eb1 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -577,6 +577,27 @@ frapy_select (PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
+/* The stack frame level for this frame. */
+
+static PyObject *
+frapy_level (PyObject *self, PyObject *args)
+{
+ struct frame_info *fi;
+
+ try
+ {
+ FRAPY_REQUIRE_VALID (self, fi);
+
+ return gdb_py_object_from_longest (frame_relative_level (fi)).release ();
+ }
+ catch (const gdb_exception &except)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+
+ Py_RETURN_NONE;
+}
+
/* Implementation of gdb.newest_frame () -> gdb.Frame.
Returns the newest frame object. */
@@ -748,6 +769,8 @@ Return the frame's symtab and line." },
Return the value of the variable in this frame." },
{ "select", frapy_select, METH_NOARGS,
"Select this frame as the user's current frame." },
+ { "level", frapy_level, METH_NOARGS,
+ "The stack level of this frame." },
{NULL} /* Sentinel */
};
diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c
index d6e2f85..d3ef191 100644
--- a/gdb/python/py-unwind.c
+++ b/gdb/python/py-unwind.c
@@ -463,6 +463,23 @@ pending_framepy_architecture (PyObject *self, PyObject *args)
return gdbarch_to_arch_object (pending_frame->gdbarch);
}
+/* Implementation of PendingFrame.level (self) -> Integer. */
+
+static PyObject *
+pending_framepy_level (PyObject *self, PyObject *args)
+{
+ pending_frame_object *pending_frame = (pending_frame_object *) self;
+
+ if (pending_frame->frame_info == NULL)
+ {
+ PyErr_SetString (PyExc_ValueError,
+ "Attempting to read stack level from stale PendingFrame");
+ return NULL;
+ }
+ int level = frame_relative_level (pending_frame->frame_info);
+ return gdb_py_object_from_longest (level).release ();
+}
+
/* frame_unwind.this_id method. */
static void
@@ -704,6 +721,8 @@ static PyMethodDef pending_frame_object_methods[] =
pending_framepy_architecture, METH_NOARGS,
"architecture () -> gdb.Architecture\n"
"The architecture for this PendingFrame." },
+ { "level", pending_framepy_level, METH_NOARGS,
+ "The stack level of this frame." },
{NULL} /* Sentinel */
};