^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * builtin-probe.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Builtin probe command: Set up probe events by C expression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Written by Masami Hiramatsu <mhiramat@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <sys/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "builtin.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "namespaces.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "util/build-id.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "util/strlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "util/strfilter.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "util/symbol_conf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "util/debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <subcmd/parse-options.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "util/probe-finder.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "util/probe-event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "util/probe-file.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define DEFAULT_FUNC_FILTER "!_*"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define DEFAULT_LIST_FILTER "*"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Session management structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int command; /* Command short_name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) bool list_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) bool uprobes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) bool quiet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) bool target_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int nevents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct perf_probe_event events[MAX_PROBES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct line_range line_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) char *target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct strfilter *filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct nsinfo *nsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) } params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* Parse an event definition. Note that any error must die. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int parse_probe_event(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct perf_probe_event *pev = ¶ms.events[params.nevents];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) pr_debug("probe-definition(%d): %s\n", params.nevents, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (++params.nevents == MAX_PROBES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) pr_err("Too many probes (> %d) were specified.", MAX_PROBES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) pev->uprobes = params.uprobes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (params.target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) pev->target = strdup(params.target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (!pev->target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) params.target_used = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) pev->nsi = nsinfo__get(params.nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* Parse a perf-probe command into event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ret = parse_perf_probe_command(str, pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pr_debug("%d arguments\n", pev->nargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int params_add_filter(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) const char *err = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) pr_debug2("Add filter: %s\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (!params.filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) params.filter = strfilter__new(str, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!params.filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ret = err ? -EINVAL : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ret = strfilter__or(params.filter, str, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (ret == -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) pr_err("Filter parse error at %td.\n", err - str + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) pr_err("Source: \"%s\"\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) pr_err(" %*c\n", (int)(err - str + 1), '^');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static int set_target(const char *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) const char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * The first argument after options can be an absolute path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * to an executable / library or kernel module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * TODO: Support relative path, and $PATH, $LD_LIBRARY_PATH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * short module name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (!params.target && ptr && *ptr == '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) params.target = strdup(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (!params.target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) params.target_used = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) buf = ptr + (strlen(ptr) - 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (strcmp(buf, ".ko"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) params.uprobes = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int parse_probe_event_argv(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int i, len, ret, found_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) found_target = set_target(argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (found_target < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return found_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (found_target && argc == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Bind up rest arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) for (i = 0; i < argc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (i == 0 && found_target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) len += strlen(argv[i]) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) buf = zalloc(len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) for (i = 0; i < argc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (i == 0 && found_target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) len += sprintf(&buf[len], "%s ", argv[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ret = parse_probe_event(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int opt_set_target(const struct option *opt, const char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) char *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (!strcmp(opt->long_name, "exec"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) params.uprobes = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) else if (!strcmp(opt->long_name, "module"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) params.uprobes = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* Expand given path to absolute path, except for modulename */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (params.uprobes || strchr(str, '/')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) tmp = nsinfo__realpath(str, params.nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (!tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) pr_warning("Failed to get the absolute path of %s: %m\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) tmp = strdup(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) free(params.target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) params.target = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) params.target_used = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static int opt_set_target_ns(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) pid_t ns_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct nsinfo *nsip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ns_pid = (pid_t)strtol(str, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (errno != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) pr_warning("Failed to parse %s as a pid: %s\n", str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) nsip = nsinfo__new(ns_pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (nsip && nsip->need_setns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) params.nsi = nsinfo__get(nsip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) nsinfo__put(nsip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* Command option callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int opt_show_lines(const struct option *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (params.command == 'L') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) pr_warning("Warning: more than one --line options are"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) " detected. Only the first one is valid.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) params.command = opt->short_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ret = parse_line_range_desc(str, ¶ms.line_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static int opt_show_vars(const struct option *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct perf_probe_event *pev = ¶ms.events[params.nevents];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = parse_probe_event(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (!ret && pev->nargs != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) pr_err(" Error: '--vars' doesn't accept arguments.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) params.command = opt->short_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) # define opt_show_lines NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) # define opt_show_vars NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int opt_add_probe_event(const struct option *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) params.command = opt->short_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return parse_probe_event(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int opt_set_filter_with_command(const struct option *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) const char *str, int unset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (!unset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) params.command = opt->short_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return params_add_filter(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int opt_set_filter(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return params_add_filter(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int init_params(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return line_range__init(¶ms.line_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static void cleanup_params(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) for (i = 0; i < params.nevents; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) clear_perf_probe_event(params.events + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) line_range__clear(¶ms.line_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) free(params.target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) strfilter__delete(params.filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) nsinfo__put(params.nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) memset(¶ms, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static void pr_err_with_code(const char *msg, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) char sbuf[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) pr_err("%s", msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) pr_debug(" Reason: %s (Code: %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) str_error_r(-err, sbuf, sizeof(sbuf)), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) pr_err("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static int perf_add_probe_events(struct perf_probe_event *pevs, int npevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int i, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) const char *event = NULL, *group = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ret = init_probe_symbol_maps(pevs->uprobes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ret = convert_perf_probe_events(pevs, npevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) goto out_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (params.command == 'D') { /* it shows definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ret = show_probe_trace_events(pevs, npevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) goto out_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ret = apply_perf_probe_events(pevs, npevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) goto out_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) for (i = k = 0; i < npevs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) k += pevs[i].ntevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) pr_info("Added new event%s\n", (k > 1) ? "s:" : ":");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) for (i = 0; i < npevs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct perf_probe_event *pev = &pevs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) for (k = 0; k < pev->ntevs; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct probe_trace_event *tev = &pev->tevs[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Skipped events have no event name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (!tev->event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* We use tev's name for showing new events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) show_perf_probe_event(tev->group, tev->event, pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) tev->point.module, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* Save the last valid name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) event = tev->event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) group = tev->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /* Note that it is possible to skip all events because of blacklist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* Show how to use the event. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) pr_info("\nYou can now use it in all perf tools, such as:\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", group, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) out_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) cleanup_perf_probe_events(pevs, npevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) exit_probe_symbol_maps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static int del_perf_probe_caches(struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct probe_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct strlist *bidlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) struct str_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) bidlist = build_id_cache__list_all(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (!bidlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) pr_debug("Failed to get buildids: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return ret ?: -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) strlist__for_each_entry(nd, bidlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) cache = probe_cache__new(nd->s, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (!cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (probe_cache__filter_purge(cache, filter) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) probe_cache__commit(cache) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) pr_warning("Failed to remove entries for %s\n", nd->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) probe_cache__delete(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static int perf_del_probe_events(struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int ret, ret2, ufd = -1, kfd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) char *str = strfilter__string(filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct strlist *klist = NULL, *ulist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct str_node *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) pr_debug("Delete filter: \'%s\'\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (probe_conf.cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return del_perf_probe_caches(filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /* Get current event names */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) klist = strlist__new(NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ulist = strlist__new(NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (!klist || !ulist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ret = probe_file__get_events(kfd, filter, klist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) strlist__for_each_entry(ent, klist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) pr_info("Removed event: %s\n", ent->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ret = probe_file__del_strlist(kfd, klist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) } else if (ret == -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ret2 = probe_file__get_events(ufd, filter, ulist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (ret2 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) strlist__for_each_entry(ent, ulist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) pr_info("Removed event: %s\n", ent->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ret2 = probe_file__del_strlist(ufd, ulist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (ret2 < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) } else if (ret2 == -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (ret == -ENOENT && ret2 == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) pr_warning("\"%s\" does not hit any event.\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (kfd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) close(kfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (ufd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) close(ufd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) strlist__delete(klist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) strlist__delete(ulist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) free(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) #define PROBEDEF_STR \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) "[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT [[NAME=]ARG ...]"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) #define PROBEDEF_STR "[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) __cmd_probe(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) const char * const probe_usage[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) "perf probe [<options>] --del '[GROUP:]EVENT' ...",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) "perf probe --list [GROUP:]EVENT ...",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) "perf probe [<options>] --line 'LINEDESC'",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) "perf probe [<options>] --vars 'PROBEPOINT'",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) "perf probe [<options>] --funcs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct option options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) OPT_INCR('v', "verbose", &verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) "be more verbose (show parsed arguments, etc)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) OPT_BOOLEAN('q', "quiet", ¶ms.quiet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) "be quiet (do not show any messages)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) OPT_CALLBACK_DEFAULT('l', "list", NULL, "[GROUP:]EVENT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) "list up probe events",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) opt_set_filter_with_command, DEFAULT_LIST_FILTER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) opt_set_filter_with_command),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) OPT_CALLBACK('a', "add", NULL, PROBEDEF_STR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) "probe point definition, where\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) "\t\tGROUP:\tGroup name (optional)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) "\t\tEVENT:\tEvent name\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) "\t\tFUNC:\tFunction name\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) "\t\tOFF:\tOffset from function entry (in byte)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) "\t\t%return:\tPut the probe at function return\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) "\t\tSRC:\tSource code path\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) "\t\tRL:\tRelative line number from function entry.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) "\t\tAL:\tAbsolute line number in file.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) "\t\tPT:\tLazy expression of line code.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) "\t\tARG:\tProbe argument (local variable name or\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) "\t\t\tkprobe-tracer argument format.)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) "\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) opt_add_probe_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) OPT_CALLBACK('D', "definition", NULL, PROBEDEF_STR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) "Show trace event definition of given traceevent for k/uprobe_events.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) opt_add_probe_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) OPT_BOOLEAN('f', "force", &probe_conf.force_add, "forcibly add events"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) " with existing name"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) OPT_CALLBACK('L', "line", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) "Show source code lines.", opt_show_lines),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) OPT_CALLBACK('V', "vars", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) "FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) "Show accessible variables on PROBEDEF", opt_show_vars),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) OPT_BOOLEAN('\0', "externs", &probe_conf.show_ext_vars,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) "Show external variables too (with --vars only)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) OPT_BOOLEAN('\0', "range", &probe_conf.show_location_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) "Show variables location range in scope (with --vars only)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) "file", "vmlinux pathname"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) OPT_STRING('s', "source", &symbol_conf.source_prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) "directory", "path to kernel source"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) "Don't search inlined functions"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) OPT__DRY_RUN(&probe_event_dry_run),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) OPT_INTEGER('\0', "max-probes", &probe_conf.max_probes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) "Set how many probe points can be found for a probe."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) OPT_CALLBACK_DEFAULT('F', "funcs", NULL, "[FILTER]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) "Show potential probe-able functions.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) opt_set_filter_with_command, DEFAULT_FUNC_FILTER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) OPT_CALLBACK('\0', "filter", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) "[!]FILTER", "Set a filter (with --vars/funcs only)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) "\t\t\t(default: \"" DEFAULT_VAR_FILTER "\" for --vars,\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) "\t\t\t \"" DEFAULT_FUNC_FILTER "\" for --funcs)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) opt_set_filter),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) OPT_CALLBACK('x', "exec", NULL, "executable|path",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) "target executable name or path", opt_set_target),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) OPT_CALLBACK('m', "module", NULL, "modname|path",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) "target module name (for online) or path (for offline)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) opt_set_target),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) "Enable symbol demangling"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) "Enable kernel symbol demangling"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) OPT_BOOLEAN(0, "cache", &probe_conf.cache, "Manipulate probe cache"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) "Look for files with symbols relative to this directory"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) OPT_CALLBACK(0, "target-ns", NULL, "pid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) "target pid for namespace contexts", opt_set_target_ns),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) set_option_flag(options, 'a', "add", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) set_option_flag(options, 'd', "del", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) set_option_flag(options, 'D', "definition", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) set_option_flag(options, 'l', "list", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) set_option_flag(options, 'L', "line", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) set_option_flag(options, 'V', "vars", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) # define set_nobuild(s, l, c) set_option_nobuild(options, s, l, "NO_DWARF=1", c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) set_nobuild('L', "line", false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) set_nobuild('V', "vars", false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) set_nobuild('\0', "externs", false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) set_nobuild('\0', "range", false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) set_nobuild('k', "vmlinux", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) set_nobuild('s', "source", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) set_nobuild('\0', "no-inlines", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) # undef set_nobuild
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) set_option_flag(options, 'F', "funcs", PARSE_OPT_EXCLUSIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) argc = parse_options(argc, argv, options, probe_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) PARSE_OPT_STOP_AT_NON_OPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (argc > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (strcmp(argv[0], "-") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) usage_with_options_msg(probe_usage, options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) "'-' is not supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (params.command && params.command != 'a') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) usage_with_options_msg(probe_usage, options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) "another command except --add is set.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) ret = parse_probe_event_argv(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) pr_err_with_code(" Error: Command Parse Error.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) params.command = 'a';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (params.quiet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (verbose != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) pr_err(" Error: -v and -q are exclusive.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) verbose = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (probe_conf.max_probes == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) probe_conf.max_probes = MAX_PROBES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * Only consider the user's kernel image path if given.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * Except for --list, --del and --add, other command doesn't depend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * nor change running kernel. So if user gives offline vmlinux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * ignore its buildid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (!strchr("lda", params.command) && symbol_conf.vmlinux_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) symbol_conf.ignore_vmlinux_buildid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) switch (params.command) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (params.uprobes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) pr_err(" Error: Don't use --list with --exec.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) parse_options_usage(probe_usage, options, "l", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) parse_options_usage(NULL, options, "x", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) ret = show_perf_probe_events(params.filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) pr_err_with_code(" Error: Failed to show event list.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case 'F':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) ret = show_available_funcs(params.target, params.nsi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) params.filter, params.uprobes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) pr_err_with_code(" Error: Failed to show functions.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) case 'L':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ret = show_line_range(¶ms.line_range, params.target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) params.nsi, params.uprobes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) pr_err_with_code(" Error: Failed to show lines.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) case 'V':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (!params.filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) params.filter = strfilter__new(DEFAULT_VAR_FILTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) ret = show_available_vars(params.events, params.nevents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) params.filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) pr_err_with_code(" Error: Failed to show vars.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ret = perf_del_probe_events(params.filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) pr_err_with_code(" Error: Failed to delete events.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) case 'D':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) case 'a':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /* Ensure the last given target is used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (params.target && !params.target_used) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) pr_err(" Error: -x/-m must follow the probe definitions.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) parse_options_usage(probe_usage, options, "m", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) parse_options_usage(NULL, options, "x", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) ret = perf_add_probe_events(params.events, params.nevents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * When perf_add_probe_events() fails it calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * cleanup_perf_probe_events(pevs, npevs), i.e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * cleanup_perf_probe_events(params.events, params.nevents), which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * will call clear_perf_probe_event(), so set nevents to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * to avoid cleanup_params() to call clear_perf_probe_event() again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * on the same pevs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) params.nevents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) pr_err_with_code(" Error: Failed to add events.", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) usage_with_options(probe_usage, options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int cmd_probe(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ret = init_params();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ret = __cmd_probe(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) cleanup_params();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return ret < 0 ? ret : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }