diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2015-10-02 08:58:32 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-10-02 14:59:23 -0400 |
commit | 1a8ac29cbffc261f6d7c92e573878110a7dcbd94 (patch) | |
tree | a03dbd5c53ed99b1b804e8039533b30a25b645b0 | |
parent | fa52ceabc2a3e70431a82bca2bc547a15eaf19df (diff) |
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: Masami 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.localdomain
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/builtin-probe.c | 8 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 8 |
2 files changed, 8 insertions, 8 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index f7882ae9ebc6..530c3a28a58c 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
@@ -182,10 +182,8 @@ static int opt_set_target(const struct option *opt, const char *str, | |||
182 | if (str) { | 182 | if (str) { |
183 | if (!strcmp(opt->long_name, "exec")) | 183 | if (!strcmp(opt->long_name, "exec")) |
184 | params.uprobes = true; | 184 | params.uprobes = true; |
185 | #ifdef HAVE_DWARF_SUPPORT | ||
186 | else if (!strcmp(opt->long_name, "module")) | 185 | else if (!strcmp(opt->long_name, "module")) |
187 | params.uprobes = false; | 186 | params.uprobes = false; |
188 | #endif | ||
189 | else | 187 | else |
190 | return ret; | 188 | return ret; |
191 | 189 | ||
@@ -490,9 +488,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
490 | "file", "vmlinux pathname"), | 488 | "file", "vmlinux pathname"), |
491 | OPT_STRING('s', "source", &symbol_conf.source_prefix, | 489 | OPT_STRING('s', "source", &symbol_conf.source_prefix, |
492 | "directory", "path to kernel source"), | 490 | "directory", "path to kernel source"), |
493 | OPT_CALLBACK('m', "module", NULL, "modname|path", | ||
494 | "target module name (for online) or path (for offline)", | ||
495 | opt_set_target), | ||
496 | OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines, | 491 | OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines, |
497 | "Don't search inlined functions"), | 492 | "Don't search inlined functions"), |
498 | #endif | 493 | #endif |
@@ -509,6 +504,9 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
509 | opt_set_filter), | 504 | opt_set_filter), |
510 | OPT_CALLBACK('x', "exec", NULL, "executable|path", | 505 | OPT_CALLBACK('x', "exec", NULL, "executable|path", |
511 | "target executable name or path", opt_set_target), | 506 | "target executable name or path", opt_set_target), |
507 | OPT_CALLBACK('m', "module", NULL, "modname|path", | ||
508 | "target module name (for online) or path (for offline)", | ||
509 | opt_set_target), | ||
512 | OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, | 510 | OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, |
513 | "Enable symbol demangling"), | 511 | "Enable symbol demangling"), |
514 | OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, | 512 | OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 3010abc071ff..b51a8bfb40f9 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -2543,7 +2543,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, | |||
2543 | goto out; | 2543 | goto out; |
2544 | } | 2544 | } |
2545 | 2545 | ||
2546 | if (!pev->uprobes && !pp->retprobe) { | 2546 | /* Note that the symbols in the kmodule are not relocated */ |
2547 | if (!pev->uprobes && !pp->retprobe && !pev->target) { | ||
2547 | reloc_sym = kernel_get_ref_reloc_sym(); | 2548 | reloc_sym = kernel_get_ref_reloc_sym(); |
2548 | if (!reloc_sym) { | 2549 | if (!reloc_sym) { |
2549 | pr_warning("Relocated base symbol is not found!\n"); | 2550 | 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 | } | 2581 | } |
2581 | /* Add one probe point */ | 2582 | /* Add one probe point */ |
2582 | tp->address = map->unmap_ip(map, sym->start) + pp->offset; | 2583 | tp->address = map->unmap_ip(map, sym->start) + pp->offset; |
2583 | /* If we found a wrong one, mark it by NULL symbol */ | 2584 | |
2584 | if (!pev->uprobes && | 2585 | /* Check the kprobe (not in module) is within .text */ |
2586 | if (!pev->uprobes && !pev->target && | ||
2585 | kprobe_warn_out_range(sym->name, tp->address)) { | 2587 | kprobe_warn_out_range(sym->name, tp->address)) { |
2586 | tp->symbol = NULL; /* Skip it */ | 2588 | tp->symbol = NULL; /* Skip it */ |
2587 | skipped++; | 2589 | skipped++; |