[PATCH 2/2] Add "set/show debug unwinder" prefix commands.

Samuel Bronson naesten@gmail.com
Fri May 29 23:10:00 GMT 2009


Also add one subcommand for tracing the sniffing of stack frames by
unwinders.

Signed-off-by: Samuel Bronson <naesten@gmail.com>
---
 gdb/frame-unwind.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/frame-unwind.h |    7 ++++++
 2 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index 98d6b43..5e893bb 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -23,6 +23,7 @@
 #include "dummy-frame.h"
 #include "value.h"
 #include "regcache.h"
+#include "gdbcmd.h"
 
 #include "gdb_assert.h"
 #include "gdb_obstack.h"
@@ -42,6 +43,9 @@ struct frame_unwind_table
   struct frame_unwind_table_entry **osabi_head;
 };
 
+/* trace unwinders called */
+static int trace_unwinders;
+
 static void *
 frame_unwind_init (struct obstack *obstack)
 {
@@ -91,14 +95,33 @@ frame_unwind_find_by_frame (struct frame_info *this_frame, void **this_cache)
   struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
   struct frame_unwind_table_entry *entry;
   struct cleanup *old_cleanup;
+
+  if (trace_unwinders) {
+    fprintf_unfiltered (gdb_stdlog, "[ Searching for unwinder for frame ...\n");
+  }
+
   for (entry = table->list; entry != NULL; entry = entry->next)
     {
       struct cleanup *old_cleanup;
+      const char *uname = entry->unwinder->unwinder_name;
+
+      if (trace_unwinders) {
+	if (!uname)
+	  uname = "<unknown>";
+	
+	fprintf_unfiltered (gdb_stdlog, "... trying unwinder \"%s\" (at %p) ...\n",
+			    uname, entry->unwinder);
+      }
 
       old_cleanup = frame_prepare_for_sniffer (this_frame, entry->unwinder);
       if (entry->unwinder->sniffer (entry->unwinder, this_frame,
 				    this_cache))
 	{
+	  if (trace_unwinders) {
+	    fprintf_unfiltered(gdb_stdlog,
+			       "... unwinder \"%s\"'s sniffer succeeded. Search over.]\n",
+			       uname);
+	  }
 	  discard_cleanups (old_cleanup);
 	  return entry->unwinder;
 	}
@@ -200,8 +223,42 @@ frame_unwind_got_address (struct frame_info *frame, int regnum,
 
 extern initialize_file_ftype _initialize_frame_unwind; /* -Wmissing-prototypes */
 
+/* "set debug unwinder" command list */
+struct cmd_list_element *set_debug_unwinder_list;
+/* "show debug unwinder" command list */
+struct cmd_list_element *show_debug_unwinder_list;
+
+static void
+set_debug_unwinder_cmd (char *args, int from_tty)
+{
+  help_list (set_debug_unwinder_list, "set debug unwinder ", -1, gdb_stdout);
+}
+
+static void
+show_debug_unwinder_cmd (char *args, int from_tty)
+{
+  help_list (show_debug_unwinder_list, "show debug unwinder ", -1, gdb_stdout);
+}
+
 void
 _initialize_frame_unwind (void)
 {
   frame_unwind_data = gdbarch_data_register_pre_init (frame_unwind_init);
+
+  add_prefix_cmd ("unwinder", class_maintenance, set_debug_unwinder_cmd, _("\
+Set stack frame unwinder debugging variables."),
+		  &set_debug_unwinder_list, "set debug unwinder ",
+		  0, &setdebuglist);
+
+  add_prefix_cmd ("unwinder", class_maintenance, show_debug_unwinder_cmd, _("\
+Show stack frame unwinder debugging variables."),
+		  &show_debug_unwinder_list, "set debug unwinder ",
+		  0, &showdebuglist);
+
+  add_setshow_boolean_cmd ("trace-tried", class_maintenance, &trace_unwinders,
+			   _("Set tracing of unwinders tried."),
+			   _("Show tracing of unwinders tried."),
+			   NULL /* main doc */,
+			   NULL, NULL,
+			   &set_debug_unwinder_list, &show_debug_unwinder_list);
 }
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index 4da7fcc..d8dfc30 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -152,6 +152,13 @@ extern void frame_unwind_prepend_unwinder (struct gdbarch *gdbarch,
 extern void frame_unwind_append_unwinder (struct gdbarch *gdbarch,
 					  const struct frame_unwind *unwinder);
 
+/* Command lists for "set/show debug unwinder" subcommands.  Most of
+   these are expected to be flags to request an unwinder or
+   closely-related group of unwinders to give a blow-by-blow account
+   of why it's sniffer did or did not succeed. */
+extern struct cmd_list_element *set_debug_unwinder_list;
+extern struct cmd_list_element *show_debug_unwinder_list;
+
 /* Iterate through sniffers for THIS frame until one returns with an
    unwinder implementation.  Possibly initialize THIS_CACHE.  */
 
-- 
1.6.3.1.169.g33fd.dirty



More information about the Gdb-patches mailing list