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.
This commit is contained in:
Andrew Burgess 2021-05-26 22:01:59 +01:00
parent 8b9c48b287
commit d52b800721
11 changed files with 258 additions and 0 deletions

View file

@ -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 */
};