[V2,3/9] New commands `enable probe' and `disable probe'.

Message ID 1412961772-16249-4-git-send-email-jose.marchesi@oracle.com
State Superseded
Headers

Commit Message

Jose E. Marchesi Oct. 10, 2014, 5:22 p.m. UTC
  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-10  Jose E. Marchesi  <jose.marchesi@oracle.com>

    	* 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-10  Jose E. Marchesi  <jose.marchesi@oracle.com>

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

Comments

Eli Zaretskii Oct. 10, 2014, 6:15 p.m. UTC | #1
> From: "Jose E. Marchesi" <jose.marchesi@oracle.com>
> Date: Fri, 10 Oct 2014 19:22:46 +0200
> 
> +Some probe points can be enabled and/or disabled.  The effects
> +associated to enabling or disabling a probe depend on the type of

Just "the effect of enabling or disabling a probe" is enough, and much
more clear.

> +probe being handled. @code{SystemTap} probes do not support these
                      ^^
Two spaces between sentences.

Also, I think we agreed to say SystemTap probes cannot be disabled.

> +@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,
> +probes by all probes from all providers are enabled.

"Probes by all probes"?  Something is wrong here.

Thanks.
  
Doug Evans Oct. 10, 2014, 10:03 p.m. UTC | #2
Jose E. Marchesi writes:
 > 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-10  Jose E. Marchesi  <jose.marchesi@oracle.com>
 > 
 >     	* 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-10  Jose E. Marchesi  <jose.marchesi@oracle.com>
 > 
 >   	* gdb.texinfo (Static Probe Points): Cover the `enable probe' and
 > 	  `disable probe' commands.

Hi.
Would it be useful to have "info probes" show
the enable/disable state of each probe?
Or at least know which ones have been disabled.

I can imagine wanting to know this information if something
wasn't working the way I expected.
  
Jose E. Marchesi Oct. 11, 2014, 6:39 a.m. UTC | #3
Hi Doug.

    Would it be useful to have "info probes" show
    the enable/disable state of each probe?
    Or at least know which ones have been disabled.

Right, `info probes' actually tells you the "Enabled" status of the
probes, provided there is at least one dtrace probe in the executable.
For example:

(gdb) info probes
Provider Name             Where              Semaphore Enabled Object                         
demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo 
demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo 
demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo

In the example above demo:am-main is a systemtap probe, for which
"Enabled" reads n/a.  demo:another is a dtrace probe which cannot be
disabled (it does not have any associated enabler) and
demo:progress-counter is a dtrace probe which is disabled.

This is the source code used for the example above:

#include "stap-sdt.h"
#include "demo.h"

int main(int argc, char *argv[]) {
  int i=0;
  long int foo = 666;
  char *jaja = "oh yeah";

   while (i < 10) {
      i++;
      if (DEMO_PROGRESS_COUNTER_ENABLED())
        DEMO_PROGRESS_COUNTER (i, foo, jaja);
      DEMO_ANOTHER (i);
   }

   STAP_PROBE3(demo, am-main, i, foo, jaja);
   i = 0;
}
  
Sergio Durigan Junior Oct. 11, 2014, 5:04 p.m. UTC | #4
On Friday, October 10 2014, Doug Evans wrote:

> Would it be useful to have "info probes" show
> the enable/disable state of each probe?
> Or at least know which ones have been disabled.
>
> I can imagine wanting to know this information if something
> wasn't working the way I expected.

The patch does that already.  :-)
  
Doug Evans Oct. 13, 2014, 4:40 p.m. UTC | #5
On Fri, Oct 10, 2014 at 11:39 PM, Jose E. Marchesi
<jose.marchesi@oracle.com> wrote:
>
> Hi Doug.
>
>     Would it be useful to have "info probes" show
>     the enable/disable state of each probe?
>     Or at least know which ones have been disabled.
>
> Right, `info probes' actually tells you the "Enabled" status of the
> probes, provided there is at least one dtrace probe in the executable.
> For example:
>
> (gdb) info probes
> Provider Name             Where              Semaphore Enabled Object
> demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo
> demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo
> demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo

Thanks.  I couldn't find it, where should I look?
  
