[PATCH 2/4] gdb/py: convert debug logging in py-unwind to use new scheme

Simon Marchi simon.marchi@polymtl.ca
Mon May 10 02:29:25 GMT 2021


On 2021-05-09 12:10 p.m., Andrew Burgess wrote:
> I'm not sure what helpful things could be printed here.  The actual
> code that finds the "correct" unwinder is elsewhere (see
> _execute_unwinders in python/lib/gdb/__init__.py), back in this C
> function all we get given is a gdb.UnwindInfo object - and in most
> cases that's all it will ever be, there's nothing really identifying
> it as having come from any particular unwinder.

We can change gdb._execute_unwinders to return the name of the unwinder.
For example:


>From 16347d43242a5e96e1a839e1d9b006bb9fb85f85 Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@polymtl.ca>
Date: Sun, 9 May 2021 22:13:29 -0400
Subject: [PATCH] gdb: print name of unwinder that claimed the frame

Change-Id: Id603545b44a97df2a39dd1872fe1f38ad5059f03
---
 gdb/python/lib/gdb/__init__.py        | 13 +++++++++----
 gdb/python/py-unwind.c                | 27 +++++++++++++++++++++------
 gdb/testsuite/gdb.python/py-unwind.py |  2 +-
 3 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py
index d748b3a5827e..3640d142910b 100644
--- a/gdb/python/lib/gdb/__init__.py
+++ b/gdb/python/lib/gdb/__init__.py
@@ -91,26 +91,31 @@ def _execute_unwinders(pending_frame):
     Arguments:
         pending_frame: gdb.PendingFrame instance.
     Returns:
-        gdb.UnwindInfo instance or None.
+        Tuple with:
+
+	  [0] gdb.UnwindInfo instance
+	  [1] Name of unwinder that claimed the frame (type `str`)
+
+	or None, if no unwinder has claimed the frame.
     """
     for objfile in objfiles():
         for unwinder in objfile.frame_unwinders:
             if unwinder.enabled:
                 unwind_info = unwinder(pending_frame)
                 if unwind_info is not None:
-                    return unwind_info
+                    return (unwind_info, unwinder.name)
 
     for unwinder in current_progspace().frame_unwinders:
         if unwinder.enabled:
             unwind_info = unwinder(pending_frame)
             if unwind_info is not None:
-                return unwind_info
+                return (unwind_info, unwinder.name)
 
     for unwinder in frame_unwinders:
         if unwinder.enabled:
             unwind_info = unwinder(pending_frame)
             if unwind_info is not None:
-                return unwind_info
+                return (unwind_info, unwinder.name)
 
     return None
 
diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c
index 7c195eb539da..58e8b6b519e8 100644
--- a/gdb/python/py-unwind.c
+++ b/gdb/python/py-unwind.c
@@ -524,27 +524,41 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
       return 0;
     }
 
-  gdbpy_ref<> pyo_unwind_info
+  /* A (gdb.UnwindInfo, str) tuple, or None.  */
+  gdbpy_ref<> pyo_execute_ret
     (PyObject_CallFunctionObjArgs (pyo_execute.get (),
 				   pyo_pending_frame.get (), NULL));
-  if (pyo_unwind_info == NULL)
+  if (pyo_execute_ret == NULL)
     {
       /* If the unwinder is cancelled due to a Ctrl-C, then propagate
 	 the Ctrl-C as a GDB exception instead of swallowing it.  */
       gdbpy_print_stack_or_quit ();
       return 0;
     }
-  if (pyo_unwind_info == Py_None)
+  if (pyo_execute_ret == Py_None)
     return 0;
 
+  if (!PyTuple_Check (pyo_execute_ret.get ()))
+    error (_("Unexpected return value type from gdb._execute_unwinders."));
+
+  if (PyTuple_GET_SIZE (pyo_execute_ret.get ()) != 2)
+    error (_("Unexpected size of the tuple returned by gdb._execute_unwinders."));
+
+  PyObject *pyo_unwind_info = PyTuple_GET_ITEM (pyo_execute_ret.get (), 0);
+
   /* Received UnwindInfo, cache data.  */
-  if (PyObject_IsInstance (pyo_unwind_info.get (),
+  if (PyObject_IsInstance (pyo_unwind_info,
 			   (PyObject *) &unwind_info_object_type) <= 0)
     error (_("A Unwinder should return gdb.UnwindInfo instance."));
 
+  PyObject *pyo_unwinder_name = PyTuple_GET_ITEM (pyo_execute_ret.get (), 1);
+
+  if (!PyUnicode_Check (pyo_unwinder_name))
+    error (_("Unexpected type for the unwinder name."));
+
   {
     unwind_info_object *unwind_info =
-      (unwind_info_object *) pyo_unwind_info.get ();
+      (unwind_info_object *) pyo_unwind_info;
     int reg_count = unwind_info->saved_regs->size ();
 
     cached_frame
@@ -575,7 +589,8 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
   }
 
   *cache_ptr = cached_frame;
-  pyuw_debug_printf ("frame claimed");
+  pyuw_debug_printf ("frame claimed by unwinder %s",
+		     PyUnicode_AsUTF8 (pyo_unwinder_name));
   return 1;
 }
 
diff --git a/gdb/testsuite/gdb.python/py-unwind.py b/gdb/testsuite/gdb.python/py-unwind.py
index 931e979d28eb..b71d07abf246 100644
--- a/gdb/testsuite/gdb.python/py-unwind.py
+++ b/gdb/testsuite/gdb.python/py-unwind.py
@@ -37,7 +37,7 @@ class TestUnwinder(Unwinder):
     AMD64_RIP = None
 
     def __init__(self):
-        Unwinder.__init__(self, "test unwinder")
+        Unwinder.__init__(self, "test🍌unwinder")
         self.char_ptr_t = gdb.lookup_type("unsigned char").pointer()
         self.char_ptr_ptr_t = self.char_ptr_t.pointer()
         self._last_arch = None
-- 
2.30.1



More information about the Gdb-patches mailing list