mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/5] perf newt: Properly restore the screen when error exiting
@ 2010-03-22 16:10 Arnaldo Carvalho de Melo
  2010-03-22 16:10 ` [PATCH 2/5] perf probe: Cleanup debuginfo related code Arnaldo Carvalho de Melo
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-03-22 16:10 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo,
	Frédéric Weisbecker, Mike Galbraith, Peter Zijlstra,
	Paul Mackerras

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Show an OK message box with the last message sent via pr_err, etc.

Reported-by: Ingo Molnar <mingo@elte.hu>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/perf.c       |    4 ++--
 tools/perf/util/cache.h |    4 ++--
 tools/perf/util/newt.c  |   19 +++++++++++++------
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index d2de839..2826e70 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -264,11 +264,11 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 	set_debugfs_path();
 
 	status = p->fn(argc, argv, prefix);
+	exit_browser(status);
+
 	if (status)
 		return status & 0xff;
 
-	exit_browser();
-
 	/* Somebody closed stdout? */
 	if (fstat(fileno(stdout), &st))
 		return 0;
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 47b12a3..4b9aab7 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -77,10 +77,10 @@ static inline void setup_browser(void)
 {
 	setup_pager();
 }
-static inline void exit_browser(void) {}
+static inline void exit_browser(bool wait_for_ok __used) {}
 #else
 void setup_browser(void);
-void exit_browser(void);
+void exit_browser(bool wait_for_ok);
 #endif
 
 extern const char *editor_program;
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index 2d19e7a..3c2ef95 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -170,18 +170,20 @@ void perf_session__browse_hists(struct rb_root *hists, u64 session_total,
 	newtFormDestroy(form);
 }
 
+static char browser__last_msg[1024];
+
 int browser__show_help(const char *format, va_list ap)
 {
 	int ret;
 	static int backlog;
-	static char msg[1024];
 
-        ret = vsnprintf(msg + backlog, sizeof(msg) - backlog, format, ap);
+        ret = vsnprintf(browser__last_msg + backlog,
+			sizeof(browser__last_msg) - backlog, format, ap);
 	backlog += ret;
 
-	if (msg[backlog - 1] == '\n') {
+	if (browser__last_msg[backlog - 1] == '\n') {
 		newtPopHelpLine();
-		newtPushHelpLine(msg);
+		newtPushHelpLine(browser__last_msg);
 		newtRefresh();
 		backlog = 0;
 	}
@@ -200,8 +202,13 @@ void setup_browser(void)
 	newtPushHelpLine(" ");
 }
 
-void exit_browser(void)
+void exit_browser(bool wait_for_ok)
 {
-	if (use_browser)
+	if (use_browser) {
+		if (wait_for_ok) {
+			char title[] = "Fatal Error", ok[] = "Ok";
+			newtWinMessage(title, ok, browser__last_msg);
+		}
 		newtFinished();
+	}
 }
-- 
1.6.2.5


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/5] perf probe: Cleanup debuginfo related code
  2010-03-22 16:10 [PATCH 1/5] perf newt: Properly restore the screen when error exiting Arnaldo Carvalho de Melo
@ 2010-03-22 16:10 ` Arnaldo Carvalho de Melo
  2010-03-22 18:55   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2010-03-22 16:10 ` [PATCH 3/5] perf probe: Add NO_DWARF make option Arnaldo Carvalho de Melo
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-03-22 16:10 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Masami Hiramatsu, Frederic Weisbecker,
	Paul Mackerras, Mike Galbraith, Peter Zijlstra,
	Arnaldo Carvalho de Melo

From: Masami Hiramatsu <mhiramat@redhat.com>

Cleanup debuginfo related code to eliminate fragile code which
pointed by Ingo (Thanks!).
1) Invert logic of NO_DWARF_SUPPORT to DWARF_SUPPORT.
2) For removing assymetric/local variable ifdefs, introduce
  more helper functions.
3) Change options order to reduce the number of ifdefs.

Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Reported-by: Ingo Molnar <mingo@elte.hu>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Makefile            |    3 +-
 tools/perf/builtin-probe.c     |   28 ++--
 tools/perf/util/probe-event.c  |  343 +++++++++++++++++++++-------------------
 tools/perf/util/probe-finder.h |    4 +-
 4 files changed, 200 insertions(+), 178 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 0abd25e..c991818 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -506,9 +506,8 @@ endif
 
 ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
 	msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev);
-	BASIC_CFLAGS += -DNO_DWARF_SUPPORT
 else
-	BASIC_CFLAGS += -I/usr/include/elfutils
+	BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT
 	EXTLIBS += -lelf -ldw
 	LIB_OBJS += util/probe-finder.o
 endif
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index e0dafd9..cf2ffa5 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -109,7 +109,7 @@ static int opt_del_probe_event(const struct option *opt __used,
 	return 0;
 }
 
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 static int opt_show_lines(const struct option *opt __used,
 			  const char *str, int unset __used)
 {
@@ -126,7 +126,7 @@ static const char * const probe_usage[] = {
 	"perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
 	"perf probe [<options>] --del '[GROUP:]EVENT' ...",
 	"perf probe --list",
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 	"perf probe --line 'LINEDESC'",
 #endif
 	NULL
@@ -135,20 +135,16 @@ static const char * const probe_usage[] = {
 static const struct option options[] = {
 	OPT_BOOLEAN('v', "verbose", &verbose,
 		    "be more verbose (show parsed arguments, etc)"),
-#ifndef NO_DWARF_SUPPORT
-	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
-		   "file", "vmlinux pathname"),
-#endif
 	OPT_BOOLEAN('l', "list", &params.list_events,
 		    "list up current probe events"),
 	OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
 		opt_del_probe_event),
 	OPT_CALLBACK('a', "add", NULL,
-#ifdef NO_DWARF_SUPPORT
-		"[EVENT=]FUNC[+OFF|%return] [ARG ...]",
-#else
+#ifdef DWARF_SUPPORT
 		"[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT"
 		" [ARG ...]",
+#else
+		"[EVENT=]FUNC[+OFF|%return] [ARG ...]",
 #endif
 		"probe point definition, where\n"
 		"\t\tGROUP:\tGroup name (optional)\n"
@@ -156,23 +152,25 @@ static const struct option options[] = {
 		"\t\tFUNC:\tFunction name\n"
 		"\t\tOFF:\tOffset from function entry (in byte)\n"
 		"\t\t%return:\tPut the probe at function return\n"
-#ifdef NO_DWARF_SUPPORT
-		"\t\tARG:\tProbe argument (only \n"
-#else
+#ifdef DWARF_SUPPORT
 		"\t\tSRC:\tSource code path\n"
 		"\t\tRL:\tRelative line number from function entry.\n"
 		"\t\tAL:\tAbsolute line number in file.\n"
 		"\t\tPT:\tLazy expression of line code.\n"
 		"\t\tARG:\tProbe argument (local variable name or\n"
-#endif
 		"\t\t\tkprobe-tracer argument format.)\n",
+#else
+		"\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n",
+#endif
 		opt_add_probe_event),
 	OPT_BOOLEAN('f', "force", &params.force_add, "forcibly add events"
 		    " with existing name"),
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 	OPT_CALLBACK('L', "line", NULL,
 		     "FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]",
 		     "Show source code lines.", opt_show_lines),
+	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
+		   "file", "vmlinux pathname"),
 #endif
 	OPT__DRY_RUN(&probe_event_dry_run),
 	OPT_END()
@@ -211,7 +209,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
 		return 0;
 	}
 
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 	if (params.show_lines) {
 		if (params.nevents != 0 || params.dellist) {
 			pr_warning("  Error: Don't use --line with"
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index c6603f3..3fc0be7 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -42,7 +42,8 @@
 #include "color.h"
 #include "symbol.h"
 #include "thread.h"
-#include "parse-events.h"  /* For debugfs_path */
+#include "trace-event.h"	/* For __unused */
+#include "parse-events.h"	/* For debugfs_path */
 #include "probe-event.h"
 #include "probe-finder.h"
 
@@ -70,10 +71,11 @@ static int e_snprintf(char *str, size_t size, const char *format, ...)
 	return ret;
 }
 
+static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
 static struct map_groups kmap_groups;
 static struct map *kmaps[MAP__NR_TYPES];
 
-/* Initialize symbol maps for vmlinux */
+/* Initialize symbol maps and path of vmlinux */
 static void init_vmlinux(void)
 {
 	symbol_conf.sort_by_name = true;
@@ -89,7 +91,7 @@ static void init_vmlinux(void)
 		die("Failed to create kernel maps.");
 }
 
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 static int open_vmlinux(void)
 {
 	if (map__load(kmaps[MAP__FUNCTION], NULL) < 0) {
@@ -99,6 +101,176 @@ static int open_vmlinux(void)
 	pr_debug("Try to open %s\n", kmaps[MAP__FUNCTION]->dso->long_name);
 	return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
 }
+
+static void convert_to_perf_probe_point(struct kprobe_trace_point *tp,
+					struct perf_probe_point *pp)
+{
+	struct symbol *sym;
+	int fd, ret = 0;
+
+	sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
+				       tp->symbol, NULL);
+	if (sym) {
+		fd = open_vmlinux();
+		ret = find_perf_probe_point(fd, sym->start + tp->offset, pp);
+		close(fd);
+	}
+	if (ret <= 0) {
+		pp->function = xstrdup(tp->symbol);
+		pp->offset = tp->offset;
+	}
+	pp->retprobe = tp->retprobe;
+}
+
+/* Try to find perf_probe_event with debuginfo */
+static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
+					   struct kprobe_trace_event **tevs)
+{
+	bool need_dwarf = perf_probe_event_need_dwarf(pev);
+	int fd, ntevs;
+
+	fd = open_vmlinux();
+	if (fd < 0) {
+		if (need_dwarf)
+			die("Could not open debuginfo file.");
+
+		pr_debug("Could not open vmlinux. Try to use symbols.\n");
+		return 0;
+	}
+
+	/* Searching trace events corresponding to probe event */
+	ntevs = find_kprobe_trace_events(fd, pev, tevs);
+	close(fd);
+
+	if (ntevs > 0)	/* Succeeded to find trace events */
+		return ntevs;
+
+	if (ntevs == 0)	/* No error but failed to find probe point. */
+		die("Probe point '%s' not found. - probe not added.",
+		    synthesize_perf_probe_point(&pev->point));
+
+	/* Error path */
+	if (need_dwarf) {
+		if (ntevs == -ENOENT)
+			pr_warning("No dwarf info found in the vmlinux - "
+				"please rebuild with CONFIG_DEBUG_INFO=y.\n");
+		die("Could not analyze debuginfo.");
+	}
+	pr_debug("An error occurred in debuginfo analysis."
+		 " Try to use symbols.\n");
+	return 0;
+
+}
+
+#define LINEBUF_SIZE 256
+#define NR_ADDITIONAL_LINES 2
+
+static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
+{
+	char buf[LINEBUF_SIZE];
+	const char *color = PERF_COLOR_BLUE;
+
+	if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
+		goto error;
+	if (!skip) {
+		if (show_num)
+			fprintf(stdout, "%7u  %s", l, buf);
+		else
+			color_fprintf(stdout, color, "         %s", buf);
+	}
+
+	while (strlen(buf) == LINEBUF_SIZE - 1 &&
+	       buf[LINEBUF_SIZE - 2] != '\n') {
+		if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
+			goto error;
+		if (!skip) {
+			if (show_num)
+				fprintf(stdout, "%s", buf);
+			else
+				color_fprintf(stdout, color, "%s", buf);
+		}
+	}
+	return;
+error:
+	if (feof(fp))
+		die("Source file is shorter than expected.");
+	else
+		die("File read error: %s", strerror(errno));
+}
+
+/*
+ * Show line-range always requires debuginfo to find source file and
+ * line number.
+ */
+void show_line_range(struct line_range *lr)
+{
+	unsigned int l = 1;
+	struct line_node *ln;
+	FILE *fp;
+	int fd, ret;
+
+	/* Search a line range */
+	init_vmlinux();
+	fd = open_vmlinux();
+	if (fd < 0)
+		die("Could not open debuginfo file.");
+	ret = find_line_range(fd, lr);
+	if (ret <= 0)
+		die("Source line is not found.\n");
+	close(fd);
+
+	setup_pager();
+
+	if (lr->function)
+		fprintf(stdout, "<%s:%d>\n", lr->function,
+			lr->start - lr->offset);
+	else
+		fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
+
+	fp = fopen(lr->path, "r");
+	if (fp == NULL)
+		die("Failed to open %s: %s", lr->path, strerror(errno));
+	/* Skip to starting line number */
+	while (l < lr->start)
+		show_one_line(fp, l++, true, false);
+
+	list_for_each_entry(ln, &lr->line_list, list) {
+		while (ln->line > l)
+			show_one_line(fp, (l++) - lr->offset, false, false);
+		show_one_line(fp, (l++) - lr->offset, false, true);
+	}
+
+	if (lr->end == INT_MAX)
+		lr->end = l + NR_ADDITIONAL_LINES;
+	while (l < lr->end && !feof(fp))
+		show_one_line(fp, (l++) - lr->offset, false, false);
+
+	fclose(fp);
+}
+
+#else	/* !DWARF_SUPPORT */
+
+static void convert_to_perf_probe_point(struct kprobe_trace_point *tp,
+					struct perf_probe_point *pp)
+{
+	pp->function = xstrdup(tp->symbol);
+	pp->offset = tp->offset;
+	pp->retprobe = tp->retprobe;
+}
+
+static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
+				struct kprobe_trace_event **tevs __unused)
+{
+	if (perf_probe_event_need_dwarf(pev))
+		die("Debuginfo-analysis is not supported");
+	return 0;
+}
+
+void show_line_range(struct line_range *lr __unused)
+{
+	die("Debuginfo-analysis is not supported");
+}
+
 #endif
 
 void parse_line_range_desc(const char *arg, struct line_range *lr)
@@ -592,32 +764,14 @@ void convert_to_perf_probe_event(struct kprobe_trace_event *tev,
 {
 	char buf[64];
 	int i;
-#ifndef NO_DWARF_SUPPORT
-	struct symbol *sym;
-	int fd, ret = 0;
-
-	sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
-				       tev->point.symbol, NULL);
-	if (sym) {
-		fd = open_vmlinux();
-		ret = find_perf_probe_point(fd, sym->start + tev->point.offset,
-					    &pev->point);
-		close(fd);
-	}
-	if (ret <= 0) {
-		pev->point.function = xstrdup(tev->point.symbol);
-		pev->point.offset = tev->point.offset;
-	}
-#else
-	/* Convert trace_point to probe_point */
-	pev->point.function = xstrdup(tev->point.symbol);
-	pev->point.offset = tev->point.offset;
-#endif
-	pev->point.retprobe = tev->point.retprobe;
 
+	/* Convert event/group name */
 	pev->event = xstrdup(tev->event);
 	pev->group = xstrdup(tev->group);
 
+	/* Convert trace_point to probe_point */
+	convert_to_perf_probe_point(&tev->point, &pev->point);
+
 	/* Convert trace_arg to probe_arg */
 	pev->nargs = tev->nargs;
 	pev->args = xzalloc(sizeof(struct perf_probe_arg) * pev->nargs);
@@ -944,52 +1098,13 @@ static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
 					  struct kprobe_trace_event **tevs)
 {
 	struct symbol *sym;
-	bool need_dwarf;
-#ifndef NO_DWARF_SUPPORT
-	int fd;
-#endif
 	int ntevs = 0, i;
 	struct kprobe_trace_event *tev;
 
-	need_dwarf = perf_probe_event_need_dwarf(pev);
-
-	if (need_dwarf)
-#ifdef NO_DWARF_SUPPORT
-		die("Debuginfo-analysis is not supported");
-#else	/* !NO_DWARF_SUPPORT */
-		pr_debug("Some probes require debuginfo.\n");
-
-	fd = open_vmlinux();
-	if (fd < 0) {
-		if (need_dwarf)
-			die("Could not open debuginfo file.");
-
-		pr_debug("Could not open vmlinux/module file."
-			 " Try to use symbols.\n");
-		goto end_dwarf;
-	}
-
-	/* Searching probe points */
-	ntevs = find_kprobe_trace_events(fd, pev, tevs);
-
-	if (ntevs > 0)	/* Found */
-		goto found;
-
-	if (ntevs == 0)	/* No error but failed to find probe point. */
-		die("Probe point '%s' not found. - probe not added.",
-		    synthesize_perf_probe_point(&pev->point));
-
-	/* Error path */
-	if (need_dwarf) {
-		if (ntevs == -ENOENT)
-			pr_warning("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO=y.\n");
-		die("Could not analyze debuginfo.");
-	}
-	pr_debug("An error occurred in debuginfo analysis."
-		 " Try to use symbols.\n");
-
-end_dwarf:
-#endif /* !NO_DWARF_SUPPORT */
+	/* Convert perf_probe_event with debuginfo */
+	ntevs = try_to_find_kprobe_trace_events(pev, tevs);
+	if (ntevs > 0)
+		return ntevs;
 
 	/* Allocate trace event buffer */
 	ntevs = 1;
@@ -1012,10 +1127,7 @@ end_dwarf:
 	if (!sym)
 		die("Kernel symbol \'%s\' not found - probe not added.",
 		    tev->point.symbol);
-#ifndef NO_DWARF_SUPPORT
-found:
-	close(fd);
-#endif
+
 	return ntevs;
 }
 
@@ -1133,90 +1245,3 @@ void del_perf_probe_events(struct strlist *dellist)
 	close(fd);
 }
 
-#define LINEBUF_SIZE 256
-#define NR_ADDITIONAL_LINES 2
-
-static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
-{
-	char buf[LINEBUF_SIZE];
-	const char *color = PERF_COLOR_BLUE;
-
-	if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
-		goto error;
-	if (!skip) {
-		if (show_num)
-			fprintf(stdout, "%7u  %s", l, buf);
-		else
-			color_fprintf(stdout, color, "         %s", buf);
-	}
-
-	while (strlen(buf) == LINEBUF_SIZE - 1 &&
-	       buf[LINEBUF_SIZE - 2] != '\n') {
-		if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
-			goto error;
-		if (!skip) {
-			if (show_num)
-				fprintf(stdout, "%s", buf);
-			else
-				color_fprintf(stdout, color, "%s", buf);
-		}
-	}
-	return;
-error:
-	if (feof(fp))
-		die("Source file is shorter than expected.");
-	else
-		die("File read error: %s", strerror(errno));
-}
-
-void show_line_range(struct line_range *lr)
-{
-	unsigned int l = 1;
-	struct line_node *ln;
-	FILE *fp;
-#ifndef NO_DWARF_SUPPORT
-	int fd, ret;
-#endif
-
-	/* Search a line range */
-	init_vmlinux();
-#ifndef NO_DWARF_SUPPORT
-	fd = open_vmlinux();
-	if (fd < 0)
-		die("Could not open debuginfo file.");
-	ret = find_line_range(fd, lr);
-	if (ret <= 0)
-		die("Source line is not found.\n");
-	close(fd);
-#endif
-
-	setup_pager();
-
-	if (lr->function)
-		fprintf(stdout, "<%s:%d>\n", lr->function,
-			lr->start - lr->offset);
-	else
-		fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
-
-	fp = fopen(lr->path, "r");
-	if (fp == NULL)
-		die("Failed to open %s: %s", lr->path, strerror(errno));
-	/* Skip to starting line number */
-	while (l < lr->start)
-		show_one_line(fp, l++, true, false);
-
-	list_for_each_entry(ln, &lr->line_list, list) {
-		while (ln->line > l)
-			show_one_line(fp, (l++) - lr->offset, false, false);
-		show_one_line(fp, (l++) - lr->offset, false, true);
-	}
-
-	if (lr->end == INT_MAX)
-		lr->end = l + NR_ADDITIONAL_LINES;
-	while (l < lr->end && !feof(fp))
-		show_one_line(fp, (l++) - lr->offset, false, false);
-
-	fclose(fp);
-}
-
-
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 2f2307d..3564f22 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -15,7 +15,7 @@ static inline int is_c_varname(const char *name)
 	return isalpha(name[0]) || name[0] == '_';
 }
 
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 /* Find kprobe_trace_events specified by perf_probe_event from debuginfo */
 extern int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
 				    struct kprobe_trace_event **tevs);
@@ -57,6 +57,6 @@ struct line_finder {
 	int			found;
 };
 
-#endif /* NO_DWARF_SUPPORT */
+#endif /* DWARF_SUPPORT */
 
 #endif /*_PROBE_FINDER_H */
-- 
1.6.2.5


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/5] perf probe: Add NO_DWARF make option
  2010-03-22 16:10 [PATCH 1/5] perf newt: Properly restore the screen when error exiting Arnaldo Carvalho de Melo
  2010-03-22 16:10 ` [PATCH 2/5] perf probe: Cleanup debuginfo related code Arnaldo Carvalho de Melo
