Commit 1a8ac29c authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Arnaldo Carvalho de Melo

perf probe: Allow probing on kmodules without dwarf

Allow probing on kernel modules when 'perf' is built without debuginfo
support.

Currently perf-probe --module requires linking with libdw, but this
doesn't make sense.

E.g.
  ----
  # make NO_DWARF=1
  # ./perf probe -m pcspkr pcspkr_event%return
    Error: unknown switch `m'
  ----

With this patch
  ----
  # ./perf probe -m pcspkr pcspkr_event%return
  Added new event:
    probe:pcspkr_event   (on pcspkr_event%return in pcspkr)

  You can now use it in all perf tools, such as:

          perf record -e probe:pcspkr_event -aR sleep 1
  ----
Signed-off-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/20151002125832.18617.78721.stgit@localhost.localdomainSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent fa52ceab
...@@ -182,10 +182,8 @@ static int opt_set_target(const struct option *opt, const char *str, ...@@ -182,10 +182,8 @@ static int opt_set_target(const struct option *opt, const char *str,
if (str) { if (str) {
if (!strcmp(opt->long_name, "exec")) if (!strcmp(opt->long_name, "exec"))
params.uprobes = true; params.uprobes = true;
#ifdef HAVE_DWARF_SUPPORT
else if (!strcmp(opt->long_name, "module")) else if (!strcmp(opt->long_name, "module"))
params.uprobes = false; params.uprobes = false;
#endif
else else
return ret; return ret;
...@@ -490,9 +488,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -490,9 +488,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
"file", "vmlinux pathname"), "file", "vmlinux pathname"),
OPT_STRING('s', "source", &symbol_conf.source_prefix, OPT_STRING('s', "source", &symbol_conf.source_prefix,
"directory", "path to kernel source"), "directory", "path to kernel source"),
OPT_CALLBACK('m', "module", NULL, "modname|path",
"target module name (for online) or path (for offline)",
opt_set_target),
OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines, OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines,
"Don't search inlined functions"), "Don't search inlined functions"),
#endif #endif
...@@ -509,6 +504,9 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -509,6 +504,9 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
opt_set_filter), opt_set_filter),
OPT_CALLBACK('x', "exec", NULL, "executable|path", OPT_CALLBACK('x', "exec", NULL, "executable|path",
"target executable name or path", opt_set_target), "target executable name or path", opt_set_target),
OPT_CALLBACK('m', "module", NULL, "modname|path",
"target module name (for online) or path (for offline)",
opt_set_target),
OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
"Enable symbol demangling"), "Enable symbol demangling"),
OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
......
...@@ -2543,7 +2543,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, ...@@ -2543,7 +2543,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
goto out; goto out;
} }
if (!pev->uprobes && !pp->retprobe) { /* Note that the symbols in the kmodule are not relocated */
if (!pev->uprobes && !pp->retprobe && !pev->target) {
reloc_sym = kernel_get_ref_reloc_sym(); reloc_sym = kernel_get_ref_reloc_sym();
if (!reloc_sym) { if (!reloc_sym) {
pr_warning("Relocated base symbol is not found!\n"); pr_warning("Relocated base symbol is not found!\n");
...@@ -2580,8 +2581,9 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, ...@@ -2580,8 +2581,9 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
} }
/* Add one probe point */ /* Add one probe point */
tp->address = map->unmap_ip(map, sym->start) + pp->offset; tp->address = map->unmap_ip(map, sym->start) + pp->offset;
/* If we found a wrong one, mark it by NULL symbol */
if (!pev->uprobes && /* Check the kprobe (not in module) is within .text */
if (!pev->uprobes && !pev->target &&
kprobe_warn_out_range(sym->name, tp->address)) { kprobe_warn_out_range(sym->name, tp->address)) {
tp->symbol = NULL; /* Skip it */ tp->symbol = NULL; /* Skip it */
skipped++; skipped++;
......
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