From 71b320a91722133d4b39ef4d7e53fcaedf75ecb7 Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Mon, 5 Dec 2022 14:45:42 +0100 Subject: [PATCH] [gdb/cli] Add maintenance ignore-probes There's a command "disable probes", but SystemTap probes cannot be disabled. Add a command "maintenance ignore-probes" that ignores probes during get_probes, such that we can easily pretend to use a glibc without say, the 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 Temporary breakpoint 1 at 0x4005bb: file longjmp.c, line 46. Starting program: outputs/gdb.base/longjmp/longjmp ^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 ^M Breakpoint 1, main () at longjmp.c:46^M 46 volatile int i = 0;^M (gdb) ... Note that as with "disable probes", running "maint ignore-probes" without arguments 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 --- gdb/probe.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ gdb/probe.h | 5 +++ gdb/stap-probe.c | 3 ++ 3 files changed, 93 insertions(+) diff --git a/gdb/probe.c b/gdb/probe.c index 4193f9f936b..1863cd96b02 100644 --- a/gdb/probe.c +++ b/gdb/probe.c @@ -680,6 +680,79 @@ disable_probes_command (const char *arg, int from_tty) } } +static bool ignore_probes_p = false; +static bool ignore_probes_verbose_p = false; +static gdb::optional ignore_obj_pat; +static gdb::optional ignore_prov_pat; +static gdb::optional ignore_probe_pat; + +/* See comments in probe.h. */ + +bool ignore_probe (const char *provider, const char *name, + const char *objfile_name, const char *type) +{ + bool res + = (ignore_probes_p + && (!ignore_obj_pat + || ignore_obj_pat->exec (objfile_name, 0, NULL, 0) == 0) + && (!ignore_prov_pat + || ignore_prov_pat->exec (provider, 0, NULL, 0) == 0) + && (!ignore_probe_pat + || ignore_probe_pat->exec (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; + + if (arg != nullptr && strcmp (arg, "-reset") == 0) + { + ignore_probes_p = false; + gdb_printf (gdb_stdout, _("ignore-probes filter has been reset\n")); + return; + } + + { + const char *str = "-verbose"; + size_t len = strlen (str); + if (arg != nullptr + && strncmp (arg, str, len) == 0 + && (arg[len] == '\0' || arg[len] == ' ')) + { + ignore_probes_verbose_p = true; + if (arg[len] == '\0') + arg = nullptr; + else + arg += (len + 1); + } + } + + parse_probe_linespec (arg, &ignore_provider, &ignore_probe_name, + &ignore_objname); + + ignore_prov_pat.emplace (ignore_provider.c_str (), REG_NOSUB, + _("Invalid provider regexp")); + ignore_probe_pat.emplace (ignore_probe_name.c_str (), REG_NOSUB, + _("Invalid probe regexp")); + ignore_obj_pat.emplace (ignore_objname.c_str (), REG_NOSUB, + _("Invalid object file regexp")); + + 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 ()); + ignore_probes_p = true; +} + /* See comments in probe.h. */ struct value * @@ -931,4 +1004,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 [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 598f43a238e..70fb71d6ae4 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 (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 6f91d87846a..a8a60d85e59 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 (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); base-commit: ea6929aaac370daddf0999faa553231c8b806b20 -- 2.35.3