public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-sergiodj-stap: Initial user-interface code.
@ 2011-01-14 21:42 tromey
  0 siblings, 0 replies; only message in thread
From: tromey @ 2011-01-14 21:42 UTC (permalink / raw)
  To: archer-commits

The branch, archer-sergiodj-stap has been updated
       via  4170e9ca59b6d5d3404c717491d5f0f6affd90dd (commit)
      from  9067ae796b9c0a9e069fcda8862e513e2cd1b6bc (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 4170e9ca59b6d5d3404c717491d5f0f6affd90dd
Author: Tom Tromey <tromey@redhat.com>
Date:   Fri Jan 14 14:10:21 2011 -0700

    Initial user-interface code.
    
    The completion code is not yet written.
    It won't immediately work once the probe-reading code is created,
    because it does not handle probe semaphores.

-----------------------------------------------------------------------

Summary of changes:
 gdb/breakpoint.c    |  414 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/coffread.c      |    1 +
 gdb/dbxread.c       |    3 +-
 gdb/doc/gdb.texinfo |   38 +++++
 gdb/elfread.c       |    2 +
 gdb/machoread.c     |    1 +
 gdb/mipsread.c      |    1 +
 gdb/somread.c       |    1 +
 gdb/symfile.h       |    7 +
 gdb/xcoffread.c     |    1 +
 10 files changed, 468 insertions(+), 1 deletions(-)

First 500 lines of diff:
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index a909aa3..f197641 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -62,6 +62,8 @@
 #include "jit.h"
 #include "xml-syscall.h"
 #include "parser-defs.h"
+#include "gdb_regex.h"
+#include "stap-marker.h"
 
 /* readline include files */
 #include "readline/readline.h"
@@ -9256,6 +9258,403 @@ catch_assert_command (char *arg, int from_tty,
 				   ops, tempflag, from_tty);
 }
 
