[PATCH V3 3/9] New commands `enable probe' and `disable probe'.

"Jose E. Marchesi" <[email protected]>
Newsgroups gmane.comp.gdb.devel
Message-ID <[email protected]>
This patch adds the above-mentioned commands to the generic probe
abstraction implemented in probe.[ch].  The effects associated to
enabling or disabling a probe depend on the type of probe being
handled, and is triggered by invoking two back-end hooks in
`probe_ops'.

In case some particular probe type does not support the notion of
enabling and/or disabling, the corresponding fields on `probe_ops' can
be initialized to NULL.  This is the case of SystemTap probes.

gdb/ChangeLog:

  2014-10-28  Jose E. Marchesi  <[email protected]>

    	* stap-probe.c (stap_probe_ops): Add NULLs in the static
    	stap_probe_ops for `enable_probe' and `disable_probe'.
    	* probe.c (enable_probes_command): New function.
    	(disable_probes_command): Likewise.
    	(_initialize_probe): Define the cli commands `enable probe' and
    	`disable probe'.
    	(parse_probe_linespec): New function.
    	(info_probes_for_ops): Use parse_probe_linespec.
    	* probe.h (probe_ops): New hooks `enable_probe' and
    	`disable_probe'.

gdb/doc/ChangeLog:

  2014-10-28  Jose E. Marchesi  <[email protected]>

  	* gdb.texinfo (Static Probe Points): Cover the `enable probe' and
	  `disable probe' commands.
---
 gdb/ChangeLog       |   13 +++++
 gdb/doc/ChangeLog   |    5 ++
 gdb/doc/gdb.texinfo |   29 ++++++++++
 gdb/probe.c         |  161 ++++++++++++++++++++++++++++++++++++++++++++-------
 gdb/probe.h         |   12 ++++
 gdb/stap-probe.c    |    2 +
 6 files changed, 202 insertions(+), 20 deletions(-)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 15c2908..cfdc506 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -4976,6 +4976,35 @@ given, all object files are considered.
 List the available static probes, from all types.
 @end table
 
+@cindex enabling and disabling probes
+Some probe points can be enabled and/or disabled.  The effect of
+enabling or disabling a probe depends on the type of probe being
+handled.  @code{SystemTap} probes cannot be disabled.
+
+You can enable (or disable) one or more probes using the following
+commands, with optional arguments:
+
+@table @code
+@kindex enable probes
+@item enable probes @r{[}@var{provider} @r{[}@var{name} @r{[}@var{objfile}@r{]}@r{]}@r{]}
+If given, @var{provider} is a regular expression used to match against
+provider names when selecting which probes to enable.  If omitted,
+all probes from all providers are enabled.
+
+If given, @var{name} is a regular expression to match against probe
+names when selecting which probes to enable.  If omitted, probe names
+are not considered when deciding whether to enable them.
+
+If given, @var{objfile} is a regular expression used to select which
+object files (executable or shared libraries) to examine.  If not
+given, all object files are considered.
+
+@kindex disable probes
+@item disable probes @r{[}@var{provider} @r{[}@var{name} @r{[}@var{objfile}@r{]}@r{]}@r{]}
+See the @code{enable probes} command above for a description of the
+optional arguments accepted by this command.
+@end table
+
 @vindex $_probe_arg@r{, convenience variable}
 A probe may specify up to twelve arguments.  These are available at the
 point at which the probe is defined---that is, when the current PC is
diff --git a/gdb/probe.c b/gdb/probe.c
index 102c2e1..b96c8ac 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -423,18 +423,18 @@ print_ui_out_not_applicables (const struct probe_ops *pops)
   VEC (info_probe_column_s) *headings = NULL;
   info_probe_column_s *column;
   int ix;
-  
+
   if (pops->gen_info_probes_table_header == NULL)
     return;
 
   c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
   pops->gen_info_probes_table_header (&headings);
-  
+
   for (ix = 0;
        VEC_iterate (info_probe_column_s, headings, ix, column);
        ++ix)
     ui_out_field_string (current_uiout, column->field_name, _("n/a"));
-  
+
   do_cleanups (c);
 }
 
@@ -527,6 +527,24 @@ exists_probe_with_pops (VEC (bound_probe_s) *probes,
   return 0;
 }
 
+/* Helper function that parses a probe linespec of the form [PROVIDER
+   [PROBE [OBJNAME]]] from the provided string STR.  */
+
+static void
+parse_probe_linespec (const char *str, char **provider,
+		      char **probe_name, char **objname)
+{
+  *probe_name = *objname = NULL;
+
+  *provider = extract_arg_const (&str);
+  if (*provider != NULL)
+    {
+      *probe_name = extract_arg_const (&str);
+      if (*probe_name != NULL)
+	*objname = extract_arg_const (&str);
+    }
+}
+
 /* See comment in probe.h.  */
 
 void
