public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-sergiodj-stap-patches: New auto-sizing algorithms, new comments, etc.
@ 2012-04-20  4:19 sergiodj
  0 siblings, 0 replies; only message in thread
From: sergiodj @ 2012-04-20  4:19 UTC (permalink / raw)
  To: archer-commits

The branch, archer-sergiodj-stap-patches has been updated
       via  ccaaf2154dfffef1ac11055f9bf0b8564ec73181 (commit)
      from  b1f5e35562e1cc1654ccf668b0166b48c9c50f46 (commit)

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

- Log -----------------------------------------------------------------
commit ccaaf2154dfffef1ac11055f9bf0b8564ec73181
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date:   Fri Apr 20 01:19:11 2012 -0300

    New auto-sizing algorithms, new comments, etc.

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

Summary of changes:
 gdb/probe.c      |  246 ++++++++++++++++++++++++++++++++++++++++++++++-------
 gdb/probe.h      |   66 +++++++++++++--
 gdb/stap-probe.c |   28 +++----
 3 files changed, 286 insertions(+), 54 deletions(-)

First 500 lines of diff:
diff --git a/gdb/probe.c b/gdb/probe.c
index 7a5e140..8659d34 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -362,7 +362,113 @@ compare_entries (const void *a, const void *b)
   return strcmp (ea->objfile->name, eb->objfile->name);
 }
 
-/* Implementation of the `info probes' command.  */
+/* Helper function that generate entries in the ui_out table being
+   crafted by `info_probes_for_ops'.  */
+
+static void
+gen_ui_out_table_header_info (VEC (probe_entry) *items,
+			      const struct probe_ops *p)
+{
+  VEC (const_char_ptr) *fields = NULL;
+  struct cleanup *c;
+  const char *f;
+  int jx;
+
+  gdb_assert (p != NULL);
+
+  if (p->gen_ui_out_table_header == NULL || p->gen_ui_out_fields == NULL)
+    return;
+
+  c = make_cleanup (VEC_cleanup (const_char_ptr), &fields);
+  p->gen_ui_out_table_header (&fields);
+
+  for (jx = 0; VEC_iterate (const_char_ptr, fields, jx, f); ++jx)
+    {
+      probe_entry *entry;
+      int ix;
+      size_t size_max = strlen (f);
+
+      for (ix = 0; VEC_iterate (probe_entry, items, ix, entry); ++ix)
+	{
+	  VEC (const_char_ptr) *values = NULL;
+	  struct cleanup *c2;
+	  const char *val;
+	  int kx;
+
+	  if (entry->probe->pops != p)
+	    continue;
+
+	  c2 = make_cleanup (VEC_cleanup (const_char_ptr), &values);
+	  p->gen_ui_out_fields (entry->probe, entry->objfile, &values);
+
+	  for (kx = 0; VEC_iterate (const_char_ptr, values, kx, val); ++kx)
+	    {
+	      size_t s;
+
+	      /* It is valid to have a NULL value here, which means that the
+		 backend does not have something to write and this particular
+		 field should be skipped.  */
+	      if (val == NULL)
+		continue;
+
+	      s = strlen (val);
+
+	      if (s > size_max)
+		size_max = s;
+	    }
+
+	  do_cleanups (c2);
+	}
+
+      ui_out_table_header (current_uiout, size_max, ui_left, f, f);
+    }
+
+  do_cleanups (c);
+}
+
+/* Helper function to print extra information about a probe and an objfile
+   represented by ENTRY.  */
+
+static void
+print_ui_out_info (probe_entry *entry)
+{
+  const char *val, *field;
+  int ix;
+  VEC (const_char_ptr) *values = NULL, *fields = NULL;
+  struct cleanup *c;
+
+  gdb_assert (entry != NULL && entry->probe != NULL
+	      && entry->probe->pops != NULL);
+
+  if (entry->probe->pops->gen_ui_out_table_header == NULL
+      || entry->probe->pops->gen_ui_out_fields == NULL)
+    return;
+
+  c = make_cleanup (VEC_cleanup (const_char_ptr), &fields);
+  make_cleanup (VEC_cleanup (const_char_ptr), &values);
+
+  entry->probe->pops->gen_ui_out_table_header (&fields);
+  entry->probe->pops->gen_ui_out_fields (entry->probe, entry->objfile,
+					 &values);
+
+  gdb_assert (VEC_length (const_char_ptr, fields)
+	      == VEC_length (const_char_ptr, values));
+
+  for (ix = 0;
+       VEC_iterate (const_char_ptr, fields, ix, field),
+       VEC_iterate (const_char_ptr, values, ix, val);
+       ++ix)
+    {
+      if (val == NULL)
+	ui_out_field_skip (current_uiout, field);
+      else
+	ui_out_field_string (current_uiout, field, val);
+    }
+
+  do_cleanups (c);
+}
+
+/* See comment in probe.h.  */
 
 void
 info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
