aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-record.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r--tools/perf/builtin-record.c68
1 files changed, 43 insertions, 25 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 1c49d4e8767c..a7c53a9ef372 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()
};