aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2024-01-04 10:57:40 +0000
committerAndrew Burgess <aburgess@redhat.com>2024-01-12 11:21:27 +0000
commitd6defe8761ca7db47e3c1e1168f7869ffbb7e087 (patch)
tree0dc36d76c7de7e15445a0cb7f2185f23d4eb22b2 /gdb
parent1925bba80edd37c2ef90ef1d2c599dfc2fc17f72 (diff)
downloadfsf-binutils-gdb-d6defe8761ca7db47e3c1e1168f7869ffbb7e087.zip
fsf-binutils-gdb-d6defe8761ca7db47e3c1e1168f7869ffbb7e087.tar.gz
fsf-binutils-gdb-d6defe8761ca7db47e3c1e1168f7869ffbb7e087.tar.bz2
gdb/python: add gdb.Frame.__repr__() method
Add a gdb.Frame.__repr__() method. Before this patch we would see output like this: (gdb) pi >>> gdb.selected_frame() <gdb.Frame object at 0x7fa8cc2df270> After this patch, we now see: (gdb) pi >>> gdb.selected_frame() <gdb.Frame level=0 frame-id={stack=0x7ffff7da0ed0,code=0x000000000040115d,!special}> More verbose, but, I hope, more useful. If the gdb.Frame becomes invalid, then we will see: (gdb) pi >>> invalid_frame_variable <gdb.Frame (invalid)> which is inline with how other invalid objects are displayed. Approved-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb')
-rw-r--r--gdb/python/py-frame.c19
-rw-r--r--gdb/testsuite/gdb.python/py-frame.exp8
2 files changed, 26 insertions, 1 deletions
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index f38bf5d..ee465ed 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -84,6 +84,23 @@ frapy_str (PyObject *self)
return PyUnicode_FromString (fid.to_string ().c_str ());
}
+/* Implement repr() for gdb.Frame. */
+
+static PyObject *
+frapy_repr (PyObject *self)
+{
+ frame_object *frame_obj = (frame_object *) self;
+ frame_info_ptr f_info = frame_find_by_id (frame_obj->frame_id);
+ if (f_info == nullptr)
+ return gdb_py_invalid_object_repr (self);
+
+ const frame_id &fid = frame_obj->frame_id;
+ return PyUnicode_FromFormat ("<%s level=%d frame-id=%s>",
+ Py_TYPE (self)->tp_name,
+ frame_relative_level (f_info),
+ fid.to_string ().c_str ());
+}
+
/* Implementation of gdb.Frame.is_valid (self) -> Boolean.
Returns True if the frame corresponding to the frame_id of this
object still exists in the inferior. */
@@ -840,7 +857,7 @@ PyTypeObject frame_object_type = {
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
- 0, /* tp_repr */
+ frapy_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp
index 16177c8..6162696 100644
--- a/gdb/testsuite/gdb.python/py-frame.exp
+++ b/gdb/testsuite/gdb.python/py-frame.exp
@@ -36,6 +36,10 @@ gdb_breakpoint [gdb_get_line_number "Block break here."]
gdb_continue_to_breakpoint "Block break here."
gdb_py_test_silent_cmd "python bf1 = gdb.selected_frame ()" "get frame" 0
+# Test Frame.__repr__() method for a valid Frame object.
+gdb_test "python print (repr(bf1))" "<gdb\\.Frame level=0 frame-id=\\{\[^\r\n\]+\\}>" \
+ "test __repr__ for gdb.Frame on a valid frame"
+
# Test Frame.architecture() method.
gdb_py_test_silent_cmd "python show_arch_str = gdb.execute(\"show architecture\", to_string=True)" "show arch" 0
gdb_test "python print (bf1.architecture().name() in show_arch_str)" "True" "test Frame.architecture()"
@@ -100,6 +104,10 @@ gdb_py_test_silent_cmd "python bframe = gdb.selected_frame()" \
"get bottommost frame" 0
gdb_test "up" ".*" ""
+# Test Frame.__repr__() method for an invalid Frame object.
+gdb_test "python print (repr(bf1))" "<gdb\\.Frame \\(invalid\\)>" \
+ "test __repr__ for gdb.Frame on an invalid frame"
+
gdb_py_test_silent_cmd "python f1 = gdb.selected_frame ()" "get second frame" 0
gdb_py_test_silent_cmd "python f0 = f1.newer ()" "get first frame" 0
gdb_py_test_silent_cmd "python f2 = f1.older ()" "get last frame" 0