Sergio Durigan Junior Oct. 14, 2014, 6:53 p.m. UTC | #6
Hi Jose,

Thanks for the v2!  Looks great.  Just a minor nit.

On Friday, October 10 2014, Jose E. Marchesi wrote:

> diff --git a/gdb/probe.c b/gdb/probe.c
> index 69ca0aa..c548b27 100644
> --- a/gdb/probe.c
> +++ b/gdb/probe.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)

Ops, another implicit comparison :-).

> +    {
> +      *probe_name = extract_arg_const (&str);
> +      if (*probe_name)

Here too.

> +	*objname = extract_arg_const (&str);
> +    }
> +}
> +

Looks good to me otherwise.
  
Sergio Durigan Junior Oct. 14, 2014, 7:01 p.m. UTC | #7
On Monday, October 13 2014, Doug Evans wrote:

> On Fri, Oct 10, 2014 at 11:39 PM, Jose E. Marchesi
> <jose.marchesi@oracle.com> wrote:
>>
>> Hi Doug.
>>
>>     Would it be useful to have "info probes" show
>>     the enable/disable state of each probe?
>>     Or at least know which ones have been disabled.
>>
>> Right, `info probes' actually tells you the "Enabled" status of the
>> probes, provided there is at least one dtrace probe in the executable.
>> For example:
>>
>> (gdb) info probes
>> Provider Name             Where              Semaphore Enabled Object
>> demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo
>> demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo
>> demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo
>
> Thanks.  I couldn't find it, where should I look?

This is on patch 1/9.
  
Jose E. Marchesi Oct. 15, 2014, 1:30 p.m. UTC | #8
> +/* 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)
    
    Ops, another implicit comparison :-).

I changed these comparisons to be explicit.
  
Doug Evans Oct. 17, 2014, 12:07 a.m. UTC | #9
On Tue, Oct 14, 2014 at 12:01 PM, Sergio Durigan Junior
<sergiodj@redhat.com> wrote:
> On Monday, October 13 2014, Doug Evans wrote:
>
>> On Fri, Oct 10, 2014 at 11:39 PM, Jose E. Marchesi
>> <jose.marchesi@oracle.com> wrote:
>>>
>>> Hi Doug.
>>>
>>>     Would it be useful to have "info probes" show
>>>     the enable/disable state of each probe?
>>>     Or at least know which ones have been disabled.
>>>
>>> Right, `info probes' actually tells you the "Enabled" status of the
>>> probes, provided there is at least one dtrace probe in the executable.
>>> For example:
>>>
>>> (gdb) info probes
>>> Provider Name             Where              Semaphore Enabled Object
>>> demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo
>>> demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo
>>> demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo
>>
>> Thanks.  I couldn't find it, where should I look?
>
> This is on patch 1/9.

Thanks.
I found the details of the "Enabled" column in 5/9.
  
Pedro Alves Oct. 17, 2014, 12:36 a.m. UTC | #10
On 10/11/2014 07:39 AM, Jose E. Marchesi wrote:
> 
> (gdb) info probes
> Provider Name             Where              Semaphore Enabled Object                         
> demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo 
> demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo 
> demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo
> 
> In the example above demo:am-main is a systemtap probe, for which
> "Enabled" reads n/a.  demo:another is a dtrace probe which cannot be
> disabled (it does not have any associated enabler) and
> demo:progress-counter is a dtrace probe which is disabled.

Shouldn't we explicitly say which probe is stap, vs dprobe (vs whatever
other probe type)?  Like, either a new column:

~~~
Type    Provider Name             Where              Semaphore Enabled Object
stap    demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo
dtrace  demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo
dtrace  demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo
~~~

or, sort output by probe type:

~~~
Stap probes:

Type    Provider Name             Where              Semaphore Enabled Object
stap    demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo

Dtrace probes:

Type    Provider Name             Where              Semaphore Enabled Object
dtrace  demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo
dtrace  demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo
~~~

Thanks,
Pedro Alves
  