@ 2010-03-22 16:10 ` Arnaldo Carvalho de Melo
  2010-03-22 18:55   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2010-03-22 16:10 ` [PATCH 4/5] perf stat: Better report failure to collect system wide stats Arnaldo Carvalho de Melo
  2010-03-22 16:10 ` [PATCH 5/5] perf tools: Exit browser before printing usage when unkown option passed Arnaldo Carvalho de Melo
  3 siblings, 1 reply; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-03-22 16:10 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Masami Hiramatsu, Ingo Molnar, Frederic Weisbecker,
	Paul Mackerras, Mike Galbraith, Peter Zijlstra,
	Arnaldo Carvalho de Melo

From: Masami Hiramatsu <mhiramat@redhat.com>

Add NO_DWARF make option for testing build without libdw.

Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Makefile |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index c991818..6903645 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -150,6 +150,8 @@ all::
 # Define LDFLAGS=-static to build a static binary.
 #
 # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
+#
+# Define NO_DWARF if you do not want debug-info analysis feature at all.
 
 PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
 	@$(SHELL_PATH) util/PERF-VERSION-GEN
@@ -507,10 +509,12 @@ endif
 ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
 	msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev);
 else
+ifndef NO_DWARF
 	BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT
 	EXTLIBS += -lelf -ldw
 	LIB_OBJS += util/probe-finder.o
 endif
+endif
 
 ifneq ($(shell sh -c "(echo '\#include <newt.h>'; echo 'int main(void) { newtInit(); newtCls(); return newtFinished(); }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -lnewt -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
 	msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
-- 
1.6.2.5


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 4/5] perf stat: Better report failure to collect system wide stats
  2010-03-22 16:10 [PATCH 1/5] perf newt: Properly restore the screen when error exiting Arnaldo Carvalho de Melo
  2010-03-22 16:10 ` [PATCH 2/5] perf probe: Cleanup debuginfo related code Arnaldo Carvalho de Melo
  2010-03-22 16:10 ` [PATCH 3/5] perf probe: Add NO_DWARF make option Arnaldo Carvalho de Melo
@ 2010-03-22 16:10 ` Arnaldo Carvalho de Melo
  2010-03-22 16:10 ` [PATCH 5/5] perf tools: Exit browser before printing usage when unkown option passed Arnaldo Carvalho de Melo
  3 siblings, 0 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-03-22 16:10 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo,
	Frédéric Weisbecker, Mike Galbraith, Peter Zijlstra,
	Paul Mackerras

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Before:

[acme@doppio linux-2.6-tip]$ perf stat -a sleep 1s

 Performance counter stats for 'sleep 1s':

  <not counted>  task-clock-msecs
  <not counted>  context-switches
  <not counted>  CPU-migrations
  <not counted>  page-faults
  <not counted>  cycles
  <not counted>  instructions
  <not counted>  branches
  <not counted>  branch-misses
  <not counted>  cache-references
  <not counted>  cache-misses

    1.016998463  seconds time elapsed

[acme@doppio linux-2.6-tip]$

Now:

[acme@doppio linux-2.6-tip]$ perf stat -a sleep 1s
No permission to collect system-wide stats.
Consider tweaking /proc/sys/kernel/perf_event_paranoid.
[acme@doppio linux-2.6-tip]$

Reported-by: Ingo Molnar <mingo@elte.hu>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c |   39 ++++++++++++++++++++++++++++-----------
 1 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index c92f90f..1036ca7 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -144,10 +144,11 @@ struct stats			runtime_branches_stats;
 #define ERR_PERF_OPEN \
 "Error: counter %d, sys_perf_event_open() syscall returned with %d (%s)\n"
 
-static void create_perf_stat_counter(int counter)
+static int create_perf_stat_counter(int counter)
 {
 	struct perf_event_attr *attr = attrs + counter;
 	int thread;
+	int ncreated = 0;
 
 	if (scale)
 		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
@@ -159,9 +160,11 @@ static void create_perf_stat_counter(int counter)
 		for (cpu = 0; cpu < nr_cpus; cpu++) {
 			fd[cpu][counter][0] = sys_perf_event_open(attr,
 					-1, cpumap[cpu], -1, 0);
-			if (fd[cpu][counter][0] < 0 && verbose)
-				fprintf(stderr, ERR_PERF_OPEN, counter,
-					fd[cpu][counter][0], strerror(errno));
+			if (fd[cpu][counter][0] < 0)
+				pr_debug(ERR_PERF_OPEN, counter,
+					 fd[cpu][counter][0], strerror(errno));
+			else
+				++ncreated;
 		}
 	} else {
 		attr->inherit	     = inherit;
@@ -172,12 +175,16 @@ static void create_perf_stat_counter(int counter)
 		for (thread = 0; thread < thread_num; thread++) {
 			fd[0][counter][thread] = sys_perf_event_open(attr,
 				all_tids[thread], -1, -1, 0);
-			if (fd[0][counter][thread] < 0 && verbose)
-				fprintf(stderr, ERR_PERF_OPEN, counter,
-					fd[0][counter][thread],
-					strerror(errno));
+			if (fd[0][counter][thread] < 0)
+				pr_debug(ERR_PERF_OPEN, counter,
+					 fd[0][counter][thread],
+					 strerror(errno));
+			else
+				++ncreated;
 		}
 	}
+
+	return ncreated;
 }
 
 /*
@@ -264,7 +271,7 @@ static int run_perf_stat(int argc __used, const char **argv)
 {
 	unsigned long long t0, t1;
 	int status = 0;
-	int counter;
+	int counter, ncreated = 0;
 	int child_ready_pipe[2], go_pipe[2];
 	const bool forks = (argc > 0);
 	char buf;
@@ -324,7 +331,16 @@ static int run_perf_stat(int argc __used, const char **argv)
 	}
 
 	for (counter = 0; counter < nr_counters; counter++)
-		create_perf_stat_counter(counter);
+		ncreated += create_perf_stat_counter(counter);
+
+	if (ncreated == 0) {
+		pr_err("No permission to collect %sstats.\n"
+		       "Consider tweaking /proc/sys/kernel/perf_event_paranoid.\n",
+		       system_wide ? "system-wide " : "");
+		if (child_pid != -1)
+			kill(child_pid, SIGTERM);
+		return -1;
+	}
 
 	/*
 	 * Enable counters and exec the command:
@@ -587,7 +603,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
 		status = run_perf_stat(argc, argv);
 	}
 
-	print_stat(argc, argv);
+	if (status != -1)
+		print_stat(argc, argv);
 
 	return status;
 }
-- 
1.6.2.5


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 5/5] perf tools: Exit browser before printing usage when unkown option passed
  2010-03-22 16:10 [PATCH 1/5] perf newt: Properly restore the screen when error exiting Arnaldo Carvalho de Melo
                   ` (2 preceding siblings ...)
  2010-03-22 16:10 ` [PATCH 4/5] perf stat: Better report failure to collect system wide stats Arnaldo Carvalho de Melo
@ 2010-03-22 16:10 ` Arnaldo Carvalho de Melo
  3 siblings, 0 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-03-22 16:10 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo,
	Frédéric Weisbecker, Mike Galbraith, Peter Zijlstra,
	Paul Mackerras

