From a225a1d911f0e434dc0407df29fd08e4388f3fa4 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 3 Nov 2009 19:12:30 -0500 Subject: [PATCH] perf/probes: Fall back to non-dwarf if possible Fall back to non-dwarf probe point if the probe definition may not need dwarf analysis, when perf can't find vmlinux/debuginfo. This might skip some inlined code of target function. Signed-off-by: Masami Hiramatsu Acked-by: Frederic Weisbecker Cc: Steven Rostedt Cc: Jim Keniston Cc: Ananth N Mavinakayanahalli Cc: Christoph Hellwig Cc: Frank Ch. Eigler Cc: Jason Baron Cc: K.Prasad Cc: Peter Zijlstra Cc: Srikar Dronamraju LKML-Reference: <20091104001229.3454.63987.stgit@harusame> Signed-off-by: Ingo Molnar --- tools/perf/builtin-probe.c | 64 +++++++++++++++++++--------------- tools/perf/util/probe-finder.c | 6 ++-- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 65bcaed0ef49..d111a93f2209 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -189,7 +189,7 @@ static void parse_probe_event(const char *str) /* Parse probe point */ parse_probe_point(argv[0], pp); free(argv[0]); - if (pp->file) + if (pp->file || pp->line) session.need_dwarf = 1; /* Copy arguments */ @@ -347,36 +347,24 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) if (session.nr_probe == 0) usage_with_options(probe_usage, options); -#ifdef NO_LIBDWARF if (session.need_dwarf) - semantic_error("Dwarf-analysis is not supported"); -#endif - - /* Synthesize probes without dwarf */ - for (j = 0; j < session.nr_probe; j++) { -#ifndef NO_LIBDWARF - if (!session.probes[j].retprobe) { - session.need_dwarf = 1; - continue; - } -#endif - ret = synthesize_probe_event(&session.probes[j]); - if (ret == -E2BIG) - semantic_error("probe point is too long."); - else if (ret < 0) - die("Failed to synthesize a probe point."); - } - -#ifndef NO_LIBDWARF - if (!session.need_dwarf) - goto setup_probes; +#ifdef NO_LIBDWARF + semantic_error("Debuginfo-analysis is not supported"); +#else /* !NO_LIBDWARF */ + pr_info("Some probes require debuginfo.\n"); if (session.vmlinux) fd = open(session.vmlinux, O_RDONLY); else fd = open_default_vmlinux(); - if (fd < 0) - die("Could not open vmlinux/module file."); + if (fd < 0) { + if (session.need_dwarf) + die("Could not open vmlinux/module file."); + + pr_warning("Could not open vmlinux/module file." + " Try to use symbols.\n"); + goto end_dwarf; + } /* Searching probe points */ for (j = 0; j < session.nr_probe; j++) { @@ -386,14 +374,34 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) lseek(fd, SEEK_SET, 0); ret = find_probepoint(fd, pp); - if (ret <= 0) - die("No probe point found.\n"); + if (ret < 0) { + if (session.need_dwarf) + die("Could not analyze debuginfo."); + + pr_warning("An error occurred in debuginfo analysis. Try to use symbols.\n"); + break; + } + if (ret == 0) /* No error but failed to find probe point. */ + die("No probe point found."); } close(fd); -setup_probes: +end_dwarf: #endif /* !NO_LIBDWARF */ + /* Synthesize probes without dwarf */ + for (j = 0; j < session.nr_probe; j++) { + pp = &session.probes[j]; + if (pp->found) /* This probe is already found. */ + continue; + + ret = synthesize_probe_event(pp); + if (ret == -E2BIG) + semantic_error("probe point is too long."); + else if (ret < 0) + die("Failed to synthesize a probe point."); + } + /* Settng up probe points */ snprintf(buf, MAX_CMDLEN, "%s/../kprobe_events", debugfs_path); fd = open(buf, O_WRONLY, O_APPEND); diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 35d5a69aaf9b..293cdfc1b8ca 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -687,8 +687,10 @@ int find_probepoint(int fd, struct probe_point *pp) struct probe_finder pf = {.pp = pp}; ret = dwarf_init(fd, DW_DLC_READ, 0, 0, &__dw_debug, &__dw_error); - if (ret != DW_DLV_OK) - die("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO.\n"); + if (ret != DW_DLV_OK) { + pr_warning("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO.\n"); + return -ENOENT; + } pp->found = 0; while (++cu_number) {