Pedro Alves Oct. 17, 2014, 12:43 a.m. UTC | #11
On 10/17/2014 01:36 AM, Pedro Alves wrote:
> On 10/11/2014 07:39 AM, Jose E. Marchesi wrote:
>>
>> (gdb) info probes
>> Provider Name             Where              Semaphore Enabled Object                         
>> demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo 
>> demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo 
>> demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo
>>
>> In the example above demo:am-main is a systemtap probe, for which
>> "Enabled" reads n/a.  demo:another is a dtrace probe which cannot be
>> disabled (it does not have any associated enabler) and
>> demo:progress-counter is a dtrace probe which is disabled.
> 
> Shouldn't we explicitly say which probe is stap, vs dprobe (vs whatever
> other probe type)?  Like, either a new column:
> 
> ~~~
> Type    Provider Name             Where              Semaphore Enabled Object
> stap    demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo
> dtrace  demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo
> dtrace  demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo
> ~~~
> 
> or, sort output by probe type:
> 
> ~~~
> Stap probes:
> 
> Type    Provider Name             Where              Semaphore Enabled Object
> stap    demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo
> 
> Dtrace probes:
> 
> Type    Provider Name             Where              Semaphore Enabled Object
> dtrace  demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo
> dtrace  demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo
> ~~~

This also raises the question, can't we have both a stap
probe and a dtrace probe with the name provider and name?  Like,
using the proposed output that doesn't distinguish the probe types,
can't the user end up with the confusing:

Provider Name             Where              Semaphore Enabled Object
demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo
demo     am-main          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo

Does GDB cope correctly with this?  Will the user have
trouble specifying the probe he wants with the current UI?

Thanks,
Pedro Alves
  
Sergio Durigan Junior Oct. 17, 2014, 12:55 a.m. UTC | #12
On Thursday, October 16 2014, Pedro Alves wrote:

> On 10/11/2014 07:39 AM, Jose E. Marchesi wrote:
>> 
>> (gdb) info probes
>> Provider Name             Where              Semaphore Enabled Object                         
>> demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo 
>> demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo 
>> demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo
>> 
>> In the example above demo:am-main is a systemtap probe, for which
>> "Enabled" reads n/a.  demo:another is a dtrace probe which cannot be
>> disabled (it does not have any associated enabler) and
>> demo:progress-counter is a dtrace probe which is disabled.
>
> Shouldn't we explicitly say which probe is stap, vs dprobe (vs whatever
> other probe type)?  Like, either a new column:

This is actually a nice idea, and if I say that I thought about it while
testing the patch, but then forgot to mention, would it seem strange?  :-)

> ~~~
> Type    Provider Name             Where              Semaphore Enabled Object
> stap    demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo
> dtrace  demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo
> dtrace  demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo
> ~~~
>
> or, sort output by probe type:

I prefer a new column.

> ~~~
> Stap probes:
>
> Type    Provider Name             Where              Semaphore Enabled Object
> stap    demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo
>
> Dtrace probes:
>
> Type    Provider Name             Where              Semaphore Enabled Object
> dtrace  demo     another          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo
> dtrace  demo     progress-counter 0x0000000000400c81 n/a       no      /home/jemarch/oracle/usdt/demo
> ~~~

Thanks.
  
Sergio Durigan Junior Oct. 17, 2014, 2:31 a.m. UTC | #13
On Thursday, October 16 2014, Pedro Alves wrote:

> This also raises the question, can't we have both a stap
> probe and a dtrace probe with the name provider and name?  Like,
> using the proposed output that doesn't distinguish the probe types,
> can't the user end up with the confusing:
>
> Provider Name             Where              Semaphore Enabled Object
> demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo
> demo     am-main          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo
>
> Does GDB cope correctly with this?  Will the user have
> trouble specifying the probe he wants with the current UI?

Aha, a good question :-P.

Well, you can actually test this with current GDB, without even needing
dtrace:

  (gdb) info probes
  Provider Name Where              Semaphore Object                                                                    
  test    bla  0x00000000004004f4           a.out
  test    bla  0x00000000004004f5           a.out
  (gdb) b -p bla
  Breakpoint 1 at 0x4004f4 (2 locations)