+/* Implementation of the `print_it' breakpoint_ops method for "catch
+   marker".  */
+
+static enum print_stop_action
+print_marker_catchpoint (struct breakpoint *b)
+{
+  annotate_catchpoint (b->number);
+
+  ui_out_text (uiout,
+	       (b->disposition == disp_del)
+	       ? "Temporary catchpoint "
+	       : "Catchpoint ");
+  ui_out_field_int (uiout, "bkptno", b->number);
+  ui_out_text (uiout, " (static marker hit), ");
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      ui_out_field_string (uiout, "reason", 
+			   async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
+      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+    }
+
+  return PRINT_SRC_AND_LOC;
+}
+
+/* Implementation of the `print_one' breakpoint_ops method for "catch
+   marker".  */
+
+static void
+print_one_marker_catchpoint (struct breakpoint *b,
+			     struct bp_location **last_loc)
+{
+  struct value_print_options opts;
+
+  get_user_print_options (&opts);
+  if (opts.addressprint)
+    {
+      annotate_field (4);
+      if (b->loc == NULL || b->loc->shlib_disabled)
+	ui_out_field_string (uiout, "addr", "<PENDING>");
+      else
+	ui_out_field_core_addr (uiout, "addr",
+				b->loc->gdbarch, b->loc->address);
+    }
+  annotate_field (5);
+  if (b->loc)
+    *last_loc = b->loc;
+  ui_out_field_string (uiout, "what", "marker hit");
+}
+
+/* Implementation of the `print_mention' breakpoint_ops method for
+   "catch marker".  */
+
+static void
+print_mention_marker_catchpoint (struct breakpoint *b)
+{
+  int bp_temp;
+
+  bp_temp = b->disposition == disp_del;
+  ui_out_text (uiout, bp_temp ? _("Temporary catchpoint ")
+			      : _("Catchpoint "));
+  ui_out_field_int (uiout, "bkptno", b->number);
+  ui_out_text (uiout, _(" (marker)"));
+}
+
+/* Implementation of the `print_recreate' breakpoint_ops method for
+   "catch marker".  */
+
+static void
+print_recreate_marker_catchpoint (struct breakpoint *b, struct ui_file *fp)
+{
+  fprintf_unfiltered (fp, (b->disposition == disp_del) ? "tcatch " : "catch ");
+  fprintf_unfiltered (fp, "marker %s", b->addr_string);
+}
+
+/* breakpoint_ops used by "catch marker".  */
+
+static struct breakpoint_ops marker_catchpoint_ops = {
+  NULL, /* insert */
+  NULL, /* remove */
+  NULL, /* breakpoint_hit */
+  print_marker_catchpoint,
+  print_one_marker_catchpoint,
+  print_mention_marker_catchpoint,
+  print_recreate_marker_catchpoint
+};
+
+/* Completion function used by "catch marker".  */
+
+static char **complete_markers (struct cmd_list_element *cmd,
+				char *text, char *word)
+{
+  return NULL;			/* FIXME */
+}
+
+/* A helper function to extract an argument from *ARG.  An argument is
+   delimited by whitespace.  The return value is either NULL if no
+   argument was found, or an xmalloc'd string.  */
+
+static char *
+extract_arg (char **arg)
+{
+  char *result, *copy;
+
+  if (!*arg)
+    return NULL;
+
+  /* Find the start of the argument.  */
+  ep_skip_leading_whitespace (arg);
+  if (! **arg)
+    return NULL;
+  result = *arg;
+
+  /* Find the end of the argument.  */
+  for (++*arg; **arg && ! isspace (**arg); ++*arg)
+    ;
+
+  if (result == *arg)
+    return NULL;
+
+  copy = xmalloc (*arg - result + 1);
+  memcpy (copy, result, *arg - result);
+  copy[*arg - result] = '\0';
+
+  return copy;
+}
+
+typedef struct symtab_and_line symtab_and_line_s;
+DEF_VEC_O (symtab_and_line_s);
+
+/* Implement the "catch marker" command.  */
+
+static void
+catch_marker_command (char *arg, int from_tty,
+		      struct cmd_list_element *command)
+{
+  char *provider, *marker, *objname, *addr;
+  struct objfile *objfile;
+  struct cleanup *cleanup, *addr_cleanup;
+  VEC (symtab_and_line_s) *salvec = NULL;
+  struct symtabs_and_lines sals;
+
+  cleanup = make_cleanup (VEC_cleanup (symtab_and_line_s), &salvec);
+
+  provider = extract_arg (&arg);
+  if (!provider)
+    error (_("provider name required"));
+  make_cleanup (xfree, provider);
+
+  marker = extract_arg (&arg);
+  if (!marker)
+    error (_("marker name required"));
+  make_cleanup (xfree, marker);
+
+  objname = extract_arg (&arg);
+  if (objname)
+    make_cleanup (xfree, objname);
+
+  ALL_OBJFILES (objfile)
+  {
+    const struct stap_marker *markers;
+    int i, num_markers;
+
+    /* FIXME filename compare - but this is probably not the most
+       useful definition of this command.  */
+    if (objname && strcmp (objfile->name, objname) != 0)
+      continue;
+
+    if (! objfile->sf || ! objfile->sf->sym_get_markers)
+      continue;
+
+    markers = objfile->sf->sym_get_markers (objfile, &num_markers);
+    for (i = 0; i < num_markers; ++i)
+      {
+	struct symtab_and_line sal;
+
+	if (strcmp (markers[i].provider, provider) != 0
+	    || strcmp (markers[i].name, marker) != 0)
+	  continue;
+
+	init_sal (&sal);
+
+	sal.pc = markers[i].address;
+	sal.section = find_pc_overlay (sal.pc);
+	sal.pspace = current_program_space;
+
+	VEC_safe_push (symtab_and_line_s, salvec, &sal);
+      }
+  }
+
+  if (VEC_empty (symtab_and_line_s, salvec))
+    /* FIXME: we should allow pending markers.  We should probably use
+       create_breakpoint instead of create_breakpoint_sal.  And we
+       should provide a new re_set method in breakpoint_ops for this
+       case.  */
+    error (_("No matching marker found"));
+
+  sals.sals = VEC_address (symtab_and_line_s, salvec);
+  sals.nelts = VEC_length (symtab_and_line_s, salvec);
+
+  addr = xstrprintf ("%s %s %s", provider, marker, objname ? objname : "");
+  addr_cleanup = make_cleanup (xfree, addr);
+
+  create_breakpoint_sal (get_current_arch (), sals,
+			 addr, NULL, bp_breakpoint, disp_donttouch,
+			 -1, 0, 0, &marker_catchpoint_ops, from_tty,
+			 1, 0);
+
+  discard_cleanups (addr_cleanup);
+  do_cleanups (cleanup);
+}
+
+/* A utility structure.  A VEC of these is built when handling "info
+   markers".  */
+
+struct stap_marker_and_objfile
+{
+  /* The marker.  */
+  const struct stap_marker *marker;
+  /* The marker's objfile.  */
+  struct objfile *objfile;
+};
+
+typedef struct stap_marker_and_objfile stap_entry;
+DEF_VEC_O (stap_entry);
+
+/* Make a vector of markers matching OBJNAME, PROVIDER, and MARKER.
+   Each argument is a regexp, or NULL, which matches anything.  */
+
+static VEC (stap_entry) *
+collect_markers (char *objname, char *provider, char *marker)
+{
+  struct objfile *objfile;
+  int need_compile = 1;
+  VEC (stap_entry) *result = NULL;
+  struct cleanup *cleanup;
+
+  cleanup = make_cleanup (VEC_cleanup (stap_entry), &result);
+
+  ALL_OBJFILES (objfile)
+  {
+    const struct stap_marker *markers;
+    int i, num_markers;
+    stap_entry entry;
+
+    if (objname)
+      {
+	if (need_compile)
+	  {
+	    char *err = re_comp (objname);
+
+	    if (err)
+	      error (_("Invalid object file regexp: %s"), err);
+
+	    need_compile = 0;
+	  }
+
+	if (re_exec (objfile->name) == 0)
+	  continue;
+      }
+
+    if (! objfile->sf || ! objfile->sf->sym_get_markers)
+      continue;
+
+    markers = objfile->sf->sym_get_markers (objfile, &num_markers);
+    for (i = 0; i < num_markers; ++i)
+      {
+	if (provider)
+	  {
+	    char *err = re_comp (provider);
+
+	    if (err)
+	      error (_("Invalid provider regexp: %s"), err);
+
+	    need_compile = 1;
+
+	    if (re_exec (markers[i].provider) == 0)
+	      continue;
+	  }
+
+	if (marker)
+	  {
+	    char *err = re_comp (marker);
+
+	    if (err)
+	      error (_("Invalid marker regexp: %s"), err);
+
+	    need_compile = 1;
+
+	    if (re_exec (markers[i].name) == 0)
+	      continue;
+	  }
+
+	entry.marker = &markers[i];
+	entry.objfile = objfile;
+	VEC_safe_push (stap_entry, result, &entry);
+      }
+  }
+
+  discard_cleanups (cleanup);
+  return result;
+}
+
+/* A qsort comparison function for stap_entry objects.  */
+
+static int
+compare_entries (const void *a, const void *b)
+{
+  const stap_entry *ea = a;
+  const stap_entry *eb = b;
+  int v;
+
+  v = strcmp (ea->marker->provider, eb->marker->provider);
+  if (v)
+    return v;
+
+  v = strcmp (ea->marker->name, eb->marker->name);
+  if (v)
+    return v;
+
+  if (ea->marker->address < eb->marker->address)
+    return -1;
+  if (ea->marker->address > eb->marker->address)
+    return 1;
+
+  return strcmp (ea->objfile->name, eb->objfile->name);
+}
+
+/* Implementation of the "info markers" command.  */
+
+static void
+info_markers_command (char *arg, int from_tty)
+{
+  char *provider, *marker = NULL, *objname = NULL;
+  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
+  VEC (stap_entry) *items;
+  int i, addr_width, any_found;
+  stap_entry *entry;
+
+  provider = extract_arg (&arg);
+  if (provider)
+    {
+      make_cleanup (xfree, provider);
+
+      marker = extract_arg (&arg);
+      if (marker)
+	{
+	  make_cleanup (xfree, marker);
+
+	  objname = extract_arg (&arg);
+	  if (objname)
+	    make_cleanup (xfree, objname);
+	}
+    }
+
+  items = collect_markers (objname, provider, marker);
+  make_cleanup (VEC_cleanup (stap_entry), &items);
+  make_cleanup_ui_out_table_begin_end (uiout, 4,
+				       VEC_length (stap_entry, items),
+				       "SystemTapMarkers");
+
+  if (! VEC_empty (stap_entry, items))
+    qsort (VEC_address (stap_entry, items),
+	   VEC_length (stap_entry, items),
+	   sizeof (stap_entry),
+	   compare_entries);
+
+  addr_width = 4 + (gdbarch_ptr_bit (get_current_arch ()) / 4);
+
+  ui_out_table_header (uiout, 15, ui_left, "provider", _("Provider"));
+  ui_out_table_header (uiout, 15, ui_left, "name", _("Name"));
+  ui_out_table_header (uiout, addr_width - 1, ui_left, "addr", _("Where"));
+  ui_out_table_header (uiout, 30, ui_left, "object", _("Object"));
+  ui_out_table_body (uiout);
+
+  for (i = 0; VEC_iterate (stap_entry, items, i, entry); ++i)
+    {
+      struct cleanup *inner;
+
+      inner = make_cleanup_ui_out_tuple_begin_end (uiout, "marker");
+
+      ui_out_field_string (uiout, "provider", entry->marker->provider);
+      ui_out_field_string (uiout, "name", entry->marker->name);
+      ui_out_field_core_addr (uiout, "addr", get_current_arch (),
+			      entry->marker->address);
+      ui_out_field_string (uiout, "object", entry->objfile->name);
+      ui_out_text (uiout, "\n");
+
+      do_cleanups (inner);
+    }
+
+  any_found = ! VEC_empty (stap_entry, items);
+  do_cleanups (cleanup);
+
+  if (! any_found)
+    ui_out_message (uiout, 0, _("No markers matched.\n"));
+}
+
 static void
 catch_command (char *arg, int from_tty)
 {
@@ -12219,6 +12618,13 @@ With an argument, catch only exceptions with the given name."),
                      NULL,
 		     CATCH_PERMANENT,
 		     CATCH_TEMPORARY);