@@ -370,11 +476,16 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
   char *provider, *probe = NULL, *objname = NULL;
   struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
   VEC (probe_entry) *items;
-  int i, any_found, ui_out_extra_fields;
+  int i, any_found;
+  int ui_out_extra_fields = 0;
   int size_addr;
+  int size_name = strlen ("Name");
+  int size_objname = strlen ("Object");
+  int size_provider = strlen ("Provider");
   probe_entry *entry;
   struct gdbarch *gdbarch = get_current_arch ();
 
+  /* Do we have a `provider:probe:objfile' style of linespec?  */
   provider = extract_arg (&arg);
   if (provider)
     {
@@ -391,7 +502,54 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
 	}
     }
 
-  ui_out_extra_fields = pops != NULL ? pops->ui_out_extra_fields : 0;
+  if (pops == NULL)
+    {
+      const struct probe_ops *po;
+      int ix;
+
+      /* If the probe_ops is NULL, it means the user has requested a "simple"
+	 `info probes', i.e., she wants to print all information about all
+	 probes.  For that, we have to identify how many extra fields we will
+	 need to add in the ui_out table.
+
+	 To do that, we iterate over all probe_ops, querying each one about
+	 its extra fields, and incrementing `ui_out_extra_fields' to reflect
+	 that number.  */
+
+      for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
+	{
+	  VEC (const_char_ptr) *fields = NULL;
+	  struct cleanup *c;
+
+	  if (po->gen_ui_out_table_header == NULL)
+	    continue;
+
+	  c = make_cleanup (VEC_cleanup (const_char_ptr), &fields);
+	  po->gen_ui_out_table_header (&fields);
+
+	  ui_out_extra_fields += VEC_length (const_char_ptr, fields);
+
+	  do_cleanups (c);
+	}
+    }
+  else
+    {
+      if (pops->gen_ui_out_table_header != NULL)
+	{
+	  VEC (const_char_ptr) *fields = NULL;
+	  struct cleanup *c;
+
+	  /* We have a probe_ops, and it exports the function used to
+	     obtains the extra fields.  So we just ask the backend about
+	     what are those extra fields, and increment `ui_out_extra_fields'
+	     accordingly.  */
+
+	  c = make_cleanup (VEC_cleanup (const_char_ptr), &fields);
+	  pops->gen_ui_out_table_header (&fields);
+	  ui_out_extra_fields = VEC_length (const_char_ptr, fields);
+	  do_cleanups (c);
+	}
+    }
 
   items = collect_probes (objname, provider, probe, pops);
   make_cleanup (VEC_cleanup (probe_entry), &items);
@@ -404,23 +562,47 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
     qsort (VEC_address (probe_entry, items), VEC_length (probe_entry, items),
 	   sizeof (probe_entry), compare_entries);
 
+  /* What's the size of an address in our architecture?  */
   size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10;
 
