This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Make collect_probes return an std::vector


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1eac6bea98f41ee12ba9e750a9578bd8585011c9

commit 1eac6bea98f41ee12ba9e750a9578bd8585011c9
Author: Simon Marchi <simon.marchi@ericsson.com>
Date:   Tue Sep 12 13:55:32 2017 +0200

    Make collect_probes return an std::vector
    
    Change collect_probes so it returns an std::vector<bound_probe> instead
    of a VEC(bound_probe_s).  This allows removing some cleanups.  It also
    seems like enable_probes_command and disable_probes_command were not
    freeing that vector.
    
    The comparison function compare_probes needs to be updated to return a
    bool indicating whether the first parameter is "less than" the second
    parameter.
    
    I defined two constructors to bound_probe.  The default constructor is
    needed, for example, so the instance in struct bp_location can be
    constructed without parameters.  The constructor with parameters is
    useful so we can use emplace_back and pass the values directly.
    
    The s390 builder on the buildbot shows a weird failure that I can't
    explain:
    
    ../../binutils-gdb/gdb/elfread.c: In function void probe_key_free(bfd*, void*):
    ../../binutils-gdb/gdb/elfread.c:1346:8: error: types may not be defined in a for-range-declaration [-Werror]
       for (struct probe *probe : *probes)
            ^~~~~~
    
    I guess it's a bug with that specific version< of the compiler, since no
    other gcc gives me that error.  It is using:
    
      g++ (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1)
    
    Any idea about this problem?
    
    gdb/ChangeLog:
    
    	* probe.h (struct bound_probe): Define constructors.
    	* probe.c (bound_probe_s): Remove typedef.
    	(DEF_VEC_O (bound_probe_s)): Remove VEC.
    	(collect_probes): Change return type to std::vector, remove
    	cleanup.
    	(compare_probes): Return bool, change parameter type.  Change
    	semantic to "less than".
    	(gen_ui_out_table_header_info): Change parameter to std::vector
    	and update.
    	(exists_probe_with_pops): Likewise.
    	(info_probes_for_ops): Update to std::vector change.
    	(enable_probes_command): Likewise.
    	(disable_probes_command): Likewise.

Diff:
---
 gdb/ChangeLog |  16 +++++++
 gdb/probe.c   | 147 +++++++++++++++++++++++-----------------------------------
 gdb/probe.h   |  23 ++++++---
 3 files changed, 92 insertions(+), 94 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0a54a90..b5fe2e2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,21 @@
 2017-09-12  Simon Marchi  <simon.marchi@ericsson.com>
 
+	* probe.h (struct bound_probe): Define constructors.
+	* probe.c (bound_probe_s): Remove typedef.
+	(DEF_VEC_O (bound_probe_s)): Remove VEC.
+	(collect_probes): Change return type to std::vector, remove
+	cleanup.
+	(compare_probes): Return bool, change parameter type.  Change
+	semantic to "less than".
+	(gen_ui_out_table_header_info): Change parameter to std::vector
+	and update.
+	(exists_probe_with_pops): Likewise.
+	(info_probes_for_ops): Update to std::vector change.
+	(enable_probes_command): Likewise.
+	(disable_probes_command): Likewise.
+
+2017-09-12  Simon Marchi  <simon.marchi@ericsson.com>
+
 	* probe.h (struct probe_ops) <get_probes>: Change parameter from
 	vec to std::vector.
 	* probe.c (parse_probes_in_pspace): Update.
diff --git a/gdb/probe.c b/gdb/probe.c
index f09d5a4..36211ea 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -38,11 +38,6 @@
 #include <algorithm>
 #include "common/gdb_optional.h"
 
-typedef struct bound_probe bound_probe_s;
-DEF_VEC_O (bound_probe_s);
-
-
-
 /* A helper for parse_probes that decodes a probe specification in
    SEARCH_PSPACE.  It appends matching SALs to RESULT.  */
 
@@ -267,17 +262,14 @@ find_probe_by_pc (CORE_ADDR pc)
    If POPS is not NULL, only probes of this certain probe_ops will match.
    Each argument is a regexp, or NULL, which matches anything.  */
 