From: Arnaldo Carvalho de Melo <acme@redhat.com>

If not the screen will get garbled when using newt.

Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/parse-options.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index efebd5b..79dfa0c 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -500,6 +500,7 @@ int usage_with_options_internal(const char * const *usagestr,
 void usage_with_options(const char * const *usagestr,
 			const struct option *opts)
 {
+	exit_browser(false);
 	usage_with_options_internal(usagestr, opts, 0);
 	exit(129);
 }
-- 
1.6.2.5


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [tip:perf/core] perf probe: Cleanup debuginfo related code
  2010-03-22 16:10 ` [PATCH 2/5] perf probe: Cleanup debuginfo related code Arnaldo Carvalho de Melo
@ 2010-03-22 18:55   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 7+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2010-03-22 18:55 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, paulus, acme, hpa, mingo, a.p.zijlstra, efault,
	fweisbec, tglx, mhiramat, mingo

Commit-ID:  4b4da7f76660ea8b5aa45615165c48f62167ffa8
Gitweb:     http://git.kernel.org/tip/4b4da7f76660ea8b5aa45615165c48f62167ffa8
Author:     Masami Hiramatsu <mhiramat@redhat.com>
AuthorDate: Mon, 22 Mar 2010 13:10:26 -0300
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Mon, 22 Mar 2010 18:47:35 +0100

perf probe: Cleanup debuginfo related code

Cleanup debuginfo related code to eliminate fragile code which
pointed by Ingo (Thanks!).
1) Invert logic of NO_DWARF_SUPPORT to DWARF_SUPPORT.
2) For removing assymetric/local variable ifdefs, introduce
  more helper functions.
3) Change options order to reduce the number of ifdefs.

Reported-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1269274229-20442-2-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 tools/perf/Makefile            |    3 +-
 tools/perf/builtin-probe.c     |   28 ++--
 tools/perf/util/probe-event.c  |  343 +++++++++++++++++++++-------------------
 tools/perf/util/probe-finder.h |    4 +-
 4 files changed, 200 insertions(+), 178 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 0abd25e..c991818 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -506,9 +506,8 @@ endif
 
 ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
 	msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev);
-	BASIC_CFLAGS += -DNO_DWARF_SUPPORT
 else
-	BASIC_CFLAGS += -I/usr/include/elfutils
+	BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT
 	EXTLIBS += -lelf -ldw
 	LIB_OBJS += util/probe-finder.o
 endif
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index e0dafd9..cf2ffa5 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -109,7 +109,7 @@ static int opt_del_probe_event(const struct option *opt __used,
 	return 0;
 }
 
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 static int opt_show_lines(const struct option *opt __used,
 			  const char *str, int unset __used)
 {
@@ -126,7 +126,7 @@ static const char * const probe_usage[] = {
 	"perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
 	"perf probe [<options>] --del '[GROUP:]EVENT' ...",
 	"perf probe --list",
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 	"perf probe --line 'LINEDESC'",
 #endif
 	NULL
@@ -135,20 +135,16 @@ static const char * const probe_usage[] = {
 static const struct option options[] = {
 	OPT_BOOLEAN('v', "verbose", &verbose,
 		    "be more verbose (show parsed arguments, etc)"),
-#ifndef NO_DWARF_SUPPORT
-	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
-		   "file", "vmlinux pathname"),
-#endif
 	OPT_BOOLEAN('l', "list", &params.list_events,
 		    "list up current probe events"),
 	OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
 		opt_del_probe_event),
 	OPT_CALLBACK('a', "add", NULL,
-#ifdef NO_DWARF_SUPPORT
-		"[EVENT=]FUNC[+OFF|%return] [ARG ...]",
-#else
+#ifdef DWARF_SUPPORT
 		"[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT"
 		" [ARG ...]",
+#else
+		"[EVENT=]FUNC[+OFF|%return] [ARG ...]",
 #endif
 		"probe point definition, where\n"
 		"\t\tGROUP:\tGroup name (optional)\n"
@@ -156,23 +152,25 @@ static const struct option options[] = {
 		"\t\tFUNC:\tFunction name\n"
 		"\t\tOFF:\tOffset from function entry (in byte)\n"
 		"\t\t%return:\tPut the probe at function return\n"
-#ifdef NO_DWARF_SUPPORT
-		"\t\tARG:\tProbe argument (only \n"
-#else
+#ifdef DWARF_SUPPORT
 		"\t\tSRC:\tSource code path\n"
 		"\t\tRL:\tRelative line number from function entry.\n"
 		"\t\tAL:\tAbsolute line number in file.\n"
 		"\t\tPT:\tLazy expression of line code.\n"
 		"\t\tARG:\tProbe argument (local variable name or\n"
-#endif
 		"\t\t\tkprobe-tracer argument format.)\n",
+#else
+		"\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n",
+#endif
 		opt_add_probe_event),
 	OPT_BOOLEAN('f', "force", &params.force_add, "forcibly add events"
 		    " with existing name"),
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 	OPT_CALLBACK('L', "line", NULL,
 		     "FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]",
 		     "Show source code lines.", opt_show_lines),
+	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
+		   "file", "vmlinux pathname"),
 #endif
 	OPT__DRY_RUN(&probe_event_dry_run),
 	OPT_END()
@@ -211,7 +209,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
 		return 0;
 	}
 
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 	if (params.show_lines) {
 		if (params.nevents != 0 || params.dellist) {
 			pr_warning("  Error: Don't use --line with"
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index c6603f3..3fc0be7 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -42,7 +42,8 @@
 #include "color.h"
 #include "symbol.h"
 #include "thread.h"
-#include "parse-events.h"  /* For debugfs_path */
+#include "trace-event.h"	/* For __unused */
+#include "parse-events.h"	/* For debugfs_path */
 #include "probe-event.h"
 #include "probe-finder.h"
 
@@ -70,10 +71,11 @@ static int e_snprintf(char *str, size_t size, const char *format, ...)
 	return ret;
 }
 
+static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
 static struct map_groups kmap_groups;
 static struct map *kmaps[MAP__NR_TYPES];
 
-/* Initialize symbol maps for vmlinux */
+/* Initialize symbol maps and path of vmlinux */
 static void init_vmlinux(void)
 {
 	symbol_conf.sort_by_name = true;
@@ -89,7 +91,7 @@ static void init_vmlinux(void)
 		die("Failed to create kernel maps.");
 }
 
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 static int open_vmlinux(void)
 {
 	if (map__load(kmaps[MAP__FUNCTION], NULL) < 0) {
@@ -99,6 +101,176 @@ static int open_vmlinux(void)
 	pr_debug("Try to open %s\n", kmaps[MAP__FUNCTION]->dso->long_name);
 	return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
 }
+
+static void convert_to_perf_probe_point(struct kprobe_trace_point *tp,
+					struct perf_probe_point *pp)
+{
+	struct symbol *sym;
+	int fd, ret = 0;
+
+	sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
+				       tp->symbol, NULL);
+	if (sym) {
+		fd = open_vmlinux();
+		ret = find_perf_probe_point(fd, sym->start + tp->offset, pp);
+		close(fd);
+	}
+	if (ret <= 0) {
+		pp->function = xstrdup(tp->symbol);
+		pp->offset = tp->offset;
+	}
+	pp->retprobe = tp->retprobe;
+}
+
+/* Try to find perf_probe_event with debuginfo */
+static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
+					   struct kprobe_trace_event **tevs)
+{
+	bool need_dwarf = perf_probe_event_need_dwarf(pev);
+	int fd, ntevs;
+
+	fd = open_vmlinux();
+	if (fd < 0) {
+		if (need_dwarf)
+			die("Could not open debuginfo file.");
+
+		pr_debug("Could not open vmlinux. Try to use symbols.\n");
+		return 0;
+	}
+
+	/* Searching trace events corresponding to probe event */
+	ntevs = find_kprobe_trace_events(fd, pev, tevs);
+	close(fd);
+
+	if (ntevs > 0)	/* Succeeded to find trace events */
+		return ntevs;
+
+	if (ntevs == 0)	/* No error but failed to find probe point. */
+		die("Probe point '%s' not found. - probe not added.",
+		    synthesize_perf_probe_point(&pev->point));
+
+	/* Error path */
+	if (need_dwarf) {
+		if (ntevs == -ENOENT)
+			pr_warning("No dwarf info found in the vmlinux - "
+				"please rebuild with CONFIG_DEBUG_INFO=y.\n");
+		die("Could not analyze debuginfo.");
+	}
+	pr_debug("An error occurred in debuginfo analysis."
+		 " Try to use symbols.\n");
+	return 0;
+
+}
+
+#define LINEBUF_SIZE 256
+#define NR_ADDITIONAL_LINES 2
+
+static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
+{
+	char buf[LINEBUF_SIZE];
+	const char *color = PERF_COLOR_BLUE;
+
+	if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
+		goto error;
+	if (!skip) {
+		if (show_num)
+			fprintf(stdout, "%7u  %s", l, buf);
+		else
+			color_fprintf(stdout, color, "         %s", buf);
+	}
+
+	while (strlen(buf) == LINEBUF_SIZE - 1 &&
+	       buf[LINEBUF_SIZE - 2] != '\n') {
+		if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
+			goto error;
+		if (!skip) {
+			if (show_num)
+				fprintf(stdout, "%s", buf);
+			else
+				color_fprintf(stdout, color, "%s", buf);
+		}
+	}
+	return;
+error:
+	if (feof(fp))
+		die("Source file is shorter than expected.");
+	else
+		die("File read error: %s", strerror(errno));
+}
+
+/*
+ * Show line-range always requires debuginfo to find source file and
+ * line number.
+ */
+void show_line_range(struct line_range *lr)
+{
+	unsigned int l = 1;
+	struct line_node *ln;
+	FILE *fp;
+	int fd, ret;
+
+	/* Search a line range */
+	init_vmlinux();
+	fd = open_vmlinux();
+	if (fd < 0)
+		die("Could not open debuginfo file.");
+	ret = find_line_range(fd, lr);
+	if (ret <= 0)
+		die("Source line is not found.\n");
+	close(fd);
+
+	setup_pager();
+
+	if (lr->function)
+		fprintf(stdout, "<%s:%d>\n", lr->function,
+			lr->start - lr->offset);
+	else
+		fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
+
+	fp = fopen(lr->path, "r");
+	if (fp == NULL)
+		die("Failed to open %s: %s", lr->path, strerror(errno));
+	/* Skip to starting line number */
+	while (l < lr->start)
+		show_one_line(fp, l++, true, false);
+
+	list_for_each_entry(ln, &lr->line_list, list) {
+		while (ln->line > l)
+			show_one_line(fp, (l++) - lr->offset, false, false);
+		show_one_line(fp, (l++) - lr->offset, false, true);
+	}
+
+	if (lr->end == INT_MAX)
+		lr->end = l + NR_ADDITIONAL_LINES;
+	while (l < lr->end && !feof(fp))
+		show_one_line(fp, (l++) - lr->offset, false, false);
+
+	fclose(fp);
+}
+
+#else	/* !DWARF_SUPPORT */
+
+static void convert_to_perf_probe_point(struct kprobe_trace_point *tp,
+					struct perf_probe_point *pp)
+{
+	pp->function = xstrdup(tp->symbol);
+	pp->offset = tp->offset;
+	pp->retprobe = tp->retprobe;
+}
+
+static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
+				struct kprobe_trace_event **tevs __unused)
+{
+	if (perf_probe_event_need_dwarf(pev))
+		die("Debuginfo-analysis is not supported");
+	return 0;
+}
+
+void show_line_range(struct line_range *lr __unused)
+{
+	die("Debuginfo-analysis is not supported");
+}
+
 #endif
 
 void parse_line_range_desc(const char *arg, struct line_range *lr)
@@ -592,32 +764,14 @@ void convert_to_perf_probe_event(struct kprobe_trace_event *tev,
 {
 	char buf[64];
 	int i;
-#ifndef NO_DWARF_SUPPORT
-	struct symbol *sym;
-	int fd, ret = 0;
-
-	sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
-				       tev->point.symbol, NULL);
-	if (sym) {
-		fd = open_vmlinux();
-		ret = find_perf_probe_point(fd, sym->start + tev->point.offset,
-					    &pev->point);
-		close(fd);
-	}
-	if (ret <= 0) {
-		pev->point.function = xstrdup(tev->point.symbol);
-		pev->point.offset = tev->point.offset;
-	}
-#else
-	/* Convert trace_point to probe_point */
-	pev->point.function = xstrdup(tev->point.symbol);
-	pev->point.offset = tev->point.offset;
-#endif
-	pev->point.retprobe = tev->point.retprobe;
 
+	/* Convert event/group name */
 	pev->event = xstrdup(tev->event);
 	pev->group = xstrdup(tev->group);
 
+	/* Convert trace_point to probe_point */
+	convert_to_perf_probe_point(&tev->point, &pev->point);
+
 	/* Convert trace_arg to probe_arg */
 	pev->nargs = tev->nargs;
 	pev->args = xzalloc(sizeof(struct perf_probe_arg) * pev->nargs);
@@ -944,52 +1098,13 @@ static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
 					  struct kprobe_trace_event **tevs)
 {
 	struct symbol *sym;
-	bool need_dwarf;
-#ifndef NO_DWARF_SUPPORT
-	int fd;
-#endif
 	int ntevs = 0, i;
 	struct kprobe_trace_event *tev;
 
-	need_dwarf = perf_probe_event_need_dwarf(pev);
-
-	if (need_dwarf)
-#ifdef NO_DWARF_SUPPORT
-		die("Debuginfo-analysis is not supported");
-#else	/* !NO_DWARF_SUPPORT */
-		pr_debug("Some probes require debuginfo.\n");
-
-	fd = open_vmlinux();
-	if (fd < 0) {
-		if (need_dwarf)
-			die("Could not open debuginfo file.");
-
-		pr_debug("Could not open vmlinux/module file."
-			 " Try to use symbols.\n");
-		goto end_dwarf;
-	}
-
-	/* Searching probe points */
-	ntevs = find_kprobe_trace_events(fd, pev, tevs);
-
-	if (ntevs > 0)	/* Found */
-		goto found;
-
-	if (ntevs == 0)	/* No error but failed to find probe point. */
-		die("Probe point '%s' not found. - probe not added.",
-		    synthesize_perf_probe_point(&pev->point));
-
-	/* Error path */
-	if (need_dwarf) {
-		if (ntevs == -ENOENT)
-			pr_warning("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO=y.\n");
-		die("Could not analyze debuginfo.");
-	}
-	pr_debug("An error occurred in debuginfo analysis."
-		 " Try to use symbols.\n");
-
-end_dwarf:
-#endif /* !NO_DWARF_SUPPORT */
+	/* Convert perf_probe_event with debuginfo */
+	ntevs = try_to_find_kprobe_trace_events(pev, tevs);
+	if (ntevs > 0)
+		return ntevs;
 
 	/* Allocate trace event buffer */
 	ntevs = 1;
@@ -1012,10 +1127,7 @@ end_dwarf:
 	if (!sym)
 		die("Kernel symbol \'%s\' not found - probe not added.",
 		    tev->point.symbol);
-#ifndef NO_DWARF_SUPPORT
-found:
-	close(fd);
-#endif
+
 	return ntevs;
 }
 
@@ -1133,90 +1245,3 @@ void del_perf_probe_events(struct strlist *dellist)
 	close(fd);
 }
 
-#define LINEBUF_SIZE 256
-#define NR_ADDITIONAL_LINES 2
-
-static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
-{
-	char buf[LINEBUF_SIZE];
-	const char *color = PERF_COLOR_BLUE;
-
-	if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
-		goto error;
-	if (!skip) {
-		if (show_num)
-			fprintf(stdout, "%7u  %s", l, buf);
-		else
-			color_fprintf(stdout, color, "         %s", buf);
-	}
-
-	while (strlen(buf) == LINEBUF_SIZE - 1 &&
-	       buf[LINEBUF_SIZE - 2] != '\n') {
-		if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
-			goto error;
-		if (!skip) {
-			if (show_num)
-				fprintf(stdout, "%s", buf);
-			else
-				color_fprintf(stdout, color, "%s", buf);
-		}
-	}
-	return;
-error:
-	if (feof(fp))
-		die("Source file is shorter than expected.");
-	else
-		die("File read error: %s", strerror(errno));
-}
-
-void show_line_range(struct line_range *lr)
-{
-	unsigned int l = 1;
-	struct line_node *ln;
-	FILE *fp;
-#ifndef NO_DWARF_SUPPORT
-	int fd, ret;
-#endif
-
-	/* Search a line range */
-	init_vmlinux();
-#ifndef NO_DWARF_SUPPORT
-	fd = open_vmlinux();
-	if (fd < 0)
-		die("Could not open debuginfo file.");
-	ret = find_line_range(fd, lr);
-	if (ret <= 0)
-		die("Source line is not found.\n");
-	close(fd);
-#endif
-
-	setup_pager();
-
-	if (lr->function)
-		fprintf(stdout, "<%s:%d>\n", lr->function,
-			lr->start - lr->offset);
-	else
-		fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
-
-	fp = fopen(lr->path, "r");
-	if (fp == NULL)
-		die("Failed to open %s: %s", lr->path, strerror(errno));
-	/* Skip to starting line number */
-	while (l < lr->start)
-		show_one_line(fp, l++, true, false);
-
-	list_for_each_entry(ln, &lr->line_list, list) {
-		while (ln->line > l)
-			show_one_line(fp, (l++) - lr->offset, false, false);
-		show_one_line(fp, (l++) - lr->offset, false, true);
-	}
-
-	if (lr->end == INT_MAX)
-		lr->end = l + NR_ADDITIONAL_LINES;
-	while (l < lr->end && !feof(fp))
-		show_one_line(fp, (l++) - lr->offset, false, false);
-
-	fclose(fp);
-}
-
-
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 2f2307d..3564f22 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -15,7 +15,7 @@ static inline int is_c_varname(const char *name)
 	return isalpha(name[0]) || name[0] == '_';
 }
 
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
 /* Find kprobe_trace_events specified by perf_probe_event from debuginfo */
 extern int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
 				    struct kprobe_trace_event **tevs);
@@ -57,6 +57,6 @@ struct line_finder {
 	int			found;
 };
 
-#endif /* NO_DWARF_SUPPORT */
+#endif /* DWARF_SUPPORT */
 
 #endif /*_PROBE_FINDER_H */

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [tip:perf/core] perf probe: Add NO_DWARF make option
  2010-03-22 16:10 ` [PATCH 3/5] perf probe: Add NO_DWARF make option Arnaldo Carvalho de Melo
@ 2010-03-22 18:55   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 7+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2010-03-22 18:55 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, paulus, acme, hpa, mingo, a.p.zijlstra, efault,
	fweisbec, tglx, mhiramat, mingo

Commit-ID:  ca721e45b39209415d2288dbac3667b26d9d1def
Gitweb:     http://git.kernel.org/tip/ca721e45b39209415d2288dbac3667b26d9d1def
Author:     Masami Hiramatsu <mhiramat@redhat.com>
AuthorDate: Mon, 22 Mar 2010 13:10:27 -0300
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Mon, 22 Mar 2010 18:47:35 +0100

perf probe: Add NO_DWARF make option

Add NO_DWARF make option for testing build without libdw.

Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1269274229-20442-3-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 tools/perf/Makefile |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index c991818..6903645 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -150,6 +150,8 @@ all::
 # Define LDFLAGS=-static to build a static binary.
 #
 # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
+#
+# Define NO_DWARF if you do not want debug-info analysis feature at all.
 
 PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
 	@$(SHELL_PATH) util/PERF-VERSION-GEN
@@ -507,10 +509,12 @@ endif
 ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
 	msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev);
 else
+ifndef NO_DWARF
 	BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT
 	EXTLIBS += -lelf -ldw
 	LIB_OBJS += util/probe-finder.o
 endif
+endif
 
 ifneq ($(shell sh -c "(echo '\#include <newt.h>'; echo 'int main(void) { newtInit(); newtCls(); return newtFinished(); }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -lnewt -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
 	msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-03-22 18:57 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-22 16:10 [PATCH 1/5] perf newt: Properly restore the screen when error exiting Arnaldo Carvalho de Melo
2010-03-22 16:10 ` [PATCH 2/5] perf probe: Cleanup debuginfo related code Arnaldo Carvalho de Melo
2010-03-22 18:55   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2010-03-22 16:10 ` [PATCH 3/5] perf probe: Add NO_DWARF make option Arnaldo Carvalho de Melo
2010-03-22 18:55   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2010-03-22 16:10 ` [PATCH 4/5] perf stat: Better report failure to collect system wide stats Arnaldo Carvalho de Melo
2010-03-22 16:10 ` [PATCH 5/5] perf tools: Exit browser before printing usage when unkown option passed Arnaldo Carvalho de Melo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®