[rfc] [7/9] Cell multi-arch: Add "set spu stop-on-load" command

Ulrich Weigand uweigand@de.ibm.com
Wed Jul 22 17:18:00 GMT 2009


Hello,

this patch is a add-on feature that improves usability of the combined
debugger: it adds a command "set spu stop-on-load" that causes execution
of each newly created SPU context to stop at its "main" function.

(This cannot be achieved simply by "break main", as that would refer
to the PowerPC-side main function only.)

Bye,
Ulrich


ChangeLog:

	* spu-tdep.c: Include "block.h".
	(setspucmdlist, showspucmdlist): New static variables.
	(spu_stop_on_load_p): Likewise.
	(spu_catch_start): New function.
	(show_spu_command, set_spu_command): New functions.
	(show_spu_stop_on_load): Likewise.
	(_initialize_spu_tdep): Attach spu_catch_start to new_objfile observer.
	Install "set spu" / "show spu" prefix command handler.
	Install "set spu stop-on-load" / "show spu stop-on-load" command.

	* NEWS: Mention "set/show spu stop-on-load" commands.

doc/ChangeLog:

	* gdb.texinfo (Cell Broadband Engine SPU architecture): Document the
	"set spu stop-on-load" and "show spu stop-on-load" commands.


Index: src/gdb/spu-tdep.c
===================================================================
--- src.orig/gdb/spu-tdep.c
+++ src/gdb/spu-tdep.c
@@ -40,11 +40,20 @@
 #include "regcache.h"
 #include "reggroups.h"
 #include "floatformat.h"
+#include "block.h"
 #include "observer.h"
 
 #include "spu-tdep.h"
 
 
+/* The list of available "set spu " and "show spu " commands.  */
+static struct cmd_list_element *setspucmdlist = NULL;
+static struct cmd_list_element *showspucmdlist = NULL;
+
+/* Whether to stop for new SPE contexts.  */
+static int spu_stop_on_load_p = 0;
+
+
 /* The tdep structure.  */
 struct gdbarch_tdep
 {
@@ -1752,6 +1761,65 @@ spu_overlay_new_objfile (struct objfile 
 }
 
 
+/* Insert temporary breakpoint on "main" function of newly loaded
+   SPE context OBJFILE.  */
+static void
+spu_catch_start (struct objfile *objfile)
+{
+  struct minimal_symbol *minsym;
+  struct symtab *symtab;
+  CORE_ADDR pc;
+  char buf[32];
+
+  /* Do this only if requested by "set spu stop-on-load on".  */
+  if (!spu_stop_on_load_p)
+    return;
+
+  /* Consider only SPU objfiles.  */
+  if (!objfile || bfd_get_arch (objfile->obfd) != bfd_arch_spu)
+    return;
+
+  /* The main objfile is handled differently.  */
+  if (objfile == symfile_objfile)
+    return;
+
+  /* There can be multiple symbols named "main".  Search for the
+     "main" in *this* objfile.  */
+  minsym = lookup_minimal_symbol ("main", NULL, objfile);
+  if (!minsym)
+    return;
+
+  /* If we have debugging information, try to use it -- this
+     will allow us to properly skip the prologue.  */
+  pc = SYMBOL_VALUE_ADDRESS (minsym);
+  symtab = find_pc_sect_symtab (pc, SYMBOL_OBJ_SECTION (minsym));
+  if (symtab != NULL)
+    {
+      struct blockvector *bv = BLOCKVECTOR (symtab);
+      struct block *block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+      struct symbol *sym;
+      struct symtab_and_line sal;
+
+      sym = lookup_block_symbol (block, "main", NULL, VAR_DOMAIN);
+      if (sym)
+	{
+	  fixup_symbol_section (sym, objfile);
+	  sal = find_function_start_sal (sym, 1);
+	  pc = sal.pc;
+	}
+    }
+
+  /* Use a numerical address for the set_breakpoint command to avoid having
+     the breakpoint re-set incorrectly.  */
+  xsnprintf (buf, sizeof buf, "*%s", core_addr_to_string (pc));
+  set_breakpoint (get_objfile_arch (objfile),
+		  buf, NULL /* condition */,
+		  0 /* hardwareflag */, 1 /* tempflag */,
+		  -1 /* thread */, 0 /* ignore_count */,
+		  0 /* pending */, 1 /* enabled */);
+}
+
+
 /* "info spu" commands.  */
 
 static void
@@ -2321,6 +2389,29 @@ info_spu_command (char *args, int from_t
 }
 
 
+/* Root of all "set spu "/"show spu " commands.  */
+
+static void
+show_spu_command (char *args, int from_tty)
+{
+  help_list (showspucmdlist, "show spu ", all_commands, gdb_stdout);
+}
+
+static void
+set_spu_command (char *args, int from_tty)
+{
+  help_list (setspucmdlist, "set spu ", all_commands, gdb_stdout);
+}
+
+static void
+show_spu_stop_on_load (struct ui_file *file, int from_tty,
+                       struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Stopping for new SPE threads is %s.\n"),
+                    value);
+}
+
+
 /* Set up gdbarch struct.  */
 
 static struct gdbarch *