-/* FIXME: provider width auto-sizing.  */
-  ui_out_table_header (current_uiout, 10, ui_left, "provider", _("Provider"));
-/* FIXME: name width auto-sizing.  */
-  ui_out_table_header (current_uiout, 10, ui_left, "name", _("Name"));
-/* FIXME: address width auto-sizing.  */
+  /* Determining the maximum size of each field (`provider', `name' and
+     `objname').  */
+  for (i = 0; VEC_iterate (probe_entry, items, i, entry); ++i)
+    {
+      int s_name = strlen (entry->probe->name);
+      int s_provider = strlen (entry->probe->provider);
+      int s_objname = strlen (entry->objfile->name);
+
+      if (s_name > size_name)
+	size_name = s_name;
+
+      if (s_provider > size_provider)
+	size_provider = s_provider;
+
+      if (s_objname > size_objname)
+	size_objname = s_objname;
+    }
+
+  ui_out_table_header (current_uiout, size_provider, ui_left, "provider",
+		       _("Provider"));
+  ui_out_table_header (current_uiout, size_name, ui_left, "name", _("Name"));
   ui_out_table_header (current_uiout, size_addr, ui_left, "addr", _("Where"));
-  if (pops != NULL && pops->gen_ui_out_table_header != NULL)
-    pops->gen_ui_out_table_header (current_uiout, ui_left);
-
-#if 0 /* FIXME */
-  ui_out_table_header (current_uiout, 10, ui_left, "semaphore",
-		       _("Semaphore"));
-#endif
-/* FIXME: object width auto-sizing.  */
-  ui_out_table_header (current_uiout, 30, ui_left, "object", _("Object"));
+
+  if (pops == NULL)
+    {
+      const struct probe_ops *po;
+      int ix;
+
+      /* We have to generate the table header for each new probe type that we
+	 will print.  */
+      for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
+	gen_ui_out_table_header_info (items, po);
+    }
+  else
+    gen_ui_out_table_header_info (items, pops);
+
+  ui_out_table_header (current_uiout, size_objname, ui_left, "object",
+		       _("Object"));
   ui_out_table_body (current_uiout);
 
   for (i = 0; VEC_iterate (probe_entry, items, i, entry); ++i)
@@ -434,17 +616,20 @@ info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
       ui_out_field_core_addr (current_uiout, "addr",
 			      get_objfile_arch (entry->objfile),
 			      entry->probe->address);
-      if (pops != NULL && pops->gen_ui_out_fields != NULL)
-	pops->gen_ui_out_fields (entry->probe, entry->objfile, current_uiout);
 
-#if 0 /* FIXME */
-      if (entry->probe->sem_addr == 0)
-	ui_out_field_skip (current_uiout, "semaphore");
+      if (pops == NULL)
+	{
+	  const struct probe_ops *po;
+	  int ix;
+
+	  for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po);
+	       ++ix)
+	    if (entry->probe->pops == po)
+	      print_ui_out_info (entry);
+	}
       else
-	ui_out_field_core_addr (current_uiout, "semaphore",
-				get_objfile_arch (entry->objfile),
-				entry->probe->sem_addr);
-#endif
+	print_ui_out_info (entry);
+
       ui_out_field_string (current_uiout, "object", entry->objfile->name);
       ui_out_text (current_uiout, "\n");
 
@@ -491,11 +676,7 @@ probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n)
 								  n);
 }
 
-/* Return specific PROBE_OPS * matching *LINESPECP and possibly updating
-   *LINESPECP to skip its "-probe-type " prefix.  Return &probe_ops_any if
-   *LINESPECP matches "-probe ", that is any unspecific probe.  Return NULL if
-   *LINESPECP is not identified as any known probe type, *LINESPECP is not
-   modified in such case.  */
+/* See comment in probe.h.  */
 
 const struct probe_ops *
 probe_linespec_to_ops (const char **linespecp)
