diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2015-02-27 21:53:29 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-03-02 10:27:43 -0500 |
commit | 79702f614187f652a814061e8f5875ddcc9e732d (patch) | |
tree | 9c9b99fbbbc030daf24ab3cb4f4222ec26eb9176 /tools/perf/util/probe-event.c | |
parent | de5349fa439dd32d432cd401eb2decfae20b9f74 (diff) |
perf probe: Warn if given uprobe event accesses memory on older kernel
Warn if given uprobe event accesses memory on older kernel.
Until 3.14, uprobe event only supports accessing registers so this warns
to upgrade kernel if uprobe-event returns -EINVAL and an argument of the
event accesses memory ($stack, @+offset, and +|-offs() symtax).
With this patch (on 3.10.0-123.13.2.el7.x86_64);
-----
# ./perf probe -x ./perf warn_uprobe_event_compat stack=-0\(%sp\)
Added new event:
Failed to write event: Invalid argument
Please upgrade your kernel to at least 3.14 to have access to feature -0(%sp)
Error: Failed to add events.
-----
Suggested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20150228025329.32106.70581.stgit@localhost.localdomain
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r-- | tools/perf/util/probe-event.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 7c0e765fa2e3..1c570c2fa7cc 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -2199,6 +2199,27 @@ static int get_new_event_name(char *buf, size_t len, const char *base, | |||
2199 | return ret; | 2199 | return ret; |
2200 | } | 2200 | } |
2201 | 2201 | ||
2202 | /* Warn if the current kernel's uprobe implementation is old */ | ||
2203 | static void warn_uprobe_event_compat(struct probe_trace_event *tev) | ||
2204 | { | ||
2205 | int i; | ||
2206 | char *buf = synthesize_probe_trace_command(tev); | ||
2207 | |||
2208 | /* Old uprobe event doesn't support memory dereference */ | ||
2209 | if (!tev->uprobes || tev->nargs == 0 || !buf) | ||
2210 | goto out; | ||
2211 | |||
2212 | for (i = 0; i < tev->nargs; i++) | ||
2213 | if (strglobmatch(tev->args[i].value, "[$@+-]*")) { | ||
2214 | pr_warning("Please upgrade your kernel to at least " | ||
2215 | "3.14 to have access to feature %s\n", | ||
2216 | tev->args[i].value); | ||
2217 | break; | ||
2218 | } | ||
2219 | out: | ||
2220 | free(buf); | ||
2221 | } | ||
2222 | |||
2202 | static int __add_probe_trace_events(struct perf_probe_event *pev, | 2223 | static int __add_probe_trace_events(struct perf_probe_event *pev, |
2203 | struct probe_trace_event *tevs, | 2224 | struct probe_trace_event *tevs, |
2204 | int ntevs, bool allow_suffix) | 2225 | int ntevs, bool allow_suffix) |
@@ -2295,6 +2316,8 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, | |||
2295 | */ | 2316 | */ |
2296 | allow_suffix = true; | 2317 | allow_suffix = true; |
2297 | } | 2318 | } |
2319 | if (ret == -EINVAL && pev->uprobes) | ||
2320 | warn_uprobe_event_compat(tev); | ||
2298 | 2321 | ||
2299 | /* Note that it is possible to skip all events because of blacklist */ | 2322 | /* Note that it is possible to skip all events because of blacklist */ |
2300 | if (ret >= 0 && tev->event) { | 2323 | if (ret >= 0 && tev->event) { |