@@ -2442,6 +2533,32 @@ _initialize_spu_tdep (void)
   observer_attach_new_objfile (spu_overlay_new_objfile);
   spu_overlay_data = register_objfile_data ();
 
+  /* Install spu stop-on-load handler.  */
+  observer_attach_new_objfile (spu_catch_start);
+
+  /* Add root prefix command for all "set spu"/"show spu" commands.  */
+  add_prefix_cmd ("spu", no_class, set_spu_command,
+		  _("Various SPU specific commands."),
+		  &setspucmdlist, "set spu ", 0, &setlist);
+  add_prefix_cmd ("spu", no_class, show_spu_command,
+		  _("Various SPU specific commands."),
+		  &showspucmdlist, "show spu ", 0, &showlist);
+
+  /* Toggle whether or not to add a temporary breakpoint at the "main"
+     function of new SPE contexts.  */
+  add_setshow_boolean_cmd ("stop-on-load", class_support,
+                          &spu_stop_on_load_p, _("\
+Set whether to stop for new SPE threads."),
+                           _("\
+Show whether to stop for new SPE threads."),
+                           _("\
+Use \"on\" to give control to the user when a new SPE thread\n\
+enters its \"main\" function.\n\
+Use \"off\" to disable stopping for new SPE threads."),
+                          NULL,
+                          show_spu_stop_on_load,
+                          &setspucmdlist, &showspucmdlist);
+
   /* Add root prefix command for all "info spu" commands.  */
   add_prefix_cmd ("spu", class_info, info_spu_command,
 		  _("Various SPU specific commands."),
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo
+++ src/gdb/doc/gdb.texinfo
@@ -17490,6 +17490,23 @@ and local store addresses and transfer s
 
 @end table
  
+When @value{GDBN} is debugging a combined PowerPC/SPU application
+on the Cell Broadband Engine, it provides in addition the following
+special commands:
+
+@table @code
+@item set spu stop-on-load @var{arg}
+@kindex set spu
+Set whether to stop for new SPE threads.  When set to @code{on}, @value{GDBN}
+will give control to the user when a new SPE thread enters its @code{main}
+function.  The default is @code{off}.
+
+@item show spu stop-on-load
+@kindex show spu
+Show whether to stop for new SPE threads.
+
+@end table
+
 @node PowerPC
 @subsection PowerPC
 @cindex PowerPC architecture
Index: src/gdb/NEWS
===================================================================
--- src.orig/gdb/NEWS
+++ src/gdb/NEWS
@@ -254,6 +254,10 @@ kill inferior NUM
 
 * New options
 
+set spu stop-on-load
+show spu stop-on-load
+  Control whether to stop for new SPE threads during Cell/B.E. debugging.
+
 set sh calling-convention
 show sh calling-convention
   Control the calling convention used when calling SH target functions.
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com



More information about the Gdb-patches mailing list