diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2015-05-27 04:37:18 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-05-27 11:21:45 -0400 |
commit | 419e87382873b11b17cb31e2f21859570a32e0d1 (patch) | |
tree | b9dd3061fb8f3633d295f5cef9978c40bc478a9b | |
parent | 9b5d1c29556989aa9dc1240566e78806ddefd160 (diff) |
perf probe: Show the error reason comes from invalid DSO
Show the reason of error when dso__load* fails. This shows when user
gives wrong kernel image or wrong path.
Without this, perf probe shows an obscure message:
----
$ perf probe -k ~/kbin/linux-3.x86_64/vmlinux -L vfs_read
Failed to find path of kernel module.
Error: Failed to show lines.
----
With this, perf shows appropriate error message:
----
$ perf probe -k ~/kbin/linux-3.x86_64/vmlinux -L vfs_read
Failed to find the path for kernel: Mismatching build id
Error: Failed to show lines.
----
And:
----
$ perf probe -k /non-exist/kernel/vmlinux -L vfs_read
Failed to find the path for kernel: No such file or directory
Error: Failed to show lines.
----
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Richard Weinberger <richard@nod.at>
Link: http://lkml.kernel.org/r/20150527083718.23880.84100.stgit@localhost.localdomain
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/probe-event.c | 47 | ||||
-rw-r--r-- | tools/perf/util/probe-event.h | 3 |
2 files changed, 24 insertions, 26 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 092256516262..f5be411bc69c 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -200,11 +200,12 @@ static void put_target_map(struct map *map, bool user) | |||
200 | } | 200 | } |
201 | 201 | ||
202 | 202 | ||
203 | static struct dso *kernel_get_module_dso(const char *module) | 203 | static int kernel_get_module_dso(const char *module, struct dso **pdso) |
204 | { | 204 | { |
205 | struct dso *dso; | 205 | struct dso *dso; |
206 | struct map *map; | 206 | struct map *map; |
207 | const char *vmlinux_name; | 207 | const char *vmlinux_name; |
208 | int ret = 0; | ||
208 | 209 | ||
209 | if (module) { | 210 | if (module) { |
210 | list_for_each_entry(dso, &host_machine->kernel_dsos.head, | 211 | list_for_each_entry(dso, &host_machine->kernel_dsos.head, |
@@ -214,30 +215,21 @@ static struct dso *kernel_get_module_dso(const char *module) | |||
214 | goto found; | 215 | goto found; |
215 | } | 216 | } |
216 | pr_debug("Failed to find module %s.\n", module); | 217 | pr_debug("Failed to find module %s.\n", module); |
217 | return NULL; | 218 | return -ENOENT; |
218 | } | 219 | } |
219 | 220 | ||
220 | map = host_machine->vmlinux_maps[MAP__FUNCTION]; | 221 | map = host_machine->vmlinux_maps[MAP__FUNCTION]; |
221 | dso = map->dso; | 222 | dso = map->dso; |
222 | 223 | ||
223 | vmlinux_name = symbol_conf.vmlinux_name; | 224 | vmlinux_name = symbol_conf.vmlinux_name; |
224 | if (vmlinux_name) { | 225 | dso->load_errno = 0; |
225 | if (dso__load_vmlinux(dso, map, vmlinux_name, false, NULL) <= 0) | 226 | if (vmlinux_name) |
226 | return NULL; | 227 | ret = dso__load_vmlinux(dso, map, vmlinux_name, false, NULL); |
227 | } else { | 228 | else |
228 | if (dso__load_vmlinux_path(dso, map, NULL) <= 0) { | 229 | ret = dso__load_vmlinux_path(dso, map, NULL); |
229 | pr_debug("Failed to load kernel map.\n"); | ||
230 | return NULL; | ||
231 | } | ||
232 | } | ||
233 | found: | 230 | found: |
234 | return dso; | 231 | *pdso = dso; |
235 | } | 232 | return ret; |
236 | |||
237 | const char *kernel_get_module_path(const char *module) | ||
238 | { | ||
239 | struct dso *dso = kernel_get_module_dso(module); | ||
240 | return (dso) ? dso->long_name : NULL; | ||
241 | } | 233 | } |
242 | 234 | ||
243 | static int convert_exec_to_group(const char *exec, char **result) | 235 | static int convert_exec_to_group(const char *exec, char **result) |
@@ -389,16 +381,25 @@ static int get_alternative_line_range(struct debuginfo *dinfo, | |||
389 | static struct debuginfo *open_debuginfo(const char *module, bool silent) | 381 | static struct debuginfo *open_debuginfo(const char *module, bool silent) |
390 | { | 382 | { |
391 | const char *path = module; | 383 | const char *path = module; |
392 | struct debuginfo *ret; | 384 | char reason[STRERR_BUFSIZE]; |
385 | struct debuginfo *ret = NULL; | ||
386 | struct dso *dso = NULL; | ||
387 | int err; | ||
393 | 388 | ||
394 | if (!module || !strchr(module, '/')) { | 389 | if (!module || !strchr(module, '/')) { |
395 | path = kernel_get_module_path(module); | 390 | err = kernel_get_module_dso(module, &dso); |
396 | if (!path) { | 391 | if (err < 0) { |
392 | if (!dso || dso->load_errno == 0) { | ||
393 | if (!strerror_r(-err, reason, STRERR_BUFSIZE)) | ||
394 | strcpy(reason, "(unknown)"); | ||
395 | } else | ||
396 | dso__strerror_load(dso, reason, STRERR_BUFSIZE); | ||
397 | if (!silent) | 397 | if (!silent) |
398 | pr_err("Failed to find path of %s module.\n", | 398 | pr_err("Failed to find the path for %s: %s\n", |
399 | module ?: "kernel"); | 399 | module ?: "kernel", reason); |
400 | return NULL; | 400 | return NULL; |
401 | } | 401 | } |
402 | path = dso->long_name; | ||
402 | } | 403 | } |
403 | ret = debuginfo__new(path); | 404 | ret = debuginfo__new(path); |
404 | if (!ret && !silent) { | 405 | if (!ret && !silent) { |
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 537eb329c2cf..31db6ee7db54 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h | |||
@@ -131,9 +131,6 @@ extern void line_range__clear(struct line_range *lr); | |||
131 | /* Initialize line range */ | 131 | /* Initialize line range */ |
132 | extern int line_range__init(struct line_range *lr); | 132 | extern int line_range__init(struct line_range *lr); |
133 | 133 | ||
134 | /* Internal use: Return kernel/module path */ | ||
135 | extern const char *kernel_get_module_path(const char *module); | ||
136 | |||
137 | extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs); | 134 | extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs); |
138 | extern int del_perf_probe_events(struct strfilter *filter); | 135 | extern int del_perf_probe_events(struct strfilter *filter); |
139 | extern int show_perf_probe_events(struct strfilter *filter); | 136 | extern int show_perf_probe_events(struct strfilter *filter); |