gdb/python: Add architecture method to gdb.PendingFrame
authorAndrew Burgess <andrew.burgess@embecosm.com>
Sun, 7 Jun 2020 22:07:52 +0000 (23:07 +0100)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Mon, 6 Jul 2020 14:06:05 +0000 (15:06 +0100)
It could be useful to determine the architecture of a frame being
unwound during the frame unwind process, that is, before we have a
gdb.Frame, but when we only have a gdb.PendingFrame.

The PendingFrame already has a pointer to the gdbarch internally, this
commit just exposes an 'architecture' method to Python, and has this
return a gdb.Architecture object (list gdb.Frame.architecture does).

gdb/ChangeLog:

* NEWS: Mention new Python API method.
* python/py-unwind.c (pending_framepy_architecture): New function.
(pending_frame_object_methods): Add architecture method.

gdb/testsuite/ChangeLog:

* gdb.python/py-unwind.py (TestUnwinder::__call__): Add test for
gdb.PendingFrame.architecture method.

gdb/doc/ChangeLog:

* python.texi (Unwinding Frames in Python): Document
PendingFrame.architecture method.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/python.texi
gdb/python/py-unwind.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-unwind.py

index 0b73be8123c6890397790cd1b61ebcb1cc9c0560..1fac9a516faab3493777abc39b321dc7d7c9a37a 100644 (file)
@@ -1,3 +1,9 @@
+2020-07-06  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * NEWS: Mention new Python API method.
+       * python/py-unwind.c (pending_framepy_architecture): New function.
+       (pending_frame_object_methods): Add architecture method.
+
 2020-07-06  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * gdbarch.c: Regenerate.
index a116d62bca369b04e8cf5c3f1f6f0737122d40db..29db0734f87451b20b3aafe040ea67d6dc0793fc 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -117,6 +117,9 @@ GNU/Linux/RISC-V (gdbserver)        riscv*-*-linux*
   ** Commands written in Python can be in the "TUI" help class by
      registering with the new constant gdb.COMMAND_TUI.
 
+  ** New method gdb.PendingFrame.architecture () to retrieve the
+     architecture of the pending frame.
+
 *** Changes in GDB 9
 
 * 'thread-exited' event is now available in the annotations interface.
index c59193450825e5ca2df223783fdb879128c78a94..82ed257fb8401bf62c484e587c1cf4561e9912d1 100644 (file)
@@ -1,3 +1,8 @@
+2020-07-06  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * python.texi (Unwinding Frames in Python): Document
+       PendingFrame.architecture method.
+
 2020-06-26  Eli Zaretskii  <eliz@gnu.org>
 
        * gdb.texinfo (Shell Commands): More accurate description of use
index a38f1dab426eb0e1413865e326c6690f16a83c64..fff7e5b0128af1540f07cff1fd829a997224f6b2 100644 (file)
@@ -2518,6 +2518,12 @@ Each attribute value should be an instance of @code{gdb.Value}.
 
 @end defun
 
+@defun PendingFrame.architecture ()
+Return the @code{gdb.Architecture} (@pxref{Architectures In Python})
+for this @code{gdb.PendingFrame}.  This represents the architecture of
+the particular frame being unwound.
+@end defun
+
 @subheading Unwinder Output: UnwindInfo
 
 Use @code{PendingFrame.create_unwind_info} method described above to
index d583ff462b08df6b76eaeab3a47efe18753a5e0a..1cef491cedf5b7495ee9d4a15c1d61789cc67d6f 100644 (file)
@@ -441,6 +441,22 @@ pending_framepy_create_unwind_info (PyObject *self, PyObject *args)
                                     frame_id_build_special (sp, pc, special));
 }
 
+/* Implementation of PendingFrame.architecture (self) -> gdb.Architecture.  */
+
+static PyObject *
+pending_framepy_architecture (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 register from stale PendingFrame");
+      return NULL;
+    }
+  return gdbarch_to_arch_object (pending_frame->gdbarch);
+}
+
 /* frame_unwind.this_id method.  */
 
 static void
@@ -671,6 +687,10 @@ static PyMethodDef pending_frame_object_methods[] =
     "create_unwind_info (FRAME_ID) -> gdb.UnwindInfo\n"
     "Construct UnwindInfo for this PendingFrame, using FRAME_ID\n"
     "to identify it." },
+  { "architecture",
+    pending_framepy_architecture, METH_NOARGS,
+    "architecture () -> gdb.Architecture\n"
+    "The architecture for this PendingFrame." },
   {NULL}  /* Sentinel */
 };
 
index f75ba7d9cf787b1283dc2092a005f7a5937afc8f..bf5b89bd0f787dc03eb3543cd52cc3e47e2936ff 100644 (file)
@@ -1,3 +1,8 @@
+2020-07-06  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * gdb.python/py-unwind.py (TestUnwinder::__call__): Add test for
+       gdb.PendingFrame.architecture method.
+
 2020-07-06  Tom de Vries  <tdevries@suse.de>
 
        * gdb.dwarf2/dw2-ranges-base.exp: Test line-table order.
index 42dd6fe138cc2b1d1133f96474d7a4a58606f735..d01da80f25ba509975cc64abbc756c7d88199e84 100644 (file)
@@ -30,7 +30,6 @@ class FrameId(object):
     def pc(self):
         return self._pc
 
-
 class TestUnwinder(Unwinder):
     AMD64_RBP = 6
     AMD64_RSP = 7
@@ -69,6 +68,15 @@ class TestUnwinder(Unwinder):
         This unwinder recognizes the corrupt frames by checking that
         *RBP == RBP, and restores previous RBP from the word above it.
         """
+
+        # Check that we can access the architecture of the pending
+        # frame, and that this is the same architecture as for the
+        # currently selected inferior.
+        inf_arch = gdb.selected_inferior ().architecture ()
+        frame_arch = pending_frame.architecture ()
+        if (inf_arch != frame_arch):
+            raise gdb.GdbError ("architecture mismatch")
+
         try:
             # NOTE: the registers in Unwinder API can be referenced
             # either by name or by number. The code below uses both