Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * builtin-probe.c
0004  *
0005  * Builtin probe command: Set up probe events by C expression
0006  *
0007  * Written by Masami Hiramatsu <mhiramat@redhat.com>
0008  */
0009 #include <sys/utsname.h>
0010 #include <sys/types.h>
0011 #include <sys/stat.h>
0012 #include <fcntl.h>
0013 #include <errno.h>
0014 #include <stdio.h>
0015 #include <unistd.h>
0016 #include <stdlib.h>
0017 #include <string.h>
0018 
0019 #include "builtin.h"
0020 #include "namespaces.h"
0021 #include "util/build-id.h"
0022 #include "util/strlist.h"
0023 #include "util/strfilter.h"
0024 #include "util/symbol.h"
0025 #include "util/symbol_conf.h"
0026 #include "util/debug.h"
0027 #include <subcmd/parse-options.h>
0028 #include "util/probe-finder.h"
0029 #include "util/probe-event.h"
0030 #include "util/probe-file.h"
0031 #include <linux/string.h>
0032 #include <linux/zalloc.h>
0033 
0034 #define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*"
0035 #define DEFAULT_FUNC_FILTER "!_* & !*@plt"
0036 #define DEFAULT_LIST_FILTER "*"
0037 
0038 /* Session management structure */
0039 static struct {
0040     int command;    /* Command short_name */
0041     bool list_events;
0042     bool uprobes;
0043     bool quiet;
0044     bool target_used;
0045     int nevents;
0046     struct perf_probe_event events[MAX_PROBES];
0047     struct line_range line_range;
0048     char *target;
0049     struct strfilter *filter;
0050     struct nsinfo *nsi;
0051 } params;
0052 
0053 /* Parse an event definition. Note that any error must die. */
0054 static int parse_probe_event(const char *str)
0055 {
0056     struct perf_probe_event *pev = &params.events[params.nevents];
0057     int ret;
0058 
0059     pr_debug("probe-definition(%d): %s\n", params.nevents, str);
0060     if (++params.nevents == MAX_PROBES) {
0061         pr_err("Too many probes (> %d) were specified.", MAX_PROBES);
0062         return -1;
0063     }
0064 
0065     pev->uprobes = params.uprobes;
0066     if (params.target) {
0067         pev->target = strdup(params.target);
0068         if (!pev->target)
0069             return -ENOMEM;
0070         params.target_used = true;
0071     }
0072 
0073     pev->nsi = nsinfo__get(params.nsi);
0074 
0075     /* Parse a perf-probe command into event */
0076     ret = parse_perf_probe_command(str, pev);
0077     pr_debug("%d arguments\n", pev->nargs);
0078 
0079     return ret;
0080 }
0081 
0082 static int params_add_filter(const char *str)
0083 {
0084     const char *err = NULL;
0085     int ret = 0;
0086 
0087     pr_debug2("Add filter: %s\n", str);
0088     if (!params.filter) {
0089         params.filter = strfilter__new(str, &err);
0090         if (!params.filter)
0091             ret = err ? -EINVAL : -ENOMEM;
0092     } else
0093         ret = strfilter__or(params.filter, str, &err);
0094 
0095     if (ret == -EINVAL) {
0096         pr_err("Filter parse error at %td.\n", err - str + 1);
0097         pr_err("Source: \"%s\"\n", str);
0098         pr_err("         %*c\n", (int)(err - str + 1), '^');
0099     }
0100 
0101     return ret;
0102 }
0103 
0104 static int set_target(const char *ptr)
0105 {
0106     int found = 0;
0107     const char *buf;
0108 
0109     /*
0110      * The first argument after options can be an absolute path
0111      * to an executable / library or kernel module.
0112      *
0113      * TODO: Support relative path, and $PATH, $LD_LIBRARY_PATH,
0114      * short module name.
0115      */
0116     if (!params.target && ptr && *ptr == '/') {
0117         params.target = strdup(ptr);
0118         if (!params.target)
0119             return -ENOMEM;
0120         params.target_used = false;
0121 
0122         found = 1;
0123         buf = ptr + (strlen(ptr) - 3);
0124 
0125         if (strcmp(buf, ".ko"))
0126             params.uprobes = true;
0127 
0128     }
0129 
0130     return found;
0131 }
0132 
0133 static int parse_probe_event_argv(int argc, const char **argv)
0134 {
0135     int i, len, ret, found_target;
0136     char *buf;
0137 
0138     found_target = set_target(argv[0]);
0139     if (found_target < 0)
0140         return found_target;
0141 
0142     if (found_target && argc == 1)
0143         return 0;
0144 
0145     /* Bind up rest arguments */
0146     len = 0;
0147     for (i = 0; i < argc; i++) {
0148         if (i == 0 && found_target)
0149             continue;
0150 
0151         len += strlen(argv[i]) + 1;
0152     }
0153     buf = zalloc(len + 1);
0154     if (buf == NULL)
0155         return -ENOMEM;
0156     len = 0;
0157     for (i = 0; i < argc; i++) {
0158         if (i == 0 && found_target)
0159             continue;
0160 
0161         len += sprintf(&buf[len], "%s ", argv[i]);
0162     }
0163     ret = parse_probe_event(buf);
0164     free(buf);
0165     return ret;
0166 }
0167 
0168 static int opt_set_target(const struct option *opt, const char *str,
0169             int unset __maybe_unused)
0170 {
0171     int ret = -ENOENT;
0172     char *tmp;
0173 
0174     if  (str) {
0175         if (!strcmp(opt->long_name, "exec"))
0176             params.uprobes = true;
0177         else if (!strcmp(opt->long_name, "module"))
0178             params.uprobes = false;
0179         else
0180             return ret;
0181 
0182         /* Expand given path to absolute path, except for modulename */
0183         if (params.uprobes || strchr(str, '/')) {
0184             tmp = nsinfo__realpath(str, params.nsi);
0185             if (!tmp) {
0186                 pr_warning("Failed to get the absolute path of %s: %m\n", str);
0187                 return ret;
0188             }
0189         } else {
0190             tmp = strdup(str);
0191             if (!tmp)
0192                 return -ENOMEM;
0193         }
0194         free(params.target);
0195         params.target = tmp;
0196         params.target_used = false;
0197         ret = 0;
0198     }
0199 
0200     return ret;
0201 }
0202 
0203 static int opt_set_target_ns(const struct option *opt __maybe_unused,
0204                  const char *str, int unset __maybe_unused)
0205 {
0206     int ret = -ENOENT;
0207     pid_t ns_pid;
0208     struct nsinfo *nsip;
0209 
0210     if (str) {
0211         errno = 0;
0212         ns_pid = (pid_t)strtol(str, NULL, 10);
0213         if (errno != 0) {
0214             ret = -errno;
0215             pr_warning("Failed to parse %s as a pid: %s\n", str,
0216                    strerror(errno));
0217             return ret;
0218         }
0219         nsip = nsinfo__new(ns_pid);
0220         if (nsip && nsinfo__need_setns(nsip))
0221             params.nsi = nsinfo__get(nsip);
0222         nsinfo__put(nsip);
0223 
0224         ret = 0;
0225     }
0226 
0227     return ret;
0228 }
0229 
0230 
0231 /* Command option callbacks */
0232 
0233 #ifdef HAVE_DWARF_SUPPORT
0234 static int opt_show_lines(const struct option *opt,
0235               const char *str, int unset __maybe_unused)
0236 {
0237     int ret = 0;
0238 
0239     if (!str)
0240         return 0;
0241 
0242     if (params.command == 'L') {
0243         pr_warning("Warning: more than one --line options are"
0244                " detected. Only the first one is valid.\n");
0245         return 0;
0246     }
0247 
0248     params.command = opt->short_name;
0249     ret = parse_line_range_desc(str, &params.line_range);
0250 
0251     return ret;
0252 }
0253 
0254 static int opt_show_vars(const struct option *opt,
0255              const char *str, int unset __maybe_unused)
0256 {
0257     struct perf_probe_event *pev = &params.events[params.nevents];
0258     int ret;
0259 
0260     if (!str)
0261         return 0;
0262 
0263     ret = parse_probe_event(str);
0264     if (!ret && pev->nargs != 0) {
0265         pr_err("  Error: '--vars' doesn't accept arguments.\n");
0266         return -EINVAL;
0267     }
0268     params.command = opt->short_name;
0269 
0270     return ret;
0271 }
0272 #else
0273 # define opt_show_lines NULL
0274 # define opt_show_vars NULL
0275 #endif
0276 static int opt_add_probe_event(const struct option *opt,
0277                   const char *str, int unset __maybe_unused)
0278 {
0279     if (str) {
0280         params.command = opt->short_name;
0281         return parse_probe_event(str);
0282     }
0283 
0284     return 0;
0285 }
0286 
0287 static int opt_set_filter_with_command(const struct option *opt,
0288                        const char *str, int unset)
0289 {
0290     if (!unset)
0291         params.command = opt->short_name;
0292 
0293     if (str)
0294         return params_add_filter(str);
0295 
0296     return 0;
0297 }
0298 
0299 static int opt_set_filter(const struct option *opt __maybe_unused,
0300               const char *str, int unset __maybe_unused)
0301 {
0302     if (str)
0303         return params_add_filter(str);
0304 
0305     return 0;
0306 }
0307 
0308 static int init_params(void)
0309 {
0310     return line_range__init(&params.line_range);
0311 }
0312 
0313 static void cleanup_params(void)
0314 {
0315     int i;
0316 
0317     for (i = 0; i < params.nevents; i++)
0318         clear_perf_probe_event(params.events + i);
0319     line_range__clear(&params.line_range);
0320     free(params.target);
0321     strfilter__delete(params.filter);
0322     nsinfo__put(params.nsi);
0323     memset(&params, 0, sizeof(params));
0324 }
0325 
0326 static void pr_err_with_code(const char *msg, int err)
0327 {
0328     char sbuf[STRERR_BUFSIZE];
0329 
0330     pr_err("%s", msg);
0331     pr_debug(" Reason: %s (Code: %d)",
0332          str_error_r(-err, sbuf, sizeof(sbuf)), err);
0333     pr_err("\n");
0334 }
0335 
0336 static int perf_add_probe_events(struct perf_probe_event *pevs, int npevs)
0337 {
0338     int ret;
0339     int i, k;
0340     const char *event = NULL, *group = NULL;
0341 
0342     ret = init_probe_symbol_maps(pevs->uprobes);
0343     if (ret < 0)
0344         return ret;
0345 
0346     ret = convert_perf_probe_events(pevs, npevs);
0347     if (ret < 0)
0348         goto out_cleanup;
0349 
0350     if (params.command == 'D') {    /* it shows definition */
0351         if (probe_conf.bootconfig)
0352             ret = show_bootconfig_events(pevs, npevs);
0353         else
0354             ret = show_probe_trace_events(pevs, npevs);
0355         goto out_cleanup;
0356     }
0357 
0358     ret = apply_perf_probe_events(pevs, npevs);
0359     if (ret < 0)
0360         goto out_cleanup;
0361 
0362     for (i = k = 0; i < npevs; i++)
0363         k += pevs[i].ntevs;
0364 
0365     pr_info("Added new event%s\n", (k > 1) ? "s:" : ":");
0366     for (i = 0; i < npevs; i++) {
0367         struct perf_probe_event *pev = &pevs[i];
0368 
0369         for (k = 0; k < pev->ntevs; k++) {
0370             struct probe_trace_event *tev = &pev->tevs[k];
0371             /* Skipped events have no event name */
0372             if (!tev->event)
0373                 continue;
0374 
0375             /* We use tev's name for showing new events */
0376             show_perf_probe_event(tev->group, tev->event, pev,
0377                           tev->point.module, false);
0378 
0379             /* Save the last valid name */
0380             event = tev->event;
0381             group = tev->group;
0382         }
0383     }
0384 
0385     /* Note that it is possible to skip all events because of blacklist */
0386     if (event) {
0387         /* Show how to use the event. */
0388         pr_info("\nYou can now use it in all perf tools, such as:\n\n");
0389         pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", group, event);
0390     }
0391 
0392 out_cleanup:
0393     cleanup_perf_probe_events(pevs, npevs);
0394     exit_probe_symbol_maps();
0395     return ret;
0396 }
0397 
0398 static int del_perf_probe_caches(struct strfilter *filter)
0399 {
0400     struct probe_cache *cache;
0401     struct strlist *bidlist;
0402     struct str_node *nd;
0403     int ret;
0404 
0405     bidlist = build_id_cache__list_all(false);
0406     if (!bidlist) {
0407         ret = -errno;
0408         pr_debug("Failed to get buildids: %d\n", ret);
0409         return ret ?: -ENOMEM;
0410     }
0411 
0412     strlist__for_each_entry(nd, bidlist) {
0413         cache = probe_cache__new(nd->s, NULL);
0414         if (!cache)
0415             continue;
0416         if (probe_cache__filter_purge(cache, filter) < 0 ||
0417             probe_cache__commit(cache) < 0)
0418             pr_warning("Failed to remove entries for %s\n", nd->s);
0419         probe_cache__delete(cache);
0420     }
0421     return 0;
0422 }
0423 
0424 static int perf_del_probe_events(struct strfilter *filter)
0425 {
0426     int ret, ret2, ufd = -1, kfd = -1;
0427     char *str = strfilter__string(filter);
0428     struct strlist *klist = NULL, *ulist = NULL;
0429     struct str_node *ent;
0430 
0431     if (!str)
0432         return -EINVAL;
0433 
0434     pr_debug("Delete filter: \'%s\'\n", str);
0435 
0436     if (probe_conf.cache)
0437         return del_perf_probe_caches(filter);
0438 
0439     /* Get current event names */
0440     ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW);
0441     if (ret < 0)
0442         goto out;
0443 
0444     klist = strlist__new(NULL, NULL);
0445     ulist = strlist__new(NULL, NULL);
0446     if (!klist || !ulist) {
0447         ret = -ENOMEM;
0448         goto out;
0449     }
0450 
0451     ret = probe_file__get_events(kfd, filter, klist);
0452     if (ret == 0) {
0453         strlist__for_each_entry(ent, klist)
0454             pr_info("Removed event: %s\n", ent->s);
0455 
0456         ret = probe_file__del_strlist(kfd, klist);
0457         if (ret < 0)
0458             goto error;
0459     } else if (ret == -ENOMEM)
0460         goto error;
0461 
0462     ret2 = probe_file__get_events(ufd, filter, ulist);
0463     if (ret2 == 0) {
0464         strlist__for_each_entry(ent, ulist)
0465             pr_info("Removed event: %s\n", ent->s);
0466 
0467         ret2 = probe_file__del_strlist(ufd, ulist);
0468         if (ret2 < 0)
0469             goto error;
0470     } else if (ret2 == -ENOMEM)
0471         goto error;
0472 
0473     if (ret == -ENOENT && ret2 == -ENOENT)
0474         pr_warning("\"%s\" does not hit any event.\n", str);
0475     else
0476         ret = 0;
0477 
0478 error:
0479     if (kfd >= 0)
0480         close(kfd);
0481     if (ufd >= 0)
0482         close(ufd);
0483 out:
0484     strlist__delete(klist);
0485     strlist__delete(ulist);
0486     free(str);
0487 
0488     return ret;
0489 }
0490 
0491 #ifdef HAVE_DWARF_SUPPORT
0492 #define PROBEDEF_STR    \
0493     "[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT [[NAME=]ARG ...]"
0494 #else
0495 #define PROBEDEF_STR    "[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]"
0496 #endif
0497 
0498 
0499 static int
0500 __cmd_probe(int argc, const char **argv)
0501 {
0502     const char * const probe_usage[] = {
0503         "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
0504         "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
0505         "perf probe [<options>] --del '[GROUP:]EVENT' ...",
0506         "perf probe --list [GROUP:]EVENT ...",
0507 #ifdef HAVE_DWARF_SUPPORT
0508         "perf probe [<options>] --line 'LINEDESC'",
0509         "perf probe [<options>] --vars 'PROBEPOINT'",
0510 #endif
0511         "perf probe [<options>] --funcs",
0512         NULL
0513     };
0514     struct option options[] = {
0515     OPT_INCR('v', "verbose", &verbose,
0516             "be more verbose (show parsed arguments, etc)"),
0517     OPT_BOOLEAN('q', "quiet", &params.quiet,
0518             "be quiet (do not show any messages)"),
0519     OPT_CALLBACK_DEFAULT('l', "list", NULL, "[GROUP:]EVENT",
0520                  "list up probe events",
0521                  opt_set_filter_with_command, DEFAULT_LIST_FILTER),
0522     OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
0523              opt_set_filter_with_command),
0524     OPT_CALLBACK('a', "add", NULL, PROBEDEF_STR,
0525         "probe point definition, where\n"
0526         "\t\tGROUP:\tGroup name (optional)\n"
0527         "\t\tEVENT:\tEvent name\n"
0528         "\t\tFUNC:\tFunction name\n"
0529         "\t\tOFF:\tOffset from function entry (in byte)\n"
0530         "\t\t%return:\tPut the probe at function return\n"
0531 #ifdef HAVE_DWARF_SUPPORT
0532         "\t\tSRC:\tSource code path\n"
0533         "\t\tRL:\tRelative line number from function entry.\n"
0534         "\t\tAL:\tAbsolute line number in file.\n"
0535         "\t\tPT:\tLazy expression of line code.\n"
0536         "\t\tARG:\tProbe argument (local variable name or\n"
0537         "\t\t\tkprobe-tracer argument format.)\n",
0538 #else
0539         "\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n",
0540 #endif
0541         opt_add_probe_event),
0542     OPT_CALLBACK('D', "definition", NULL, PROBEDEF_STR,
0543         "Show trace event definition of given traceevent for k/uprobe_events.",
0544         opt_add_probe_event),
0545     OPT_BOOLEAN('f', "force", &probe_conf.force_add, "forcibly add events"
0546             " with existing name"),
0547     OPT_CALLBACK('L', "line", NULL,
0548              "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
0549              "Show source code lines.", opt_show_lines),
0550     OPT_CALLBACK('V', "vars", NULL,
0551              "FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT",
0552              "Show accessible variables on PROBEDEF", opt_show_vars),
0553     OPT_BOOLEAN('\0', "externs", &probe_conf.show_ext_vars,
0554             "Show external variables too (with --vars only)"),
0555     OPT_BOOLEAN('\0', "range", &probe_conf.show_location_range,
0556         "Show variables location range in scope (with --vars only)"),
0557     OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
0558            "file", "vmlinux pathname"),
0559     OPT_STRING('s', "source", &symbol_conf.source_prefix,
0560            "directory", "path to kernel source"),
0561     OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines,
0562         "Don't search inlined functions"),
0563     OPT__DRY_RUN(&probe_event_dry_run),
0564     OPT_INTEGER('\0', "max-probes", &probe_conf.max_probes,
0565          "Set how many probe points can be found for a probe."),
0566     OPT_CALLBACK_DEFAULT('F', "funcs", NULL, "[FILTER]",
0567                  "Show potential probe-able functions.",
0568                  opt_set_filter_with_command, DEFAULT_FUNC_FILTER),
0569     OPT_CALLBACK('\0', "filter", NULL,
0570              "[!]FILTER", "Set a filter (with --vars/funcs only)\n"
0571              "\t\t\t(default: \"" DEFAULT_VAR_FILTER "\" for --vars,\n"
0572              "\t\t\t \"" DEFAULT_FUNC_FILTER "\" for --funcs)",
0573              opt_set_filter),
0574     OPT_CALLBACK('x', "exec", NULL, "executable|path",
0575             "target executable name or path", opt_set_target),
0576     OPT_CALLBACK('m', "module", NULL, "modname|path",
0577         "target module name (for online) or path (for offline)",
0578         opt_set_target),
0579     OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
0580             "Enable symbol demangling"),
0581     OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
0582             "Enable kernel symbol demangling"),
0583     OPT_BOOLEAN(0, "cache", &probe_conf.cache, "Manipulate probe cache"),
0584     OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
0585            "Look for files with symbols relative to this directory"),
0586     OPT_CALLBACK(0, "target-ns", NULL, "pid",
0587              "target pid for namespace contexts", opt_set_target_ns),
0588     OPT_BOOLEAN(0, "bootconfig", &probe_conf.bootconfig,
0589             "Output probe definition with bootconfig format"),
0590     OPT_END()
0591     };
0592     int ret;
0593 
0594     set_option_flag(options, 'a', "add", PARSE_OPT_EXCLUSIVE);
0595     set_option_flag(options, 'd', "del", PARSE_OPT_EXCLUSIVE);
0596     set_option_flag(options, 'D', "definition", PARSE_OPT_EXCLUSIVE);
0597     set_option_flag(options, 'l', "list", PARSE_OPT_EXCLUSIVE);
0598 #ifdef HAVE_DWARF_SUPPORT
0599     set_option_flag(options, 'L', "line", PARSE_OPT_EXCLUSIVE);
0600     set_option_flag(options, 'V', "vars", PARSE_OPT_EXCLUSIVE);
0601 #else
0602 # define set_nobuild(s, l, c) set_option_nobuild(options, s, l, "NO_DWARF=1", c)
0603     set_nobuild('L', "line", false);
0604     set_nobuild('V', "vars", false);
0605     set_nobuild('\0', "externs", false);
0606     set_nobuild('\0', "range", false);
0607     set_nobuild('k', "vmlinux", true);
0608     set_nobuild('s', "source", true);
0609     set_nobuild('\0', "no-inlines", true);
0610 # undef set_nobuild
0611 #endif
0612     set_option_flag(options, 'F', "funcs", PARSE_OPT_EXCLUSIVE);
0613 
0614     argc = parse_options(argc, argv, options, probe_usage,
0615                  PARSE_OPT_STOP_AT_NON_OPTION);
0616     if (argc > 0) {
0617         if (strcmp(argv[0], "-") == 0) {
0618             usage_with_options_msg(probe_usage, options,
0619                 "'-' is not supported.\n");
0620         }
0621         if (params.command && params.command != 'a') {
0622             usage_with_options_msg(probe_usage, options,
0623                 "another command except --add is set.\n");
0624         }
0625         ret = parse_probe_event_argv(argc, argv);
0626         if (ret < 0) {
0627             pr_err_with_code("  Error: Command Parse Error.", ret);
0628             return ret;
0629         }
0630         params.command = 'a';
0631     }
0632 
0633     ret = symbol__validate_sym_arguments();
0634     if (ret)
0635         return ret;
0636 
0637     if (params.quiet) {
0638         if (verbose != 0) {
0639             pr_err("  Error: -v and -q are exclusive.\n");
0640             return -EINVAL;
0641         }
0642         verbose = -1;
0643     }
0644 
0645     if (probe_conf.max_probes == 0)
0646         probe_conf.max_probes = MAX_PROBES;
0647 
0648     /*
0649      * Only consider the user's kernel image path if given.
0650      */
0651     symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
0652 
0653     /*
0654      * Except for --list, --del and --add, other command doesn't depend
0655      * nor change running kernel. So if user gives offline vmlinux,
0656      * ignore its buildid.
0657      */
0658     if (!strchr("lda", params.command) && symbol_conf.vmlinux_name)
0659         symbol_conf.ignore_vmlinux_buildid = true;
0660 
0661     switch (params.command) {
0662     case 'l':
0663         if (params.uprobes) {
0664             pr_err("  Error: Don't use --list with --exec.\n");
0665             parse_options_usage(probe_usage, options, "l", true);
0666             parse_options_usage(NULL, options, "x", true);
0667             return -EINVAL;
0668         }
0669         ret = show_perf_probe_events(params.filter);
0670         if (ret < 0)
0671             pr_err_with_code("  Error: Failed to show event list.", ret);
0672         return ret;
0673     case 'F':
0674         ret = show_available_funcs(params.target, params.nsi,
0675                        params.filter, params.uprobes);
0676         if (ret < 0)
0677             pr_err_with_code("  Error: Failed to show functions.", ret);
0678         return ret;
0679 #ifdef HAVE_DWARF_SUPPORT
0680     case 'L':
0681         ret = show_line_range(&params.line_range, params.target,
0682                       params.nsi, params.uprobes);
0683         if (ret < 0)
0684             pr_err_with_code("  Error: Failed to show lines.", ret);
0685         return ret;
0686     case 'V':
0687         if (!params.filter)
0688             params.filter = strfilter__new(DEFAULT_VAR_FILTER,
0689                                NULL);
0690 
0691         ret = show_available_vars(params.events, params.nevents,
0692                       params.filter);
0693         if (ret < 0)
0694             pr_err_with_code("  Error: Failed to show vars.", ret);
0695         return ret;
0696 #endif
0697     case 'd':
0698         ret = perf_del_probe_events(params.filter);
0699         if (ret < 0) {
0700             pr_err_with_code("  Error: Failed to delete events.", ret);
0701             return ret;
0702         }
0703         break;
0704     case 'D':
0705         if (probe_conf.bootconfig && params.uprobes) {
0706             pr_err("  Error: --bootconfig doesn't support uprobes.\n");
0707             return -EINVAL;
0708         }
0709         __fallthrough;
0710     case 'a':
0711 
0712         /* Ensure the last given target is used */
0713         if (params.target && !params.target_used) {
0714             pr_err("  Error: -x/-m must follow the probe definitions.\n");
0715             parse_options_usage(probe_usage, options, "m", true);
0716             parse_options_usage(NULL, options, "x", true);
0717             return -EINVAL;
0718         }
0719 
0720         ret = perf_add_probe_events(params.events, params.nevents);
0721         if (ret < 0) {
0722 
0723             /*
0724              * When perf_add_probe_events() fails it calls
0725              * cleanup_perf_probe_events(pevs, npevs), i.e.
0726              * cleanup_perf_probe_events(params.events, params.nevents), which
0727              * will call clear_perf_probe_event(), so set nevents to zero
0728              * to avoid cleanup_params() to call clear_perf_probe_event() again
0729              * on the same pevs.
0730              */
0731             params.nevents = 0;
0732             pr_err_with_code("  Error: Failed to add events.", ret);
0733             return ret;
0734         }
0735         break;
0736     default:
0737         usage_with_options(probe_usage, options);
0738     }
0739     return 0;
0740 }
0741 
0742 int cmd_probe(int argc, const char **argv)
0743 {
0744     int ret;
0745 
0746     ret = init_params();
0747     if (!ret) {
0748         ret = __cmd_probe(argc, argv);
0749         cleanup_params();
0750     }
0751 
0752     return ret < 0 ? ret : 0;
0753 }