From patchwork Tue Oct 28 13:50:12 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Jose E. Marchesi" X-Patchwork-Id: 3442 Received: (qmail 12764 invoked by alias); 28 Oct 2014 13:45:30 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 12498 invoked by uid 89); 28 Oct 2014 13:45:26 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_PASS, UNPARSEABLE_RELAY autolearn=ham version=3.3.2 X-HELO: aserp1040.oracle.com Received: from aserp1040.oracle.com (HELO aserp1040.oracle.com) (141.146.126.69) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Tue, 28 Oct 2014 13:45:19 +0000 Received: from ucsinet22.oracle.com (ucsinet22.oracle.com [156.151.31.94]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s9SDjHRJ014108 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 28 Oct 2014 13:45:17 GMT Received: from userz7022.oracle.com (userz7022.oracle.com [156.151.31.86]) by ucsinet22.oracle.com (8.14.5+Sun/8.14.5) with ESMTP id s9SCv5Tc024486 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 28 Oct 2014 12:57:06 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by userz7022.oracle.com (8.14.5+Sun/8.14.4) with ESMTP id s9SCv5om024457 for ; Tue, 28 Oct 2014 12:57:05 GMT Received: from localhost.localdomain (/10.175.175.133) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 28 Oct 2014 06:45:15 -0700 From: "Jose E. Marchesi" To: gdb-patches@sourceware.org Subject: [PATCH V3 3/9] New commands `enable probe' and `disable probe'. Date: Tue, 28 Oct 2014 14:50:12 +0100 Message-Id: <1414504218-31204-4-git-send-email-jose.marchesi@oracle.com> In-Reply-To: <1414504218-31204-1-git-send-email-jose.marchesi@oracle.com> References: <1414504218-31204-1-git-send-email-jose.marchesi@oracle.com> X-IsSubscribed: yes 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 * 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 * 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. */