[binutils-gdb] gdb/python: print name of unwinder that claimed frame in debug message

Simon Marchi simark@sourceware.org
Tue Jun 22 18:47:28 GMT 2021


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4e317a765bbe1c47fb9d461b7effa40f34220c85

commit 4e317a765bbe1c47fb9d461b7effa40f34220c85
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Tue Jun 22 14:16:01 2021 -0400

    gdb/python: print name of unwinder that claimed frame in debug message
    
    If we have multiple registered unwinders, this will helps identify which
    unwinder was chosen and make it easier to track down potential problems.
    Unwinders have a mandatory name argument, which we can use in the
    message.
    
    First, make gdb._execute_unwinders return a tuple containing the name,
    in addition to the UnwindInfo.  Then, make pyuw_sniffer include the name
    in the debug message.
    
    I moved the debug message earlier.  I think it's good to print it as
    early as possible, so that we see it in case an assert is hit in the
    loop below, for example.
    
    gdb/ChangeLog:
    
            * python/lib/gdb/__init__.py (_execute_unwinders): Return tuple
            with name of chosen unwinder.
            * python/py-unwind.c (pyuw_sniffer): Print name of chosen
            unwinder in debug message.
    
    Change-Id: Id603545b44a97df2a39dd1872fe1f38ad5059f03

Diff:
---
 gdb/ChangeLog                  |  7 +++++++
 gdb/python/lib/gdb/__init__.py | 14 ++++++++++----
 gdb/python/py-unwind.c         | 36 +++++++++++++++++++++++++++++-------
 3 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d9e0a3a4f4d..995c8a1a375 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2021-06-22  Simon Marchi  <simon.marchi@polymtl.ca>
+
+	* python/lib/gdb/__init__.py (_execute_unwinders): Return tuple
+	with name of chosen unwinder.
+	* python/py-unwind.c (pyuw_sniffer): Print name of chosen
+	unwinder in debug message.
+
 2021-06-22  Andreas Schwab  <schwab@suse.de>
 
 	PR symtab/27999
diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py
index d748b3a5827..f2f38b32af9 100644
--- a/gdb/python/lib/gdb/__init__.py
+++ b/gdb/python/lib/gdb/__init__.py
@@ -90,27 +90,33 @@ 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 d3ef1911ab8..18ea2434f87 100644
--- a/gdb/python/py-unwind.c
+++ b/gdb/python/py-unwind.c
@@ -556,33 +556,56 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
     }
   gdbpy_ref<> pyo_execute (PyObject_GetAttrString (gdb_python_module,
 						   "_execute_unwinders"));
-  if (pyo_execute == NULL)
+  if (pyo_execute == nullptr)
     {
       gdbpy_print_stack ();
       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 == nullptr)
     {
       /* 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;
 
+  /* Verify the return value of _execute_unwinders is a tuple of size 2.  */
+  gdb_assert (PyTuple_Check (pyo_execute_ret.get ()));
+  gdb_assert (PyTuple_GET_SIZE (pyo_execute_ret.get ()) == 2);
+
+  if (pyuw_debug)
+    {
+      PyObject *pyo_unwinder_name = PyTuple_GET_ITEM (pyo_execute_ret.get (), 1);
+      gdb::unique_xmalloc_ptr<char> name
+	= python_string_to_host_string (pyo_unwinder_name);
+
+      /* This could happen if the user passed something else than a string
+	 as the unwinder's name.  */
+      if (name == nullptr)
+	{
+	  gdbpy_print_stack ();
+	  name = make_unique_xstrdup ("<failed to get unwinder name>");
+	}
+
+      pyuw_debug_printf ("frame claimed by unwinder %s", name.get ());
+    }
+
   /* Received UnwindInfo, cache data.  */
-  if (PyObject_IsInstance (pyo_unwind_info.get (),
+  PyObject *pyo_unwind_info = PyTuple_GET_ITEM (pyo_execute_ret.get (), 0);
+  if (PyObject_IsInstance (pyo_unwind_info,
 			   (PyObject *) &unwind_info_object_type) <= 0)
     error (_("A Unwinder should return gdb.UnwindInfo instance."));
 
   {
     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
@@ -613,7 +636,6 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
   }
 
   *cache_ptr = cached_frame;
-  pyuw_debug_printf ("frame claimed");
   return 1;
 }


More information about the Gdb-cvs mailing list