@@ -510,7 +691,7 @@ probe_linespec_to_ops (const char **linespecp)
   return NULL;
 }
 
-/* See comments in probe.h.  */
+/* See comment in probe.h.  */
 
 int
 probe_is_linespec_by_keyword (const char **linespecp, const char *const *keywords)
@@ -555,7 +736,6 @@ probe_any_get_probes (VEC (probe_p) **probesp, struct objfile *objfile)
 
 const struct probe_ops probe_ops_any =
 {
-  0,
   probe_any_is_linespec,
   probe_any_get_probes,
 };
diff --git a/gdb/probe.h b/gdb/probe.h
index 4e53098..96be016 100644
--- a/gdb/probe.h
+++ b/gdb/probe.h
@@ -22,6 +22,8 @@
 
 #include "gdb_vecs.h"
 
+DEF_VEC_P (const_char_ptr);
+
 struct linespec_result;
 enum ui_align;
 
@@ -29,13 +31,25 @@ enum ui_align;
 
 struct probe_ops
   {
-    int ui_out_extra_fields;
+    /* Method responsible for verifying if the linespec provided is a valid
+       linespec for a probe breakpoint.  It should return 1 if it is, or zero
+       if it is not.  It also should update the pointer passed in order to
+       discard the breakpoint option associated with this linespec.  For
+       example, if the option is `-probe', and the linespec provided is
+       `-probe abc', the function should return 1 and set the string pointer
+       to `abc'.  */
+
+    int (*is_linespec) (const char **);
+
+    /* Function that should fill the `VEC (probe_p) **' argument with
+       known probes from the objfile specified.  */
 
-    int (*is_linespec) (const char **linespecp);
+    void (*get_probes) (VEC (probe_p) **, struct objfile *);
 
-    void (*get_probes) (VEC (probe_p) **probesp, struct objfile *objfile);
+    /* Function used to relocate a probe's addresses according to some
+       `CORE_ADDR' delta provided.  */
 
-    void (*relocate) (struct probe *probe, CORE_ADDR delta);
+    void (*relocate) (struct probe *, CORE_ADDR);
 
     /* Return the number of arguments of this probe.  */
 
@@ -73,21 +87,52 @@ struct probe_ops
 
     void (*destroy) (struct probe *);
 
-    void (*gen_ui_out_table_header) (struct ui_out *, enum ui_align);
+    /* Function responsible for providing the extra fields that will be
+       printed in the `info probes' command.  It should fill the
+       `VEC (const_char_ptr) **' with whatever extra fields it needs.
+       If the backend doesn't need to print extra fields, it can set this
+       method to NULL.  */
+
+    void (*gen_ui_out_table_header) (VEC (const_char_ptr) **);
+
+    /* Function that will provide a `VEC (const_char_ptr) **' containing
+       the values of the extra fields to be printed for the specified probe
+       and objfile.  If the backend implements the `gen_ui_out_table_header',
+       then it should implement this method as well.  The backend should also
+       guarantee that the order and the number of values in the vector is
+       exactly the same as the order of the extra fields provided in the
+       method `gen_ui_out_table_header'.  If a certain field is to be skipped
+       when printing the information, you can push a NULL value in that
+       position in the vector.  */
 
     void (*gen_ui_out_fields) (struct probe *, struct objfile *,
-			       struct ui_out *);
+			       VEC (const_char_ptr) **);
   };
 
+/* Definition of a vector of probe_ops.  */
+
 typedef const struct probe_ops *probe_ops_cp;
 DEF_VEC_P (probe_ops_cp);
 extern VEC (probe_ops_cp) *all_probe_ops;
 
+/* The probe_ops associated with the generic probe.  */
+
 extern const struct probe_ops probe_ops_any;
 
+/* Helper function that, given KEYWORDS, iterate over it trying to match
+   each keyword with LINESPECP.  If it succeeds, it updates the LINESPECP
+   pointer and returns 1.  Otherwise, nothing is done to LINESPECP and zero
+   is returned.  */
+
 extern int probe_is_linespec_by_keyword (const char **linespecp,
 					 const char *const *keywords);
 
