diff options
author | Tom de Vries <tdevries@suse.de> | 2022-12-31 10:23:06 +0100 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2022-12-31 10:23:06 +0100 |
commit | 08c59458a106038c6d678621e7290948127671e2 (patch) | |
tree | 64912d2f4d83b4eda9fcfe45b757a8063f5ad57b | |
parent | a667697f36ef4f910e09c4a02f34a44fa3e86157 (diff) | |
download | gdb-08c59458a106038c6d678621e7290948127671e2.zip gdb-08c59458a106038c6d678621e7290948127671e2.tar.gz gdb-08c59458a106038c6d678621e7290948127671e2.tar.bz2 |
[gdb/cli] Add maintenance ignore-probes
There's a command "disable probes", but SystemTap probes, for instance
libc:longjmp cannot be disabled:
...
$ gdb -q -batch a.out -ex start -ex "disable probes libc ^longjmp$"
...
Probe libc:longjmp cannot be disabled.
Probe libc:longjmp cannot be disabled.
Probe libc:longjmp cannot be disabled.
...
Add a command "maintenance ignore-probes" that ignores probes during
get_probes, such that we can easily pretend to use a libc without the
libc:longjmp probe:
...
(gdb) maint ignore-probes -verbose libc ^longjmp$
ignore-probes filter has been set to:
PROVIDER: 'libc'
PROBE_NAME: '^longjmp$'
OBJNAME: ''
(gdb) start ^M
...
Ignoring SystemTap probe libc longjmp in /lib64/libc.so.6.^M
Ignoring SystemTap probe libc longjmp in /lib64/libc.so.6.^M
Ignoring SystemTap probe libc longjmp in /lib64/libc.so.6.^M
...
The "Ignoring ..." messages can be suppressed by not using -verbose.
Note that as with "disable probes", running simply "maint ignore-probes"
ignores all probes.
The ignore-probes filter can be reset by using:
...
(gdb) maint ignore-probes -reset
ignore-probes filter has been reset
...
For now, the command is only supported for SystemTap probes.
PR cli/27159
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27159
-rw-r--r-- | gdb/doc/gdb.texinfo | 22 | ||||
-rw-r--r-- | gdb/probe.c | 115 | ||||
-rw-r--r-- | gdb/probe.h | 5 | ||||
-rw-r--r-- | gdb/stap-probe.c | 3 |
4 files changed, 145 insertions, 0 deletions
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 21a00ed..704415b 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -6114,6 +6114,7 @@ disabled, but @code{SystemTap} probes cannot be disabled. You can enable (or disable) one or more probes using the following commands, with optional arguments: +@anchor{enable probes} @table @code @kindex enable probes @item enable probes @r{[}@var{provider} @r{[}@var{name} @r{[}@var{objfile}@r{]}@r{]}@r{]} @@ -40897,6 +40898,27 @@ Like the @code{with} command, but works with @code{maintenance set} variables. This is used by the testsuite to exercise the @code{with} command's infrastructure. +@kindex maint ignore-probes +@item maint ignore-probes [@var{-v}|@var{-verbose}] [@var{provider} [@var{name} [@var{objfile}]]] +@itemx maint ignore-probes @var{-reset} +Set or reset the ignore-probes filter. The @var{provider}, @var{name} +and @var{objfile} arguments are as in @code{enable probes} and +@code{disable probes} (@pxref{enable probes}). Only supported for +SystemTap probes. + +Here's an example of using @code{maint ignore-probes}: +@smallexample +(gdb) maint ignore-probes -verbose libc ^longjmp$ +ignore-probes filter has been set to: +PROVIDER: 'libc' +PROBE_NAME: '^longjmp$' +OBJNAME: '' +(gdb) start +<... more output ...> +Ignoring SystemTap probe libc longjmp in /lib64/libc.so.6.^M +Ignoring SystemTap probe libc longjmp in /lib64/libc.so.6.^M +Ignoring SystemTap probe libc longjmp in /lib64/libc.so.6.^M +@end smallexample @end table The following command is useful for non-interactive invocations of diff --git a/gdb/probe.c b/gdb/probe.c index 4193f9f..10e51df 100644 --- a/gdb/probe.c +++ b/gdb/probe.c @@ -680,6 +680,109 @@ disable_probes_command (const char *arg, int from_tty) } } +static bool ignore_probes_p = false; +static bool ignore_probes_idx = 0; +static bool ignore_probes_verbose_p; +static gdb::optional<compiled_regex> ignore_probes_prov_pat[2]; +static gdb::optional<compiled_regex> ignore_probes_name_pat[2]; +static gdb::optional<compiled_regex> ignore_probes_obj_pat[2]; + +/* See comments in probe.h. */ + +bool +ignore_probe_p (const char *provider, const char *name, + const char *objfile_name, const char *type) +{ + if (!ignore_probes_p) + return false; + + gdb::optional<compiled_regex> &re_prov + = ignore_probes_prov_pat[ignore_probes_idx]; + gdb::optional<compiled_regex> &re_name + = ignore_probes_name_pat[ignore_probes_idx]; + gdb::optional<compiled_regex> &re_obj + = ignore_probes_obj_pat[ignore_probes_idx]; + + bool res + = ((!re_prov + || re_prov->exec (provider, 0, NULL, 0) == 0) + && (!re_name + || re_name->exec (name, 0, NULL, 0) == 0) + && (!re_obj + || re_obj->exec (objfile_name, 0, NULL, 0) == 0)); + + if (res && ignore_probes_verbose_p) + gdb_printf (gdb_stdlog, _("Ignoring %s probe %s %s in %s.\n"), + type, provider, name, objfile_name); + + return res; +} + +/* Implementation of the `maintenance ignore-probes' command. */ + +static void +ignore_probes_command (const char *arg, int from_tty) +{ + std::string ignore_provider, ignore_probe_name, ignore_objname; + + bool verbose_p = false; + if (arg != nullptr) + { + const char *idx = arg; + std::string s = extract_arg (&idx); + + if (strcmp (s.c_str (), "-reset") == 0) + { + if (*idx != '\0') + error (_("-reset: no arguments allowed")); + + ignore_probes_p = false; + gdb_printf (gdb_stdout, _("ignore-probes filter has been reset\n")); + return; + } + + if (strcmp (s.c_str (), "-verbose") == 0 + || strcmp (s.c_str (), "-v") == 0) + { + verbose_p = true; + arg = idx; + } + } + + parse_probe_linespec (arg, &ignore_provider, &ignore_probe_name, + &ignore_objname); + + /* Parse the regular expressions, making sure that the old regular + expressions are still valid if an exception is throw. */ + int new_ignore_probes_idx = 1 - ignore_probes_idx; + gdb::optional<compiled_regex> &re_prov + = ignore_probes_prov_pat[new_ignore_probes_idx]; + gdb::optional<compiled_regex> &re_name + = ignore_probes_name_pat[new_ignore_probes_idx]; + gdb::optional<compiled_regex> &re_obj + = ignore_probes_obj_pat[new_ignore_probes_idx]; + re_prov.reset (); + re_name.reset (); + re_obj.reset (); + if (!ignore_provider.empty ()) + re_prov.emplace (ignore_provider.c_str (), REG_NOSUB, + _("Invalid provider regexp")); + if (!ignore_probe_name.empty ()) + re_name.emplace (ignore_probe_name.c_str (), REG_NOSUB, + _("Invalid probe regexp")); + if (!ignore_objname.empty ()) + re_obj.emplace (ignore_objname.c_str (), REG_NOSUB, + _("Invalid object file regexp")); + ignore_probes_idx = new_ignore_probes_idx; + + ignore_probes_p = true; + ignore_probes_verbose_p = verbose_p; + gdb_printf (gdb_stdout, _("ignore-probes filter has been set to:\n")); + gdb_printf (gdb_stdout, _("PROVIDER: '%s'\n"), ignore_provider.c_str ()); + gdb_printf (gdb_stdout, _("PROBE_NAME: '%s'\n"), ignore_probe_name.c_str ()); + gdb_printf (gdb_stdout, _("OBJNAME: '%s'\n"), ignore_objname.c_str ()); +} + /* See comments in probe.h. */ struct value * @@ -931,4 +1034,16 @@ If you do not specify any argument then the command will disable\n\ all defined probes."), &disablelist); + add_cmd ("ignore-probes", class_maintenance, ignore_probes_command, _("\ +Ignore probes.\n\ +Usage: maintenance ignore-probes [-v|-verbose] [PROVIDER [NAME [OBJECT]]]\n\ + maintenance ignore-probes -reset\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 ignore\n\ +all defined probes. To reset the ignore-probes filter, use the -reset form.\n\ +Only supported for SystemTap probes."), + &maintenancelist); } diff --git a/gdb/probe.h b/gdb/probe.h index 598f43a..a600176 100644 --- a/gdb/probe.h +++ b/gdb/probe.h @@ -304,4 +304,9 @@ extern struct cmd_list_element **info_probes_cmdlist_get (void); extern struct value *probe_safe_evaluate_at_pc (frame_info_ptr frame, unsigned n); +/* Return true if the PROVIDER/NAME probe from OBJFILE_NAME needs to be + ignored. */ + +bool ignore_probe_p (const char *provider, const char *name, + const char *objfile_name, const char *TYPE); #endif /* !defined (PROBE_H) */ diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c index 6f91d87..f119e2c 100644 --- a/gdb/stap-probe.c +++ b/gdb/stap-probe.c @@ -1619,6 +1619,9 @@ handle_stap_probe (struct objfile *objfile, struct sdt_note *el, return; } + if (ignore_probe_p (provider, name, objfile_name (objfile), "SystemTap")) + return; + stap_probe *ret = new stap_probe (std::string (name), std::string (provider), address, gdbarch, sem_addr, probe_args); |