* [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", ¶ms.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", ¶ms.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
* [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", ¶ms.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", ¶ms.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
* [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
* [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
* [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
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®