+/* Return specific PROBE_OPS * matching *LINESPECP and possibly updating
+   *LINESPECP to skip its "-probe-type " prefix.  Return &probe_ops_any if
+   *LINESPECP matches "-probe ", that is any unspecific probe.  Return NULL if
+   *LINESPECP is not identified as any known probe type, *LINESPECP is not
+   modified in such case.  */
+
 extern const struct probe_ops *probe_linespec_to_ops (const char **linespecp);
 
 /* The probe itself.  The struct contains generic information about the
@@ -137,9 +182,18 @@ extern VEC (probe_p) *find_probes_in_objfile (struct objfile *objfile,
 					      const char *provider,
 					      const char *name);
 
+/* Generate a `info probes' command output for probe_ops represented by
+   POPS.  It is a helper function that can be used by the probe backends
+   to print their `info probe TYPE'.  */
+
 extern void info_probes_for_ops (char *arg, int from_tty,
 				 const struct probe_ops *pops);
 
+/* Return the `cmd_list_element' associated with the `info probes' command,
+   or create a new one if it doesn't exist.  Helper function that serves the
+   purpose of avoiding the case of a backend using the `cmd_list_element'
+   associated with `info probes', without having it registered yet.  */
+
 extern struct cmd_list_element **info_probes_cmdlist_get (void);
 
 /* A convenience function that finds a probe at the PC in FRAME and
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index 94ca5e0..3acebd5 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -93,6 +93,9 @@ DEF_VEC_O (stap_probe_arg_s);
 
 struct stap_probe
 {
+  /* Generic information about the probe.  This shall be the first element
+     of this struct, in order to maintain binary compatibility with the
+     `struct probe' and be able to fully abstract it.  */
   struct probe p;
 
   /* If the probe has a semaphore associated, then this is the value of
@@ -1446,36 +1449,31 @@ stap_probe_is_linespec (const char **linespecp)
 }
 
 static void
-stap_gen_ui_out_table_header (struct ui_out *uiout, enum ui_align uialign)
+stap_gen_ui_out_table_header (VEC (const_char_ptr) **fields)
 {
-  struct gdbarch *gdbarch = get_current_arch ();
-  int size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10;
-
-  ui_out_table_header (uiout, size_addr, uialign, "semaphore",
-		       _("Semaphore"));
+  VEC_safe_push (const_char_ptr, *fields, _("Semaphore"));
 }
 
 static void
-stap_gen_ui_out_fields (struct probe *probe_generic,
-			struct objfile *objfile, struct ui_out *uiout)
+stap_gen_ui_out_fields (struct probe *probe_generic, struct objfile *objfile,
+			VEC (const_char_ptr) **ret)
 {
   struct stap_probe *probe = (struct stap_probe *) probe_generic;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  const char *val = NULL;
 
   gdb_assert (probe_generic->pops == &stap_probe_ops);
 
-  if (probe->sem_addr == 0)
-    ui_out_field_skip (uiout, "semaphore");
-  else
-    ui_out_field_core_addr (uiout, "semaphore",
-			    get_objfile_arch (objfile),
-			    probe->sem_addr);
+  if (probe->sem_addr)
+    val = print_core_address (gdbarch, probe->sem_addr);
+
+  VEC_safe_push (const_char_ptr, *ret, val);
 }
 
 /* SystemTap probe_ops.  */
 
 static const struct probe_ops stap_probe_ops =
 {
-  1, /* ui_out_extra_fields */
   stap_probe_is_linespec,
   stap_get_probes,
   stap_relocate,


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


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

only message in thread, other threads:[~2012-04-20  4:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-20  4:19 [SCM] archer-sergiodj-stap-patches: New auto-sizing algorithms, new comments, etc sergiodj

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).