+  add_catch_command ("marker", _("\
+Stop at a SystemTap static marker.\n\
+Arguments are the provider name and marker name."),
+		     catch_marker_command,
+		     complete_markers,
+		     CATCH_PERMANENT,
+		     CATCH_TEMPORARY);
 
   c = add_com ("watch", class_breakpoint, watch_command, _("\
 Set a watchpoint for an expression.\n\
@@ -12251,6 +12657,14 @@ the memory to which it refers."));
 Status of watchpoints, or watchpoint number NUMBER."));
 
 
+  add_info ("markers", info_markers_command, _("\
+Show available static markers.\n\
+Usage: info markers [PROVIDER [NAME [OBJECT]]]\n\
+Each argument is a regular expression, used to select markers.\n\
+PROVIDER matches marker provider names.\n\
+NAME matches the marker names.\n\
+OBJECT match the executable or shared library name."));
+
 
   /* XXX: cagney/2005-02-23: This should be a boolean, and should
      respond to changes - contrary to the description.  */
diff --git a/gdb/coffread.c b/gdb/coffread.c
index c799745..53ec503 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -2199,6 +2199,7 @@ static const struct sym_fns coff_sym_fns =
 
   default_symfile_relocate,	/* sym_relocate: Relocate a debug
 				   section.  */