-static VEC (bound_probe_s) *
+static std::vector<bound_probe>
 collect_probes (const std::string &objname, const std::string &provider,
 		const std::string &probe_name, const struct probe_ops *pops)
 {
   struct objfile *objfile;
-  VEC (bound_probe_s) *result = NULL;
-  struct cleanup *cleanup;
+  std::vector<bound_probe> result;
   gdb::optional<compiled_regex> obj_pat, prov_pat, probe_pat;
 
-  cleanup = make_cleanup (VEC_cleanup (bound_probe_s), &result);
-
   if (!provider.empty ())
     prov_pat.emplace (provider.c_str (), REG_NOSUB,
 		      _("Invalid provider regexp"));
@@ -304,8 +296,6 @@ collect_probes (const std::string &objname, const std::string &provider,
 
       for (struct probe *probe : probes)
 	{
-	  struct bound_probe bound;
-
 	  if (pops != NULL && probe->pops != pops)
 	    continue;
 
@@ -317,46 +307,39 @@ collect_probes (const std::string &objname, const std::string &provider,
 	      && probe_pat->exec (probe->name, 0, NULL, 0) != 0)
 	    continue;
 
-	  bound.objfile = objfile;
-	  bound.probe = probe;
-	  VEC_safe_push (bound_probe_s, result, &bound);
+	  result.emplace_back (probe, objfile);
 	}
     }
 
-  discard_cleanups (cleanup);
   return result;
 }
 
 /* A qsort comparison function for bound_probe_s objects.  */
 
-static int
-compare_probes (const void *a, const void *b)
+static bool
+compare_probes (const bound_probe &a, const bound_probe &b)
 {
-  const struct bound_probe *pa = (const struct bound_probe *) a;
-  const struct bound_probe *pb = (const struct bound_probe *) b;
   int v;
 
-  v = strcmp (pa->probe->provider, pb->probe->provider);
-  if (v)
-    return v;
+  v = strcmp (a.probe->provider, b.probe->provider);
+  if (v != 0)
+    return v < 0;
 
-  v = strcmp (pa->probe->name, pb->probe->name);
-  if (v)
-    return v;
+  v = strcmp (a.probe->name, b.probe->name);
+  if (v != 0)
+    return v < 0;
 
-  if (pa->probe->address < pb->probe->address)
-    return -1;
-  if (pa->probe->address > pb->probe->address)
-    return 1;
+  if (a.probe->address != b.probe->address)
+    return a.probe->address < b.probe->address;
 
-  return strcmp (objfile_name (pa->objfile), objfile_name (pb->objfile));
+  return strcmp (objfile_name (a.objfile), objfile_name (b.objfile)) < 0;
 }
 
 /* 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 (bound_probe_s) *probes,
+gen_ui_out_table_header_info (const std::vector<bound_probe> &probes,
 			      const struct probe_ops *p)
 {
   /* `headings' refers to the names of the columns when printing `info
@@ -385,11 +368,9 @@ gen_ui_out_table_header_info (VEC (bound_probe_s) *probes,
        VEC_iterate (info_probe_column_s, headings, ix, column);
        ++ix)
     {
-      struct bound_probe *probe;
-      int jx;
       size_t size_max = strlen (column->print_name);
 
-      for (jx = 0; VEC_iterate (bound_probe_s, probes, jx, probe); ++jx)
+      for (const bound_probe &probe : probes)
 	{
 	  /* `probe_fields' refers to the values of each new field that this
 	     probe will display.  */
