perf probe: Allow probing on kmodules without dwarf
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Fri, 2 Oct 2015 12:58:32 +0000 (21:58 +0900)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 2 Oct 2015 18:59:23 +0000 (15:59 -0300)
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>
tools/perf/builtin-probe.c
tools/perf/util/probe-event.c

index f7882ae9ebc68b9674b4960e0a000ddc1972fef8..530c3a28a58c6bb1bcd48e67f854cd10a1445936 100644 (file)
@@ -182,10 +182,8 @@ static int opt_set_target(const struct option *opt, const char *str,
        if  (str) {
                if (!strcmp(opt->long_name, "exec"))
                        params.uprobes = true;
-#ifdef HAVE_DWARF_SUPPORT
                else if (!strcmp(opt->long_name, "module"))
                        params.uprobes = false;
-#endif
                else
                        return ret;
 
@@ -490,9 +488,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                   "file", "vmlinux pathname"),
        OPT_STRING('s', "source", &symbol_conf.source_prefix,
                   "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,
                "Don't search inlined functions"),
 #endif
@@ -509,6 +504,9 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
                     opt_set_filter),
        OPT_CALLBACK('x', "exec", NULL, "executable|path",
                        "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,
                    "Enable symbol demangling"),
        OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
index 3010abc071ff4dc3bcdecb7f21dfeb59d12894c4..b51a8bfb40f92cd861d0954ed84e71e15ee50784 100644 (file)
@@ -2543,7 +2543,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
                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();
                if (!reloc_sym) {
                        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,
                }
                /* Add one probe point */
                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)) {
                        tp->symbol = NULL;      /* Skip it */
                        skipped++;