diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index eb75a5efcfd7..416c10f8fd2a 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1077,6 +1077,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) struct perf_probe_point *pp = &pev->point; char *ptr, *tmp; char c, nc = 0; + bool file_spec = false; /* * * perf probe [EVENT=]SRC[:LN|;PTN] @@ -1105,6 +1106,23 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) arg = tmp; } + /* + * Check arg is function or file name and copy it. + * + * We consider arg to be a file spec if and only if it satisfies + * all of the below criteria:: + * - it does not include any of "+@%", + * - it includes one of ":;", and + * - it has a period '.' in the name. + * + * Otherwise, we consider arg to be a function specification. + */ + if (!strpbrk(arg, "+@%") && (ptr = strpbrk(arg, ";:")) != NULL) { + /* This is a file spec if it includes a '.' before ; or : */ + if (memchr(arg, '.', ptr - arg)) + file_spec = true; + } + ptr = strpbrk(arg, ";:+@%"); if (ptr) { nc = *ptr; @@ -1115,10 +1133,9 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) if (tmp == NULL) return -ENOMEM; - /* Check arg is function or file and copy it */ - if (strchr(tmp, '.')) /* File */ + if (file_spec) pp->file = tmp; - else /* Function */ + else pp->function = tmp; /* Parse other options */ @@ -2265,6 +2282,9 @@ static int get_new_event_name(char *buf, size_t len, const char *base, { int i, ret; + if (*base == '.') + base++; + /* Try no suffix */ ret = e_snprintf(buf, len, "%s", base); if (ret < 0) { @@ -2766,6 +2786,9 @@ int del_perf_probe_events(struct strlist *dellist) event = str; } + if (event && *event == '.') + event++; + ret = e_snprintf(buf, 128, "%s:%s", group, event); if (ret < 0) { pr_err("Failed to copy event.");