@@ -546,26 +564,14 @@ info_probes_for_ops (const char *arg, int from_tty,
   struct bound_probe *probe;
   struct gdbarch *gdbarch = get_current_arch ();
 
-  /* Do we have a `provider:probe:objfile' style of linespec?  */
-  provider = extract_arg_const (&arg);
-  if (provider)
-    {
-      make_cleanup (xfree, provider);
-
-      probe_name = extract_arg_const (&arg);
-      if (probe_name)
-	{
-	  make_cleanup (xfree, probe_name);
-
-	  objname = extract_arg_const (&arg);
-	  if (objname)
-	    make_cleanup (xfree, objname);
-	}
-    }
+  parse_probe_linespec (arg, &provider, &probe_name, &objname);
+  make_cleanup (xfree, provider);
+  make_cleanup (xfree, probe_name);
+  make_cleanup (xfree, objname);
 
   probes = collect_probes (objname, provider, probe_name, pops);
   make_cleanup (VEC_cleanup (probe_p), &probes);
-  
+
   if (pops == NULL)
     {
       const struct probe_ops *po;
@@ -689,6 +695,98 @@ info_probes_command (char *arg, int from_tty)
   info_probes_for_ops (arg, from_tty, NULL);
 }
 
+/* Implementation of the `enable probes' command.  */
+
+static void
+enable_probes_command (char *arg, int from_tty)
+{
+  char *provider, *probe_name = NULL, *objname = NULL;
+  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);
+  make_cleanup (xfree, provider);
+  make_cleanup (xfree, probe_name);
+  make_cleanup (xfree, objname);
+
+  probes = collect_probes (objname, provider, probe_name, NULL);
+  if (VEC_empty (bound_probe_s, probes))
+    {
+      ui_out_message (current_uiout, 0, _("No probes matched.\n"));
+      do_cleanups (cleanup);
+      return;
+    }
+
+  /* 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)
+    {
+      const struct probe_ops *pops = probe->probe->pops;
+
+      if (pops->enable_probe != NULL)
+	{
+	  pops->enable_probe (probe->probe);
+	  ui_out_message (current_uiout, 0,
+			  _("Probe %s:%s enabled.\n"),
+			  probe->probe->provider, probe->probe->name);
+	}
+      else
+	ui_out_message (current_uiout, 0,
+			_("Probe %s:%s cannot be enabled.\n"),
+			probe->probe->provider, probe->probe->name);
+    }
+
+  do_cleanups (cleanup);
+}
+
+/* Implementation of the `disable probes' command.  */
+
+static void
+disable_probes_command (char *arg, int from_tty)
+{
+  char *provider, *probe_name = NULL, *objname = NULL;
+  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);
+  make_cleanup (xfree, provider);
+  make_cleanup (xfree, probe_name);
+  make_cleanup (xfree, objname);
+
+  probes = collect_probes (objname, provider, probe_name, NULL /* pops */);
+  if (VEC_empty (bound_probe_s, probes))
+    {
+      ui_out_message (current_uiout, 0, _("No probes matched.\n"));
+      do_cleanups (cleanup);
+      return;
+    }
+
+  /* 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)
+    {
+      const struct probe_ops *pops = probe->probe->pops;
+
+      if (pops->disable_probe != NULL)
+	{
+	  pops->disable_probe (probe->probe);
+	  ui_out_message (current_uiout, 0,
+			  _("Probe %s:%s disabled.\n"),
+			  probe->probe->provider, probe->probe->name);
+	}
+      else
+	ui_out_message (current_uiout, 0,
+			_("Probe %s:%s cannot be disabled.\n"),
+			probe->probe->provider, probe->probe->name);
+    }
+
+  do_cleanups (cleanup);
+}
+
 /* See comments in probe.h.  */
 
 CORE_ADDR
@@ -950,4 +1048,27 @@ _initialize_probe (void)
 	   _("\
 Show information about all type of probes."),
 	   info_probes_cmdlist_get ());
+
+  add_cmd ("probes", class_breakpoint, enable_probes_command, _("\
+Enable probes.\n\
+Usage: enable probes [PROVIDER [NAME [OBJECT]]]\n\
+Each argument is a regular expression, used to select probes.\n\
+PROVIDER matches probe provider names.\n\
+NAME matches the probe names.\n\
+OBJECT matches the executable or shared library name.\n\
+If you do not specify any argument then the command will enable\n\
+all defined probes."),
+	   &enablelist);
+
+  add_cmd ("probes", class_breakpoint, disable_probes_command, _("\
+Disable probes.\n\
+Usage: disable probes [PROVIDER [NAME [OBJECT]]]\n\
+Each argument is a regular expression, used to select probes.\n\
+PROVIDER matches probe provider names.\n\
+NAME matches the probe names.\n\
+OBJECT matches the executable or shared library name.\n\
+If you do not specify any argument then the command will disable\n\
+all defined probes."),
+	   &disablelist);
+
 }
diff --git a/gdb/probe.h b/gdb/probe.h
index 66c8c53..c244a21 100644
--- a/gdb/probe.h
+++ b/gdb/probe.h
@@ -138,6 +138,18 @@ struct probe_ops
 
     void (*gen_info_probes_table_values) (struct probe *probe,
 					  VEC (const_char_ptr) **values);
+
+    /* Enable a probe.  The semantics of "enabling" a probe depend on
+       the specific backend and the field can be NULL in case enabling
+       probes is not supported.  */
+
+    void (*enable_probe) (struct probe *probe);
+
+    /* Disable a probe.  The semantics of "disabling" a probe depend
+       on the specific backend and the field can be NULL in case
+       disabling probes is not supported.  */
+
+    void (*disable_probe) (struct probe *probe);
   };
 
 /* Definition of a vector of probe_ops.  */
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index ed4ce69..8366ce2 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -1684,6 +1684,8 @@ static const struct probe_ops stap_probe_ops =
   stap_type_name,
   stap_gen_info_probes_table_header,
   stap_gen_info_probes_table_values,
+  NULL,  /* enable_probe  */
+  NULL   /* disable_probe  */
 };
 
 /* Implementation of the `info probes stap' command.  */
-- 
1.7.10.4
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.