diff options
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r-- | tools/perf/builtin-record.c | 68 |
1 files changed, 43 insertions, 25 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 1c49d4e8767..a7c53a9ef37 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -660,7 +660,7 @@ static const struct branch_mode branch_modes[] = { }; static int -parse_branch_stack(const struct option *opt, const char *str, int unset __used) +parse_branch_stack(const struct option *opt, const char *str, int unset) { #define ONLY_PLM \ (PERF_SAMPLE_BRANCH_USER |\ @@ -669,40 +669,53 @@ parse_branch_stack(const struct option *opt, const char *str, int unset __used) uint64_t *mode = (uint64_t *)opt->value; const struct branch_mode *br; - char *s, *os, *p; + char *s, *os = NULL, *p; int ret = -1; - *mode = 0; + if (unset) + return 0; - /* because str is read-only */ - s = os = strdup(str); - if (!s) + /* + * cannot set it twice, -b + --branch-filter for instance + */ + if (*mode) return -1; - for (;;) { - p = strchr(s, ','); - if (p) - *p = '\0'; - - for (br = branch_modes; br->name; br++) { - if (!strcasecmp(s, br->name)) - break; - } - if (!br->name) - goto error; + /* str may be NULL in case no arg is passed to -b */ + if (str) { + /* because str is read-only */ + s = os = strdup(str); + if (!s) + return -1; + + for (;;) { + p = strchr(s, ','); + if (p) + *p = '\0'; + + for (br = branch_modes; br->name; br++) { + if (!strcasecmp(s, br->name)) + break; + } + if (!br->name) { + ui__warning("unknown branch filter %s," + " check man page\n", s); + goto error; + } - *mode |= br->mode; + *mode |= br->mode; - if (!p) - break; + if (!p) + break; - s = p + 1; + s = p + 1; + } } ret = 0; + /* default to any branch */ if ((*mode & ~ONLY_PLM) == 0) { - error("need at least one branch type with -b\n"); - ret = -1; + *mode = PERF_SAMPLE_BRANCH_ANY; } error: free(os); @@ -798,8 +811,13 @@ const struct option record_options[] = { "monitor event in cgroup name only", parse_cgroups), OPT_STRING('u', "uid", &record.uid_str, "user", "user to profile"), - OPT_CALLBACK('b', "branch-stack", &record.opts.branch_stack, - "branch mode mask", "branch stack sampling modes", + + OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack, + "branch any", "sample any taken branches", + parse_branch_stack), + + OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack, + "branch filter mask", "branch stack filter modes", parse_branch_stack), OPT_END() }; |