+  NULL,				/* sym_get_markers */
   &psym_functions
 };
 
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index a3218ec..237e2eb 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -1,6 +1,6 @@
 /* Read dbx symbol tables and convert to internal format, for GDB.
    Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2008, 2009, 2010.
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2008, 2009, 2010, 2011.
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -3593,6 +3593,7 @@ static const struct sym_fns aout_sym_fns =
   default_symfile_segments,	/* Get segment information from a file.  */
   NULL,
   default_symfile_relocate,	/* Relocate a debug section.  */
+  NULL,				/* sym_get_markers */
   &psym_functions
 };
 
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7f8c785..42d031b 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -3925,6 +3925,7 @@ shared library.  Use the @code{catch} command to set a catchpoint.
 @kindex catch
 @item catch @var{event}
 Stop when @var{event} occurs.  @var{event} can be any of the following:
+
 @table @code
 @item throw
 @cindex stop on C@t{++} exceptions
@@ -4100,6 +4101,26 @@ and @sc{gnu}/Linux.
 A call to @code{vfork}.  This is currently only available for HP-UX
 and @sc{gnu}/Linux.
 
+@item marker @var{provider} @var{name} [@var{objfile}]
+A @code{SystemTap} static marker was hit.
+
+The @sc{gnu}/Linux tool @code{SystemTap} provides a way for
+applications to embed static markers.  @value{GDBN} can detect when a
+marker was hit.


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-01-14 21:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-14 21:42 [SCM] archer-sergiodj-stap: Initial user-interface code tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).