Commit 92561cb7 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Arnaldo Carvalho de Melo

perf probe: Warn user to rebuild target with debuginfo

Warn user to rebuild target with debuginfo when the perf probe fails to
find debug information in the target binary.

Without this, perf probe just reports the failure, but it's no hint for
users. This gives more hint for users.

Without this:

  $ strip perf
  $ ./perf probe -x perf -L argv_split
  Failed to open debuginfo file.
    Error: Failed to show lines.

With this:

  $ strip perf
  $ ./perf probe -x perf -L argv_split
  The /home/fedora/ksrc/linux-3/tools/perf/perf file has no debug information.
  Rebuild with -g, or install an appropriate debuginfo package.
    Error: Failed to show lines.

The "rebuild with ..." part changes to "rebuild with CONFIG_DEBUG_INFO"
if the target is the kernel or a kernel module.
Suggested-by: default avatarArnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: yrl.pp-manager.tt@hitachi.com
Link: http://lkml.kernel.org/r/20140815014432.29869.57941.stgit@kbuild-fedora.novalocalSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent f373da34
...@@ -258,21 +258,33 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) ...@@ -258,21 +258,33 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
#ifdef HAVE_DWARF_SUPPORT #ifdef HAVE_DWARF_SUPPORT
/* Open new debuginfo of given module */ /* Open new debuginfo of given module */
static struct debuginfo *open_debuginfo(const char *module) static struct debuginfo *open_debuginfo(const char *module, bool silent)
{ {
const char *path = module; const char *path = module;
struct debuginfo *ret;
if (!module || !strchr(module, '/')) { if (!module || !strchr(module, '/')) {
path = kernel_get_module_path(module); path = kernel_get_module_path(module);
if (!path) { if (!path) {
if (!silent)
pr_err("Failed to find path of %s module.\n", pr_err("Failed to find path of %s module.\n",
module ?: "kernel"); module ?: "kernel");
return NULL; return NULL;
} }
} }
return debuginfo__new(path); ret = debuginfo__new(path);
if (!ret && !silent) {
pr_warning("The %s file has no debug information.\n", path);
if (!module || !strtailcmp(path, ".ko"))
pr_warning("Rebuild with CONFIG_DEBUG_INFO=y, ");
else
pr_warning("Rebuild with -g, ");
pr_warning("or install an appropriate debuginfo package.\n");
}
return ret;
} }
static int get_text_start_address(const char *exec, unsigned long *address) static int get_text_start_address(const char *exec, unsigned long *address)
{ {
Elf *elf; Elf *elf;
...@@ -333,15 +345,13 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp, ...@@ -333,15 +345,13 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
pr_debug("try to find information at %" PRIx64 " in %s\n", addr, pr_debug("try to find information at %" PRIx64 " in %s\n", addr,
tp->module ? : "kernel"); tp->module ? : "kernel");
dinfo = open_debuginfo(tp->module); dinfo = open_debuginfo(tp->module, verbose == 0);
if (dinfo) { if (dinfo) {
ret = debuginfo__find_probe_point(dinfo, ret = debuginfo__find_probe_point(dinfo,
(unsigned long)addr, pp); (unsigned long)addr, pp);
debuginfo__delete(dinfo); debuginfo__delete(dinfo);
} else { } else
pr_debug("Failed to open debuginfo at 0x%" PRIx64 "\n", addr);
ret = -ENOENT; ret = -ENOENT;
}
if (ret > 0) { if (ret > 0) {
pp->retprobe = tp->retprobe; pp->retprobe = tp->retprobe;
...@@ -457,13 +467,11 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, ...@@ -457,13 +467,11 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
struct debuginfo *dinfo; struct debuginfo *dinfo;
int ntevs, ret = 0; int ntevs, ret = 0;
dinfo = open_debuginfo(target); dinfo = open_debuginfo(target, !need_dwarf);
if (!dinfo) { if (!dinfo) {
if (need_dwarf) { if (need_dwarf)
pr_warning("Failed to open debuginfo file.\n");
return -ENOENT; return -ENOENT;
}
pr_debug("Could not open debuginfo. Try to use symbols.\n"); pr_debug("Could not open debuginfo. Try to use symbols.\n");
return 0; return 0;
} }
...@@ -620,11 +628,9 @@ static int __show_line_range(struct line_range *lr, const char *module) ...@@ -620,11 +628,9 @@ static int __show_line_range(struct line_range *lr, const char *module)
char *tmp; char *tmp;
/* Search a line range */ /* Search a line range */
dinfo = open_debuginfo(module); dinfo = open_debuginfo(module, false);
if (!dinfo) { if (!dinfo)
pr_warning("Failed to open debuginfo file.\n");
return -ENOENT; return -ENOENT;
}
ret = debuginfo__find_line_range(dinfo, lr); ret = debuginfo__find_line_range(dinfo, lr);
debuginfo__delete(dinfo); debuginfo__delete(dinfo);
...@@ -772,9 +778,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, ...@@ -772,9 +778,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
if (ret < 0) if (ret < 0)
return ret; return ret;
dinfo = open_debuginfo(module); dinfo = open_debuginfo(module, false);
if (!dinfo) { if (!dinfo) {
pr_warning("Failed to open debuginfo file.\n");
ret = -ENOENT; ret = -ENOENT;
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment