* [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines
@ 2009-06-12 22:11 Frederic Weisbecker
2009-06-12 22:11 ` [PATCH 2/2] perfcounters: print a sorted summary of annotated overhead lines Frederic Weisbecker
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Frederic Weisbecker @ 2009-06-12 22:11 UTC (permalink / raw)
To: Ingo Molnar
Cc: LKML, Peter Zijlstra, Mike Galbraith, Paul Mackerras,
Frederic Weisbecker
When we have a colored line in perf annotate, ie a middle/high
overhead one, it's sometimes useful to get the matching line
and filename from the source file, especially this path prepares
to another subsequent one which will print a sorted summary of
midle/high overhead lines in the beginning of the output.
Filename:Lines have the same color than the concerned ip lines.
It can be slow because it relies on addr2line. We could also
use objdump with -l but that implies we would have to bufferize
objdump output and parse it to filter the relevant lines since
we want to print a sorted summary in the beginning.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
tools/perf/builtin-annotate.c | 98 ++++++++++++++++++++++++++++++++++++++++-
tools/perf/util/symbol.h | 1 +
2 files changed, 98 insertions(+), 1 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index b1ed5f7..6a08da4 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -39,6 +39,8 @@ static int dump_trace = 0;
static int verbose;
+static int print_line;
+
static unsigned long page_size;
static unsigned long mmap_window = 32;
@@ -84,6 +86,12 @@ typedef union event_union {
struct period_event period;
} event_t;
+
+struct sym_ext {
+ double percent;
+ char *path;
+};
+
static LIST_HEAD(dsos);
static struct dso *kernel_dso;
static struct dso *vdso;
@@ -1034,6 +1042,8 @@ static int
parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
{
char *line = NULL, *tmp, *tmp2;
+ static const char *prev_line;
+ static const char *prev_color;
unsigned int offset;
size_t line_len;
__u64 line_ip;
@@ -1073,15 +1083,20 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
}
if (line_ip != -1) {
+ const char *path = NULL;
unsigned int hits = 0;
double percent = 0.0;
char *color = PERF_COLOR_NORMAL;
+ struct sym_ext *sym_ext = sym->priv;
offset = line_ip - start;
if (offset < len)
hits = sym->hist[offset];
- if (sym->hist_sum)
+ if (sym_ext) {
+ path = sym_ext[offset].path;
+ percent = sym_ext[offset].percent;
+ } else if (sym->hist_sum)
percent = 100.0 * hits / sym->hist_sum;
/*
@@ -1096,6 +1111,20 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
color = PERF_COLOR_GREEN;
}
+ /*
+ * Also color the filename and line if needed, with
+ * the same color than the percentage. Don't print it
+ * twice for close colored ip with the same filename:line
+ */
+ if (path) {
+ if (!prev_line || strcmp(prev_line, path)
+ || color != prev_color) {
+ color_fprintf(stdout, color, " %s", path);
+ prev_line = path;
+ prev_color = color;
+ }
+ }
+
color_fprintf(stdout, color, " %7.2f", percent);
printf(" : ");
color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", line);
@@ -1109,6 +1138,67 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
return 0;
}
+static void free_source_line(struct symbol *sym, int len)
+{
+ struct sym_ext *sym_ext = sym->priv;
+ int i;
+
+ if (!sym_ext)
+ return;
+
+ for (i = 0; i < len; i++)
+ free(sym_ext[i].path);
+ free(sym_ext);
+
+ sym->priv = NULL;
+}
+
+/* Get the filename:line for the colored entries */
+static void get_source_line(struct symbol *sym, __u64 start, int len)
+{
+ int i;
+ char cmd[PATH_MAX * 2];
+ struct sym_ext *sym_ext;
+
+ if (!sym->hist_sum)
+ return;
+
+ sym->priv = calloc(len, sizeof(struct sym_ext));
+ if (!sym->priv)
+ return;
+
+ sym_ext = sym->priv;
+
+ for (i = 0; i < len; i++) {
+ char *path = NULL;
+ size_t line_len;
+ __u64 offset;
+ FILE *fp;
+
+ sym_ext[i].percent = 100.0 * sym->hist[i] / sym->hist_sum;
+ if (sym_ext[i].percent <= 0.5)
+ continue;
+
+ offset = start + i;
+ sprintf(cmd, "addr2line -e %s %016llx", vmlinux, offset);
+ fp = popen(cmd, "r");
+ if (!fp)
+ continue;
+
+ if (getline(&path, &line_len, fp) < 0 || !line_len)
+ goto next;
+
+ sym_ext[i].path = malloc(sizeof(char) * line_len);
+ if (!sym_ext[i].path)
+ goto next;
+
+ strcpy(sym_ext[i].path, path);
+
+ next:
+ pclose(fp);
+ }
+}
+
static void annotate_sym(struct dso *dso, struct symbol *sym)
{
char *filename = dso->name;
@@ -1135,6 +1225,9 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
end = start + sym->end - sym->start + 1;
len = sym->end - sym->start;
+ if (print_line)
+ get_source_line(sym, start, len);
+
sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", (__u64)start, (__u64)end, filename);
if (verbose >= 3)
@@ -1150,6 +1243,7 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
}
pclose(file);
+ free_source_line(sym, len);
}
static void find_annotations(void)
@@ -1308,6 +1402,8 @@ static const struct option options[] = {
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"),
OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
+ OPT_BOOLEAN('l', "print-line", &print_line,
+ "print matching source lines (may be slow)"),
OPT_END()
};
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 0d1292b..5ad9b06 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -12,6 +12,7 @@ struct symbol {
__u64 obj_start;
__u64 hist_sum;
__u64 *hist;
+ void *priv;
char name[0];
};
--
1.6.2.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] perfcounters: print a sorted summary of annotated overhead lines
2009-06-12 22:11 [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines Frederic Weisbecker
@ 2009-06-12 22:11 ` Frederic Weisbecker
2009-06-13 11:02 ` Ingo Molnar
2009-06-13 14:48 ` [tip:perfcounters/core] perf annotate: Print " tip-bot for Frederic Weisbecker
2009-06-13 11:12 ` [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines Ingo Molnar
2009-06-13 14:48 ` [tip:perfcounters/core] perf annotate: " tip-bot for Frederic Weisbecker
2 siblings, 2 replies; 9+ messages in thread
From: Frederic Weisbecker @ 2009-06-12 22:11 UTC (permalink / raw)
To: Ingo Molnar
Cc: LKML, Peter Zijlstra, Mike Galbraith, Paul Mackerras,
Frederic Weisbecker
It's can be very annoying to scroll down perf annotated output
until we find relevant overhead.
Using the -l option, you can now have a small summary sorted per
overhead in the beginning of the output.
Example:
./perf annotate -l -k ../../vmlinux -s __lock_acquire
Sorted summary for file ../../vmlinux
----------------------------------------------
12.04 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
4.61 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1740
3.77 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1775
3.56 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
2.93 /home/fweisbec/linux/linux-2.6-tip/arch/x86/include/asm/irqflags.h:15
2.83 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2545
2.30 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2594
2.20 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2388
2.20 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
2.09 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
2.09 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:138
1.88 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2548
1.47 /home/fweisbec/linux/linux-2.6-tip/arch/x86/include/asm/irqflags.h:15
1.36 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2594
1.36 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
1.26 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1654
1.26 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
1.15 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2592
1.15 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1740
1.15 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1740
[...]
Only overhead over 0.5% are summarized.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
tools/perf/builtin-annotate.c | 111 +++++++++++++++++++++++++++++++++--------
1 files changed, 90 insertions(+), 21 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 6a08da4..7a5b278 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -25,6 +25,10 @@
#define SHOW_USER 2
#define SHOW_HV 4
+#define MIN_GREEN 0.5
+#define MIN_RED 5.0
+
+
static char const *input_name = "perf.data";
static char *vmlinux = "vmlinux";
@@ -88,6 +92,7 @@ typedef union event_union {
struct sym_ext {
+ struct rb_node node;
double percent;
char *path;
};
@@ -1038,6 +1043,24 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
return 0;
}
+static char *get_color(double percent)
+{
+ char *color = PERF_COLOR_NORMAL;
+
+ /*
+ * We color high-overhead entries in red, mid-overhead
+ * entries in green - and keep the low overhead places
+ * normal:
+ */
+ if (percent >= MIN_RED)
+ color = PERF_COLOR_RED;
+ else {
+ if (percent > MIN_GREEN)
+ color = PERF_COLOR_GREEN;
+ }
+ return color;
+}
+
static int
parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
{
@@ -1086,7 +1109,7 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
const char *path = NULL;
unsigned int hits = 0;
double percent = 0.0;
- char *color = PERF_COLOR_NORMAL;
+ char *color;
struct sym_ext *sym_ext = sym->priv;
offset = line_ip - start;
@@ -1099,17 +1122,7 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
} else if (sym->hist_sum)
percent = 100.0 * hits / sym->hist_sum;
- /*
- * We color high-overhead entries in red, mid-overhead
- * entries in green - and keep the low overhead places
- * normal:
- */
- if (percent >= 5.0)
- color = PERF_COLOR_RED;
- else {
- if (percent > 0.5)
- color = PERF_COLOR_GREEN;
- }
+ color = get_color(percent);
/*
* Also color the filename and line if needed, with
@@ -1138,6 +1151,28 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
return 0;
}
+static struct rb_root root_sym_ext;
+
+static void insert_source_line(struct sym_ext *sym_ext)
+{
+ struct sym_ext *iter;
+ struct rb_node **p = &root_sym_ext.rb_node;
+ struct rb_node *parent = NULL;
+
+ while (*p != NULL) {
+ parent = *p;
+ iter = rb_entry(parent, struct sym_ext, node);
+
+ if (sym_ext->percent > iter->percent)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&sym_ext->node, parent, p);
+ rb_insert_color(&sym_ext->node, &root_sym_ext);
+}
+
static void free_source_line(struct symbol *sym, int len)
{
struct sym_ext *sym_ext = sym->priv;
@@ -1151,6 +1186,7 @@ static void free_source_line(struct symbol *sym, int len)
free(sym_ext);
sym->priv = NULL;
+ root_sym_ext = RB_ROOT;
}
/* Get the filename:line for the colored entries */
@@ -1193,12 +1229,42 @@ static void get_source_line(struct symbol *sym, __u64 start, int len)
goto next;
strcpy(sym_ext[i].path, path);
+ insert_source_line(&sym_ext[i]);
next:
pclose(fp);
}
}
+static void print_summary(char *filename)
+{
+ struct sym_ext *sym_ext;
+ struct rb_node *node;
+
+ printf("\nSorted summary for file %s\n", filename);
+ printf("----------------------------------------------\n\n");
+
+ if (RB_EMPTY_ROOT(&root_sym_ext)) {
+ printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
+ return;
+ }
+
+ node = rb_first(&root_sym_ext);
+ while (node) {
+ double percent;
+ char *color;
+ char *path;
+
+ sym_ext = rb_entry(node, struct sym_ext, node);
+ percent = sym_ext->percent;
+ color = get_color(percent);
+ path = sym_ext->path;
+
+ color_fprintf(stdout, color, " %7.2f %s", percent, path);
+ node = rb_next(node);
+ }
+}
+
static void annotate_sym(struct dso *dso, struct symbol *sym)
{
char *filename = dso->name;
@@ -1211,13 +1277,6 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
if (dso == kernel_dso)
filename = vmlinux;
- printf("\n------------------------------------------------\n");
- printf(" Percent | Source code & Disassembly of %s\n", filename);
- printf("------------------------------------------------\n");
-
- if (verbose >= 2)
- printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
-
start = sym->obj_start;
if (!start)
start = sym->start;
@@ -1225,8 +1284,17 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
end = start + sym->end - sym->start + 1;
len = sym->end - sym->start;
- if (print_line)
+ if (print_line) {
get_source_line(sym, start, len);
+ print_summary(filename);
+ }
+
+ printf("\n\n------------------------------------------------\n");
+ printf(" Percent | Source code & Disassembly of %s\n", filename);
+ printf("------------------------------------------------\n");
+
+ if (verbose >= 2)
+ printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", (__u64)start, (__u64)end, filename);
@@ -1243,7 +1311,8 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
}
pclose(file);
- free_source_line(sym, len);
+ if (print_line)
+ free_source_line(sym, len);
}
static void find_annotations(void)
--
1.6.2.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] perfcounters: print a sorted summary of annotated overhead lines
2009-06-12 22:11 ` [PATCH 2/2] perfcounters: print a sorted summary of annotated overhead lines Frederic Weisbecker
@ 2009-06-13 11:02 ` Ingo Molnar
2009-06-13 14:48 ` [tip:perfcounters/core] perf annotate: Print " tip-bot for Frederic Weisbecker
1 sibling, 0 replies; 9+ messages in thread
From: Ingo Molnar @ 2009-06-13 11:02 UTC (permalink / raw)
To: Frederic Weisbecker; +Cc: LKML, Peter Zijlstra, Mike Galbraith, Paul Mackerras
* Frederic Weisbecker <fweisbec@gmail.com> wrote:
> It's can be very annoying to scroll down perf annotated output
> until we find relevant overhead.
>
> Using the -l option, you can now have a small summary sorted per
> overhead in the beginning of the output.
>
> Example:
>
> ./perf annotate -l -k ../../vmlinux -s __lock_acquire
>
> Sorted summary for file ../../vmlinux
> ----------------------------------------------
>
> 12.04 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
> 4.61 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1740
> 3.77 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1775
> 3.56 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
> 2.93 /home/fweisbec/linux/linux-2.6-tip/arch/x86/include/asm/irqflags.h:15
> 2.83 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2545
> 2.30 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2594
> 2.20 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2388
> 2.20 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
> 2.09 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
> 2.09 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:138
> 1.88 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2548
> 1.47 /home/fweisbec/linux/linux-2.6-tip/arch/x86/include/asm/irqflags.h:15
> 1.36 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2594
> 1.36 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
> 1.26 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1654
> 1.26 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
Nice!
I'm wondering how hard it would be to add wildcard support to the
symbol matching, say:
perf annotate "sys_*" # Annotate all syscalls
perf annotate "sched*" # All scheduler functions
perf annotate "*" # All symbols we know about
It would be slower, obviously - but pretty useful as well.
Also, perhaps an 'annotate top 10 overhead functions':
perf annotate --top 10
Would be popular too ...
Ingo
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines
2009-06-12 22:11 [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines Frederic Weisbecker
2009-06-12 22:11 ` [PATCH 2/2] perfcounters: print a sorted summary of annotated overhead lines Frederic Weisbecker
@ 2009-06-13 11:12 ` Ingo Molnar
2009-06-13 12:35 ` Frederic Weisbecker
2009-06-13 14:48 ` [tip:perfcounters/core] perf annotate: " tip-bot for Frederic Weisbecker
2 siblings, 1 reply; 9+ messages in thread
From: Ingo Molnar @ 2009-06-13 11:12 UTC (permalink / raw)
To: Frederic Weisbecker; +Cc: LKML, Peter Zijlstra, Mike Galbraith, Paul Mackerras
hm, -l doesnt work so well if a user-space binary (in this case the
'git' binary of the Git project) is profiled:
aldebaran:~/git> perf record -f ./git gc
Counting objects: 1148, done.
Delta compression using up to 16 threads.
Compressing objects: 100% (450/450), done.
Writing objects: 100% (1148/1148), done.
Total 1148 (delta 690), reused 1148 (delta 690)
[ perf record: Captured and wrote 1.649 MB perf.data (~72032 samples) ]
aldebaran:~/git> perf annotate -l lookup_object
addr2line: 'vmlinux': No such file
addr2line: 'vmlinux': No such file
addr2line: 'vmlinux': No such file
addr2line: 'vmlinux': No such file
addr2line: 'vmlinux': No such file
addr2line: 'vmlinux': No such file
addr2line: 'vmlinux': No such file
addr2line: 'vmlinux': No such file
addr2line: 'vmlinux': No such file
addr2line: 'vmlinux': No such file
addr2line: 'vmlinux': No such file
addr2line: 'vmlinux': No such file
------------------------------------------------
Percent | Source code & Disassembly of /home/mingo/git/git-update-server-info
------------------------------------------------
:
: /home/mingo/git/git-update-server-info: file format elf64-x86-64
:
:
: Disassembly of section .text:
:
: 00000000004160f0 <lookup_object>:
: memcpy(&i, sha1, sizeof(unsigned int));
: return (int)(i % obj_hash_size);
: }
Ingo
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines
2009-06-13 11:12 ` [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines Ingo Molnar
@ 2009-06-13 12:35 ` Frederic Weisbecker
0 siblings, 0 replies; 9+ messages in thread
From: Frederic Weisbecker @ 2009-06-13 12:35 UTC (permalink / raw)
To: Ingo Molnar; +Cc: LKML, Peter Zijlstra, Mike Galbraith, Paul Mackerras
On Sat, Jun 13, 2009 at 01:12:48PM +0200, Ingo Molnar wrote:
>
> hm, -l doesnt work so well if a user-space binary (in this case the
> 'git' binary of the Git project) is profiled:
Oops, sorry. Would you prefer the fix as a delta or..?
Thanks,
Frederic.
>
> aldebaran:~/git> perf record -f ./git gc
> Counting objects: 1148, done.
> Delta compression using up to 16 threads.
> Compressing objects: 100% (450/450), done.
> Writing objects: 100% (1148/1148), done.
> Total 1148 (delta 690), reused 1148 (delta 690)
> [ perf record: Captured and wrote 1.649 MB perf.data (~72032 samples) ]
>
> aldebaran:~/git> perf annotate -l lookup_object
>
> addr2line: 'vmlinux': No such file
> addr2line: 'vmlinux': No such file
> addr2line: 'vmlinux': No such file
> addr2line: 'vmlinux': No such file
> addr2line: 'vmlinux': No such file
> addr2line: 'vmlinux': No such file
> addr2line: 'vmlinux': No such file
> addr2line: 'vmlinux': No such file
> addr2line: 'vmlinux': No such file
> addr2line: 'vmlinux': No such file
> addr2line: 'vmlinux': No such file
> addr2line: 'vmlinux': No such file
>
> ------------------------------------------------
> Percent | Source code & Disassembly of /home/mingo/git/git-update-server-info
> ------------------------------------------------
> :
> : /home/mingo/git/git-update-server-info: file format elf64-x86-64
> :
> :
> : Disassembly of section .text:
> :
> : 00000000004160f0 <lookup_object>:
> : memcpy(&i, sha1, sizeof(unsigned int));
> : return (int)(i % obj_hash_size);
> : }
>
> Ingo
^ permalink raw reply [flat|nested] 9+ messages in thread
* [tip:perfcounters/core] perf annotate: Print the filename:line for annotated colored lines
2009-06-12 22:11 [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines Frederic Weisbecker
2009-06-12 22:11 ` [PATCH 2/2] perfcounters: print a sorted summary of annotated overhead lines Frederic Weisbecker
2009-06-13 11:12 ` [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines Ingo Molnar
@ 2009-06-13 14:48 ` tip-bot for Frederic Weisbecker
2 siblings, 0 replies; 9+ messages in thread
From: tip-bot for Frederic Weisbecker @ 2009-06-13 14:48 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, paulus, hpa, mingo, a.p.zijlstra, efault, fweisbec,
tglx, mingo
Commit-ID: 301406b9c69e4914cf45ae9d5f929e7bcf0d93cd
Gitweb: http://git.kernel.org/tip/301406b9c69e4914cf45ae9d5f929e7bcf0d93cd
Author: Frederic Weisbecker <fweisbec@gmail.com>
AuthorDate: Sat, 13 Jun 2009 00:11:21 +0200
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Sat, 13 Jun 2009 12:58:23 +0200
perf annotate: Print the filename:line for annotated colored lines
When we have a colored line in perf annotate, ie a middle/high
overhead one, it's sometimes useful to get the matching line
and filename from the source file, especially this path prepares
to another subsequent one which will print a sorted summary of
midle/high overhead lines in the beginning of the output.
Filename:Lines have the same color than the concerned ip lines.
It can be slow because it relies on addr2line. We could also
use objdump with -l but that implies we would have to bufferize
objdump output and parse it to filter the relevant lines since
we want to print a sorted summary in the beginning.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1244844682-12928-1-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
tools/perf/builtin-annotate.c | 98 ++++++++++++++++++++++++++++++++++++++++-
tools/perf/util/symbol.h | 1 +
2 files changed, 98 insertions(+), 1 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index b1ed5f7..6a08da4 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -39,6 +39,8 @@ static int dump_trace = 0;
static int verbose;
+static int print_line;
+
static unsigned long page_size;
static unsigned long mmap_window = 32;
@@ -84,6 +86,12 @@ typedef union event_union {
struct period_event period;
} event_t;
+
+struct sym_ext {
+ double percent;
+ char *path;
+};
+
static LIST_HEAD(dsos);
static struct dso *kernel_dso;
static struct dso *vdso;
@@ -1034,6 +1042,8 @@ static int
parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
{
char *line = NULL, *tmp, *tmp2;
+ static const char *prev_line;
+ static const char *prev_color;
unsigned int offset;
size_t line_len;
__u64 line_ip;
@@ -1073,15 +1083,20 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
}
if (line_ip != -1) {
+ const char *path = NULL;
unsigned int hits = 0;
double percent = 0.0;
char *color = PERF_COLOR_NORMAL;
+ struct sym_ext *sym_ext = sym->priv;
offset = line_ip - start;
if (offset < len)
hits = sym->hist[offset];
- if (sym->hist_sum)
+ if (sym_ext) {
+ path = sym_ext[offset].path;
+ percent = sym_ext[offset].percent;
+ } else if (sym->hist_sum)
percent = 100.0 * hits / sym->hist_sum;
/*
@@ -1096,6 +1111,20 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
color = PERF_COLOR_GREEN;
}
+ /*
+ * Also color the filename and line if needed, with
+ * the same color than the percentage. Don't print it
+ * twice for close colored ip with the same filename:line
+ */
+ if (path) {
+ if (!prev_line || strcmp(prev_line, path)
+ || color != prev_color) {
+ color_fprintf(stdout, color, " %s", path);
+ prev_line = path;
+ prev_color = color;
+ }
+ }
+
color_fprintf(stdout, color, " %7.2f", percent);
printf(" : ");
color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", line);
@@ -1109,6 +1138,67 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
return 0;
}
+static void free_source_line(struct symbol *sym, int len)
+{
+ struct sym_ext *sym_ext = sym->priv;
+ int i;
+
+ if (!sym_ext)
+ return;
+
+ for (i = 0; i < len; i++)
+ free(sym_ext[i].path);
+ free(sym_ext);
+
+ sym->priv = NULL;
+}
+
+/* Get the filename:line for the colored entries */
+static void get_source_line(struct symbol *sym, __u64 start, int len)
+{
+ int i;
+ char cmd[PATH_MAX * 2];
+ struct sym_ext *sym_ext;
+
+ if (!sym->hist_sum)
+ return;
+
+ sym->priv = calloc(len, sizeof(struct sym_ext));
+ if (!sym->priv)
+ return;
+
+ sym_ext = sym->priv;
+
+ for (i = 0; i < len; i++) {
+ char *path = NULL;
+ size_t line_len;
+ __u64 offset;
+ FILE *fp;
+
+ sym_ext[i].percent = 100.0 * sym->hist[i] / sym->hist_sum;
+ if (sym_ext[i].percent <= 0.5)
+ continue;
+
+ offset = start + i;
+ sprintf(cmd, "addr2line -e %s %016llx", vmlinux, offset);
+ fp = popen(cmd, "r");
+ if (!fp)
+ continue;
+
+ if (getline(&path, &line_len, fp) < 0 || !line_len)
+ goto next;
+
+ sym_ext[i].path = malloc(sizeof(char) * line_len);
+ if (!sym_ext[i].path)
+ goto next;
+
+ strcpy(sym_ext[i].path, path);
+
+ next:
+ pclose(fp);
+ }
+}
+
static void annotate_sym(struct dso *dso, struct symbol *sym)
{
char *filename = dso->name;
@@ -1135,6 +1225,9 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
end = start + sym->end - sym->start + 1;
len = sym->end - sym->start;
+ if (print_line)
+ get_source_line(sym, start, len);
+
sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", (__u64)start, (__u64)end, filename);
if (verbose >= 3)
@@ -1150,6 +1243,7 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
}
pclose(file);
+ free_source_line(sym, len);
}
static void find_annotations(void)
@@ -1308,6 +1402,8 @@ static const struct option options[] = {
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"),
OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
+ OPT_BOOLEAN('l', "print-line", &print_line,
+ "print matching source lines (may be slow)"),
OPT_END()
};
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 0d1292b..5ad9b06 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -12,6 +12,7 @@ struct symbol {
__u64 obj_start;
__u64 hist_sum;
__u64 *hist;
+ void *priv;
char name[0];
};
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [tip:perfcounters/core] perf annotate: Print a sorted summary of annotated overhead lines
2009-06-12 22:11 ` [PATCH 2/2] perfcounters: print a sorted summary of annotated overhead lines Frederic Weisbecker
2009-06-13 11:02 ` Ingo Molnar
@ 2009-06-13 14:48 ` tip-bot for Frederic Weisbecker
1 sibling, 0 replies; 9+ messages in thread
From: tip-bot for Frederic Weisbecker @ 2009-06-13 14:48 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, paulus, hpa, mingo, a.p.zijlstra, efault, fweisbec,
tglx, mingo
Commit-ID: 971738f3669092dd247eaf89658f2685180492a0
Gitweb: http://git.kernel.org/tip/971738f3669092dd247eaf89658f2685180492a0
Author: Frederic Weisbecker <fweisbec@gmail.com>
AuthorDate: Sat, 13 Jun 2009 00:11:22 +0200
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Sat, 13 Jun 2009 12:58:23 +0200
perf annotate: Print a sorted summary of annotated overhead lines
It's can be very annoying to scroll down perf annotated output
until we find relevant overhead.
Using the -l option, you can now have a small summary sorted per
overhead in the beginning of the output.
Example:
./perf annotate -l -k ../../vmlinux -s __lock_acquire
Sorted summary for file ../../vmlinux
----------------------------------------------
12.04 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
4.61 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1740
3.77 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1775
3.56 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
2.93 /home/fweisbec/linux/linux-2.6-tip/arch/x86/include/asm/irqflags.h:15
2.83 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2545
2.30 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2594
2.20 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2388
2.20 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
2.09 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
2.09 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:138
1.88 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2548
1.47 /home/fweisbec/linux/linux-2.6-tip/arch/x86/include/asm/irqflags.h:15
1.36 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2594
1.36 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
1.26 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1654
1.26 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
1.15 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2592
1.15 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1740
1.15 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1740
[...]
Only overhead over 0.5% are summarized.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1244844682-12928-2-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
tools/perf/builtin-annotate.c | 111 +++++++++++++++++++++++++++++++++--------
1 files changed, 90 insertions(+), 21 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 6a08da4..7a5b278 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -25,6 +25,10 @@
#define SHOW_USER 2
#define SHOW_HV 4
+#define MIN_GREEN 0.5
+#define MIN_RED 5.0
+
+
static char const *input_name = "perf.data";
static char *vmlinux = "vmlinux";
@@ -88,6 +92,7 @@ typedef union event_union {
struct sym_ext {
+ struct rb_node node;
double percent;
char *path;
};
@@ -1038,6 +1043,24 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
return 0;
}
+static char *get_color(double percent)
+{
+ char *color = PERF_COLOR_NORMAL;
+
+ /*
+ * We color high-overhead entries in red, mid-overhead
+ * entries in green - and keep the low overhead places
+ * normal:
+ */
+ if (percent >= MIN_RED)
+ color = PERF_COLOR_RED;
+ else {
+ if (percent > MIN_GREEN)
+ color = PERF_COLOR_GREEN;
+ }
+ return color;
+}
+
static int
parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
{
@@ -1086,7 +1109,7 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
const char *path = NULL;
unsigned int hits = 0;
double percent = 0.0;
- char *color = PERF_COLOR_NORMAL;
+ char *color;
struct sym_ext *sym_ext = sym->priv;
offset = line_ip - start;
@@ -1099,17 +1122,7 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
} else if (sym->hist_sum)
percent = 100.0 * hits / sym->hist_sum;
- /*
- * We color high-overhead entries in red, mid-overhead
- * entries in green - and keep the low overhead places
- * normal:
- */
- if (percent >= 5.0)
- color = PERF_COLOR_RED;
- else {
- if (percent > 0.5)
- color = PERF_COLOR_GREEN;
- }
+ color = get_color(percent);
/*
* Also color the filename and line if needed, with
@@ -1138,6 +1151,28 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
return 0;
}
+static struct rb_root root_sym_ext;
+
+static void insert_source_line(struct sym_ext *sym_ext)
+{
+ struct sym_ext *iter;
+ struct rb_node **p = &root_sym_ext.rb_node;
+ struct rb_node *parent = NULL;
+
+ while (*p != NULL) {
+ parent = *p;
+ iter = rb_entry(parent, struct sym_ext, node);
+
+ if (sym_ext->percent > iter->percent)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&sym_ext->node, parent, p);
+ rb_insert_color(&sym_ext->node, &root_sym_ext);
+}
+
static void free_source_line(struct symbol *sym, int len)
{
struct sym_ext *sym_ext = sym->priv;
@@ -1151,6 +1186,7 @@ static void free_source_line(struct symbol *sym, int len)
free(sym_ext);
sym->priv = NULL;
+ root_sym_ext = RB_ROOT;
}
/* Get the filename:line for the colored entries */
@@ -1193,12 +1229,42 @@ static void get_source_line(struct symbol *sym, __u64 start, int len)
goto next;
strcpy(sym_ext[i].path, path);
+ insert_source_line(&sym_ext[i]);
next:
pclose(fp);
}
}
+static void print_summary(char *filename)
+{
+ struct sym_ext *sym_ext;
+ struct rb_node *node;
+
+ printf("\nSorted summary for file %s\n", filename);
+ printf("----------------------------------------------\n\n");
+
+ if (RB_EMPTY_ROOT(&root_sym_ext)) {
+ printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
+ return;
+ }
+
+ node = rb_first(&root_sym_ext);
+ while (node) {
+ double percent;
+ char *color;
+ char *path;
+
+ sym_ext = rb_entry(node, struct sym_ext, node);
+ percent = sym_ext->percent;
+ color = get_color(percent);
+ path = sym_ext->path;
+
+ color_fprintf(stdout, color, " %7.2f %s", percent, path);
+ node = rb_next(node);
+ }
+}
+
static void annotate_sym(struct dso *dso, struct symbol *sym)
{
char *filename = dso->name;
@@ -1211,13 +1277,6 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
if (dso == kernel_dso)
filename = vmlinux;
- printf("\n------------------------------------------------\n");
- printf(" Percent | Source code & Disassembly of %s\n", filename);
- printf("------------------------------------------------\n");
-
- if (verbose >= 2)
- printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
-
start = sym->obj_start;
if (!start)
start = sym->start;
@@ -1225,8 +1284,17 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
end = start + sym->end - sym->start + 1;
len = sym->end - sym->start;
- if (print_line)
+ if (print_line) {
get_source_line(sym, start, len);
+ print_summary(filename);
+ }
+
+ printf("\n\n------------------------------------------------\n");
+ printf(" Percent | Source code & Disassembly of %s\n", filename);
+ printf("------------------------------------------------\n");
+
+ if (verbose >= 2)
+ printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", (__u64)start, (__u64)end, filename);
@@ -1243,7 +1311,8 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
}
pclose(file);
- free_source_line(sym, len);
+ if (print_line)
+ free_source_line(sym, len);
}
static void find_annotations(void)
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines
2009-06-13 15:25 [PATCH 1/2] perfcounters: " Frederic Weisbecker
@ 2009-06-13 15:26 ` Frederic Weisbecker
0 siblings, 0 replies; 9+ messages in thread
From: Frederic Weisbecker @ 2009-06-13 15:26 UTC (permalink / raw)
To: Ingo Molnar; +Cc: LKML, Peter Zijlstra, Mike Galbraith, Paul Mackerras
On Sat, Jun 13, 2009 at 05:25:31PM +0200, Frederic Weisbecker wrote:
> When we have a colored line in perf annotate, ie a middle/high
> overhead one, it's sometimes useful to get the matching line
> and filename from the source file, especially this path prepares
> to another subsequent one which will print a sorted summary of
> midle/high overhead lines in the beginning of the output.
>
> Filename:Lines have the same color than the concerned ip lines.
>
> It can be slow because it relies on addr2line. We could also
> use objdump with -l but that implies we would have to bufferize
> objdump output and parse it to filter the relevant lines since
> we want to print a sorted summary in the beginning.
>
> Changes in v2:
> - fix addr2line on userspace binary
> - fix string allocation size (missing ending null char room)
> - fix overflow in symbol extra info
>
> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Forgot to put "v2" in the [PATCH] token. It fixes what you reported
Ingo, and also some other things.
Thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines
@ 2009-06-13 15:25 Frederic Weisbecker
2009-06-13 15:26 ` Frederic Weisbecker
0 siblings, 1 reply; 9+ messages in thread
From: Frederic Weisbecker @ 2009-06-13 15:25 UTC (permalink / raw)
To: Ingo Molnar
Cc: LKML, Peter Zijlstra, Mike Galbraith, Paul Mackerras,
Frederic Weisbecker
When we have a colored line in perf annotate, ie a middle/high
overhead one, it's sometimes useful to get the matching line
and filename from the source file, especially this path prepares
to another subsequent one which will print a sorted summary of
midle/high overhead lines in the beginning of the output.
Filename:Lines have the same color than the concerned ip lines.
It can be slow because it relies on addr2line. We could also
use objdump with -l but that implies we would have to bufferize
objdump output and parse it to filter the relevant lines since
we want to print a sorted summary in the beginning.
Changes in v2:
- fix addr2line on userspace binary
- fix string allocation size (missing ending null char room)
- fix overflow in symbol extra info
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
tools/perf/builtin-annotate.c | 99 ++++++++++++++++++++++++++++++++++++++++-
tools/perf/util/symbol.h | 1 +
2 files changed, 99 insertions(+), 1 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index b1ed5f7..15192a3 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -39,6 +39,8 @@ static int dump_trace = 0;
static int verbose;
+static int print_line;
+
static unsigned long page_size;
static unsigned long mmap_window = 32;
@@ -84,6 +86,12 @@ typedef union event_union {
struct period_event period;
} event_t;
+
+struct sym_ext {
+ double percent;
+ char *path;
+};
+
static LIST_HEAD(dsos);
static struct dso *kernel_dso;
static struct dso *vdso;
@@ -1034,6 +1042,8 @@ static int
parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
{
char *line = NULL, *tmp, *tmp2;
+ static const char *prev_line;
+ static const char *prev_color;
unsigned int offset;
size_t line_len;
__u64 line_ip;
@@ -1073,15 +1083,20 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
}
if (line_ip != -1) {
+ const char *path = NULL;
unsigned int hits = 0;
double percent = 0.0;
char *color = PERF_COLOR_NORMAL;
+ struct sym_ext *sym_ext = sym->priv;
offset = line_ip - start;
if (offset < len)
hits = sym->hist[offset];
- if (sym->hist_sum)
+ if (offset < len && sym_ext) {
+ path = sym_ext[offset].path;
+ percent = sym_ext[offset].percent;
+ } else if (sym->hist_sum)
percent = 100.0 * hits / sym->hist_sum;
/*
@@ -1096,6 +1111,20 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
color = PERF_COLOR_GREEN;
}
+ /*
+ * Also color the filename and line if needed, with
+ * the same color than the percentage. Don't print it
+ * twice for close colored ip with the same filename:line
+ */
+ if (path) {
+ if (!prev_line || strcmp(prev_line, path)
+ || color != prev_color) {
+ color_fprintf(stdout, color, " %s", path);
+ prev_line = path;
+ prev_color = color;
+ }
+ }
+
color_fprintf(stdout, color, " %7.2f", percent);
printf(" : ");
color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", line);
@@ -1109,6 +1138,68 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
return 0;
}
+static void free_source_line(struct symbol *sym, int len)
+{
+ struct sym_ext *sym_ext = sym->priv;
+ int i;
+
+ if (!sym_ext)
+ return;
+
+ for (i = 0; i < len; i++)
+ free(sym_ext[i].path);
+ free(sym_ext);
+
+ sym->priv = NULL;
+}
+
+/* Get the filename:line for the colored entries */
+static void
+get_source_line(struct symbol *sym, __u64 start, int len, char *filename)
+{
+ int i;
+ char cmd[PATH_MAX * 2];
+ struct sym_ext *sym_ext;
+
+ if (!sym->hist_sum)
+ return;
+
+ sym->priv = calloc(len, sizeof(struct sym_ext));
+ if (!sym->priv)
+ return;
+
+ sym_ext = sym->priv;
+
+ for (i = 0; i < len; i++) {
+ char *path = NULL;
+ size_t line_len;
+ __u64 offset;
+ FILE *fp;
+
+ sym_ext[i].percent = 100.0 * sym->hist[i] / sym->hist_sum;
+ if (sym_ext[i].percent <= 0.5)
+ continue;
+
+ offset = start + i;
+ sprintf(cmd, "addr2line -e %s %016llx", filename, offset);
+ fp = popen(cmd, "r");
+ if (!fp)
+ continue;
+
+ if (getline(&path, &line_len, fp) < 0 || !line_len)
+ goto next;
+
+ sym_ext[i].path = malloc(sizeof(char) * line_len + 1);
+ if (!sym_ext[i].path)
+ goto next;
+
+ strcpy(sym_ext[i].path, path);
+
+ next:
+ pclose(fp);
+ }
+}
+
static void annotate_sym(struct dso *dso, struct symbol *sym)
{
char *filename = dso->name;
@@ -1135,6 +1226,9 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
end = start + sym->end - sym->start + 1;
len = sym->end - sym->start;
+ if (print_line)
+ get_source_line(sym, start, len, filename);
+
sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", (__u64)start, (__u64)end, filename);
if (verbose >= 3)
@@ -1150,6 +1244,7 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
}
pclose(file);
+ free_source_line(sym, len);
}
static void find_annotations(void)
@@ -1308,6 +1403,8 @@ static const struct option options[] = {
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"),
OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
+ OPT_BOOLEAN('l', "print-line", &print_line,
+ "print matching source lines (may be slow)"),
OPT_END()
};
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 0d1292b..5ad9b06 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -12,6 +12,7 @@ struct symbol {
__u64 obj_start;
__u64 hist_sum;
__u64 *hist;
+ void *priv;
char name[0];
};
--
1.6.2.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2009-06-13 15:26 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-12 22:11 [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines Frederic Weisbecker
2009-06-12 22:11 ` [PATCH 2/2] perfcounters: print a sorted summary of annotated overhead lines Frederic Weisbecker
2009-06-13 11:02 ` Ingo Molnar
2009-06-13 14:48 ` [tip:perfcounters/core] perf annotate: Print " tip-bot for Frederic Weisbecker
2009-06-13 11:12 ` [PATCH 1/2] perfcounters: Print the filename:line for annotated colored lines Ingo Molnar
2009-06-13 12:35 ` Frederic Weisbecker
2009-06-13 14:48 ` [tip:perfcounters/core] perf annotate: " tip-bot for Frederic Weisbecker
2009-06-13 15:25 [PATCH 1/2] perfcounters: " Frederic Weisbecker
2009-06-13 15:26 ` Frederic Weisbecker
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).