@@ -398,11 +379,11 @@ gen_ui_out_table_header_info (VEC (bound_probe_s) *probes,
 	  const char *val;
 	  int kx;
 
-	  if (probe->probe->pops != p)
+	  if (probe.probe->pops != p)
 	    continue;
 
 	  c2 = make_cleanup (VEC_cleanup (const_char_ptr), &probe_fields);
-	  p->gen_info_probes_table_values (probe->probe, &probe_fields);
+	  p->gen_info_probes_table_values (probe.probe, &probe_fields);
 
 	  gdb_assert (VEC_length (const_char_ptr, probe_fields)
 		      == headings_size);
@@ -529,14 +510,14 @@ get_number_extra_fields (const struct probe_ops *pops)
    featuring the given POPS.  It returns 0 otherwise.  */
 
 static int
-exists_probe_with_pops (VEC (bound_probe_s) *probes,
+exists_probe_with_pops (const std::vector<bound_probe> &probes,
 			const struct probe_ops *pops)
 {
   struct bound_probe *probe;
   int ix;
 
-  for (ix = 0; VEC_iterate (bound_probe_s, probes, ix, probe); ++ix)
-    if (probe->probe->pops == pops)
+  for (const bound_probe &probe : probes)
+    if (probe.probe->pops == pops)
       return 1;
 
   return 0;
@@ -568,21 +549,19 @@ info_probes_for_ops (const char *arg, int from_tty,
 {
   std::string provider, probe_name, objname;
   struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
-  VEC (bound_probe_s) *probes;
-  int i, any_found;
+  int any_found;
   int ui_out_extra_fields = 0;
   size_t size_addr;
   size_t size_name = strlen ("Name");
   size_t size_objname = strlen ("Object");
   size_t size_provider = strlen ("Provider");
   size_t size_type = strlen ("Type");
-  struct bound_probe *probe;
   struct gdbarch *gdbarch = get_current_arch ();
 
   parse_probe_linespec (arg, &provider, &probe_name, &objname);
 
-  probes = collect_probes (objname, provider, probe_name, pops);
-  make_cleanup (VEC_cleanup (probe_p), &probes);
+  std::vector<bound_probe> probes
+    = collect_probes (objname, provider, probe_name, pops);
 
   if (pops == NULL)
     {
@@ -609,27 +588,23 @@ info_probes_for_ops (const char *arg, int from_tty,
   {
     ui_out_emit_table table_emitter (current_uiout,
 				     5 + ui_out_extra_fields,
-				     VEC_length (bound_probe_s, probes),
-				     "StaticProbes");
+				     probes.size (), "StaticProbes");
 
-    if (!VEC_empty (bound_probe_s, probes))
-      qsort (VEC_address (bound_probe_s, probes),
-	     VEC_length (bound_probe_s, probes),
-	     sizeof (bound_probe_s), compare_probes);
+    std::sort (probes.begin (), probes.end (), compare_probes);
 
     /* What's the size of an address in our architecture?  */
     size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10;
 
     /* Determining the maximum size of each field (`type', `provider',
        `name' and `objname').  */
-    for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
+    for (const bound_probe &probe : probes)
       {
-	const char *probe_type = probe->probe->pops->type_name (probe->probe);
+	const char *probe_type = probe.probe->pops->type_name (probe.probe);
 
 	size_type = std::max (strlen (probe_type), size_type);
-	size_name = std::max (strlen (probe->probe->name), size_name);
-	size_provider = std::max (strlen (probe->probe->provider), size_provider);
-	size_objname = std::max (strlen (objfile_name (probe->objfile)),
+	size_name = std::max (strlen (probe.probe->name), size_name);
+	size_provider = std::max (strlen (probe.probe->provider), size_provider);
+	size_objname = std::max (strlen (objfile_name (probe.objfile)),
 				 size_objname);
       }
 
@@ -657,18 +632,18 @@ info_probes_for_ops (const char *arg, int from_tty,
     current_uiout->table_header (size_objname, ui_left, "object", _("Object"));
     current_uiout->table_body ();
 
-    for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
+    for (const bound_probe &probe : probes)
       {
-	const char *probe_type = probe->probe->pops->type_name (probe->probe);
+	const char *probe_type = probe.probe->pops->type_name (probe.probe);
 
 	ui_out_emit_tuple tuple_emitter (current_uiout, "probe");
 
 	current_uiout->field_string ("type",probe_type);
-	current_uiout->field_string ("provider", probe->probe->provider);
-	current_uiout->field_string ("name", probe->probe->name);
-	current_uiout->field_core_addr (
-					"addr", probe->probe->arch,
-					get_probe_address (probe->probe, probe->objfile));
+	current_uiout->field_string ("provider", probe.probe->provider);
+	current_uiout->field_string ("name", probe.probe->name);
+	current_uiout->field_core_addr ("addr", probe.probe->arch,
+					get_probe_address (probe.probe,
+							   probe.objfile));
 
 	if (pops == NULL)
 	  {
@@ -677,20 +652,20 @@ info_probes_for_ops (const char *arg, int from_tty,
 
 	    for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po);
 		 ++ix)
-	      if (probe->probe->pops == po)
-		print_ui_out_info (probe->probe);
+	      if (probe.probe->pops == po)
+		print_ui_out_info (probe.probe);
 	      else if (exists_probe_with_pops (probes, po))
 		print_ui_out_not_applicables (po);
 	  }
 	else
-	  print_ui_out_info (probe->probe);
+	  print_ui_out_info (probe.probe);
 
 	current_uiout->field_string ("object",
-				     objfile_name (probe->objfile));
+				     objfile_name (probe.objfile));
 	current_uiout->text ("\n");
       }
 
-    any_found = !VEC_empty (bound_probe_s, probes);
+    any_found = !probes.empty ();
   }
   do_cleanups (cleanup);
 
@@ -713,14 +688,12 @@ enable_probes_command (char *arg, int from_tty)
 {
   std::string provider, probe_name, objname;
   struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
-  VEC (bound_probe_s) *probes;
-  struct bound_probe *probe;
-  int i;
 
   parse_probe_linespec ((const char *) arg, &provider, &probe_name, &objname);
 
-  probes = collect_probes (objname, provider, probe_name, NULL);
-  if (VEC_empty (bound_probe_s, probes))
+  std::vector<bound_probe> probes
+    = collect_probes (objname, provider, probe_name, NULL);
+  if (probes.empty ())
     {
       current_uiout->message (_("No probes matched.\n"));
       do_cleanups (cleanup);
@@ -729,19 +702,19 @@ enable_probes_command (char *arg, int from_tty)
 
   /* Enable the selected probes, provided their backends support the
      notion of enabling a probe.  */
-  for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
+  for (const bound_probe &probe: probes)
     {
-      const struct probe_ops *pops = probe->probe->pops;
+      const struct probe_ops *pops = probe.probe->pops;
 
       if (pops->enable_probe != NULL)
 	{
-	  pops->enable_probe (probe->probe);
+	  pops->enable_probe (probe.probe);
 	  current_uiout->message (_("Probe %s:%s enabled.\n"),
-				  probe->probe->provider, probe->probe->name);
+				  probe.probe->provider, probe.probe->name);
 	}
       else
 	current_uiout->message (_("Probe %s:%s cannot be enabled.\n"),
-				probe->probe->provider, probe->probe->name);
+				probe.probe->provider, probe.probe->name);
     }
 
   do_cleanups (cleanup);
@@ -754,14 +727,12 @@ disable_probes_command (char *arg, int from_tty)
 {
   std::string provider, probe_name, objname;
   struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
-  VEC (bound_probe_s) *probes;
-  struct bound_probe *probe;
-  int i;
 
   parse_probe_linespec ((const char *) arg, &provider, &probe_name, &objname);
 
-  probes = collect_probes (objname, provider, probe_name, NULL /* pops */);
-  if (VEC_empty (bound_probe_s, probes))
+  std::vector<bound_probe> probes
+    = collect_probes (objname, provider, probe_name, NULL /* pops */);
+  if (probes.empty ())
     {
       current_uiout->message (_("No probes matched.\n"));
       do_cleanups (cleanup);
@@ -770,19 +741,19 @@ disable_probes_command (char *arg, int from_tty)
 
   /* Disable the selected probes, provided their backends support the
      notion of enabling a probe.  */
-  for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
+  for (const bound_probe &probe : probes)
     {
-      const struct probe_ops *pops = probe->probe->pops;
+      const struct probe_ops *pops = probe.probe->pops;
 
       if (pops->disable_probe != NULL)
 	{
-	  pops->disable_probe (probe->probe);
+	  pops->disable_probe (probe.probe);
 	  current_uiout->message (_("Probe %s:%s disabled.\n"),
-				  probe->probe->provider, probe->probe->name);
+				  probe.probe->provider, probe.probe->name);
 	}
       else
 	current_uiout->message (_("Probe %s:%s cannot be disabled.\n"),
-				probe->probe->provider, probe->probe->name);
+				probe.probe->provider, probe.probe->name);
     }
 
   do_cleanups (cleanup);
diff --git a/gdb/probe.h b/gdb/probe.h
index 61e3031..3248dc8 100644
--- a/gdb/probe.h
+++ b/gdb/probe.h
@@ -214,15 +214,26 @@ struct probe
    their point of use.  */
 
 struct bound_probe
-  {
-    /* The probe.  */
+{
+  /* Create an empty bound_probe object.  */
 
-    struct probe *probe;
+  bound_probe ()
+  {}
 
-    /* The objfile in which the probe originated.  */
+  /* Create and initialize a bound_probe object using PROBE and OBJFILE.  */
 
-    struct objfile *objfile;
-  };
+  bound_probe (struct probe *probe_, struct objfile *objfile_)
+  : probe (probe_), objfile (objfile_)
+  {}
+
+  /* The probe.  */
+
+  struct probe *probe = NULL;
+
+  /* The objfile in which the probe originated.  */
+
+  struct objfile *objfile = NULL;
+};
 
 /* A helper for linespec that decodes a probe specification.  It
    returns a std::vector<symtab_and_line> object and updates LOC or


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]