You have basically two ways of specifying where the probe breakpoint is
going to be located: either by using -probe (or -p), or using
-probe-[type] (or -p[type]).  The second way is not problematic, because
you tell GDB that type you want explicitly, so there is no confusion.
However, in the first way, you put a breakpoint in a "probe" (the type
is not important here, only the probe name/provider).  GDB will then try
to see if any of the probe backends have probes with this name, and will
put a breakpoint on every probe it finds (again, no matter which type).

The logic for this is in gdb/probe.c:parse_probes, if you are
interested.

This is already working (as you can see in my example above), and Jose's
patch does not touch it, so we are pretty much covered in this area.

Nonetheless, I think it is a good idea to add one more field to the
output of 'info probes', specifying the probe type.

Thanks,
  
Jose E. Marchesi Oct. 17, 2014, 5:57 a.m. UTC | #14
> Shouldn't we explicitly say which probe is stap, vs dprobe (vs whatever
    > other probe type)?  Like, either a new column:
    
    This is actually a nice idea, and if I say that I thought about it while
    testing the patch, but then forgot to mention, would it seem
    strange?  :-)

Noooo ;)

I like the idea of having a new column with the type.  I will add an
extra patch to the patch series.
  
Pedro Alves Oct. 17, 2014, 11:23 a.m. UTC | #15
On 10/17/2014 03:31 AM, Sergio Durigan Junior wrote:
> On Thursday, October 16 2014, Pedro Alves wrote:
> 
>> This also raises the question, can't we have both a stap
>> probe and a dtrace probe with the name provider and name?  Like,
>> using the proposed output that doesn't distinguish the probe types,
>> can't the user end up with the confusing:
>>
>> Provider Name             Where              Semaphore Enabled Object
>> demo     am-main          0x0000000000400c96           n/a     /home/jemarch/oracle/usdt/demo
>> demo     am-main          0x0000000000400c8b n/a       always  /home/jemarch/oracle/usdt/demo
>>
>> Does GDB cope correctly with this?  Will the user have
>> trouble specifying the probe he wants with the current UI?
> 
> Aha, a good question :-P.
> 
> Well, you can actually test this with current GDB, without even needing
> dtrace:
> 
>   (gdb) info probes
>   Provider Name Where              Semaphore Object                                                                    
>   test    bla  0x00000000004004f4           a.out
>   test    bla  0x00000000004004f5           a.out
>   (gdb) b -p bla
>   Breakpoint 1 at 0x4004f4 (2 locations)
> 
> You have basically two ways of specifying where the probe breakpoint is
> going to be located: either by using -probe (or -p), or using
> -probe-[type] (or -p[type]).  The second way is not problematic, because
> you tell GDB that type you want explicitly, so there is no confusion.
> However, in the first way, you put a breakpoint in a "probe" (the type
> is not important here, only the probe name/provider).  GDB will then try
> to see if any of the probe backends have probes with this name, and will
> put a breakpoint on every probe it finds (again, no matter which type).
> 
> The logic for this is in gdb/probe.c:parse_probes, if you are
> interested.
> 
> This is already working (as you can see in my example above), and Jose's
> patch does not touch it, so we are pretty much covered in this area.

Excellent, thank you.

> Nonetheless, I think it is a good idea to add one more field to the
> output of 'info probes', specifying the probe type.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 429c650..a9c70b0 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -4976,6 +4976,36 @@  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 effects
+associated to enabling or disabling a probe depend on the type of
+probe being handled. @code{SystemTap} probes do not support these
+notions.
+
+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,
+probes by 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 69ca0aa..c548b27 100644
--- a/gdb/probe.c
+++ b/gdb/probe.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)
+    {
+      *probe_name = extract_arg_const (&str);
+      if (*probe_name)
+	*objname = extract_arg_const (&str);
+    }
+}
+
 /* See comment in probe.h.  */
 
 void
@@ -545,22 +563,10 @@  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);
@@ -682,6 +688,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
@@ -943,4 +1041,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 b4ff0a6..3f27d0d 100644
--- a/gdb/probe.h
+++ b/gdb/probe.h
@@ -132,6 +132,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 bcbb42f..43dc248 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -1674,6 +1674,8 @@  static const struct probe_ops stap_probe_ops =
   stap_probe_destroy,
   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.  */