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

Samuel Bronson
2009-05-29T23:10:06Z

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