diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-26 12:26:02 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-26 12:26:02 -0400 |
commit | 5ad90e4ea4a096af9f0a362e34dfae5686a191ef (patch) | |
tree | f537aae3fd9e04395658c19cc97a401431c972fa | |
parent | 62e3436b5f3461662929eae102beefbd12127cb1 (diff) |
perf symbols: Add the build id cache to the vmlinux path
So that if the kernel DSO has a build id because record inserted it in
the perf.data build id table in the header, or a BUILD_ID event was
inserted in the stream, we first look at the build id cache
($HOME/.debug/).
If we find it there, try to use it, allowing offline annotation in
addition to 'perf report'.
Reported-by: Stephane Eranian <eranian@google.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/builtin-top.c | 2 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 27 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 2 |
3 files changed, 25 insertions, 6 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 397290a0a76e..a66f4272b994 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -1060,7 +1060,7 @@ static void event__process_sample(const event_t *self, | |||
1060 | pr_err("Can't annotate %s", sym->name); | 1060 | pr_err("Can't annotate %s", sym->name); |
1061 | if (sym_filter_entry->map->dso->origin == DSO__ORIG_KERNEL) { | 1061 | if (sym_filter_entry->map->dso->origin == DSO__ORIG_KERNEL) { |
1062 | pr_err(": No vmlinux file was found in the path:\n"); | 1062 | pr_err(": No vmlinux file was found in the path:\n"); |
1063 | vmlinux_path__fprintf(stderr); | 1063 | machine__fprintf_vmlinux_path(machine, stderr); |
1064 | } else | 1064 | } else |
1065 | pr_err(".\n"); | 1065 | pr_err(".\n"); |
1066 | exit(1); | 1066 | exit(1); |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index aaa51ba147df..7fd6b151feb5 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -1695,9 +1695,20 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map, | |||
1695 | symbol_filter_t filter) | 1695 | symbol_filter_t filter) |
1696 | { | 1696 | { |
1697 | int i, err = 0; | 1697 | int i, err = 0; |
1698 | char *filename; | ||
1698 | 1699 | ||
1699 | pr_debug("Looking at the vmlinux_path (%d entries long)\n", | 1700 | pr_debug("Looking at the vmlinux_path (%d entries long)\n", |
1700 | vmlinux_path__nr_entries); | 1701 | vmlinux_path__nr_entries + 1); |
1702 | |||
1703 | filename = dso__build_id_filename(self, NULL, 0); | ||
1704 | if (filename != NULL) { | ||
1705 | err = dso__load_vmlinux(self, map, filename, filter); | ||
1706 | if (err > 0) { | ||
1707 | dso__set_long_name(self, filename); | ||
1708 | goto out; | ||
1709 | } | ||
1710 | free(filename); | ||
1711 | } | ||
1701 | 1712 | ||
1702 | for (i = 0; i < vmlinux_path__nr_entries; ++i) { | 1713 | for (i = 0; i < vmlinux_path__nr_entries; ++i) { |
1703 | err = dso__load_vmlinux(self, map, vmlinux_path[i], filter); | 1714 | err = dso__load_vmlinux(self, map, vmlinux_path[i], filter); |
@@ -1706,7 +1717,7 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map, | |||
1706 | break; | 1717 | break; |
1707 | } | 1718 | } |
1708 | } | 1719 | } |
1709 | 1720 | out: | |
1710 | return err; | 1721 | return err; |
1711 | } | 1722 | } |
1712 | 1723 | ||
@@ -2102,13 +2113,21 @@ out_fail: | |||
2102 | return -1; | 2113 | return -1; |
2103 | } | 2114 | } |
2104 | 2115 | ||
2105 | size_t vmlinux_path__fprintf(FILE *fp) | 2116 | size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp) |
2106 | { | 2117 | { |
2107 | int i; | 2118 | int i; |
2108 | size_t printed = 0; | 2119 | size_t printed = 0; |
2120 | struct dso *kdso = self->vmlinux_maps[MAP__FUNCTION]->dso; | ||
2121 | |||
2122 | if (kdso->has_build_id) { | ||
2123 | char filename[PATH_MAX]; | ||
2124 | if (dso__build_id_filename(kdso, filename, sizeof(filename))) | ||
2125 | printed += fprintf(fp, "[0] %s\n", filename); | ||
2126 | } | ||
2109 | 2127 | ||
2110 | for (i = 0; i < vmlinux_path__nr_entries; ++i) | 2128 | for (i = 0; i < vmlinux_path__nr_entries; ++i) |
2111 | printed += fprintf(fp, "[%d] %s\n", i, vmlinux_path[i]); | 2129 | printed += fprintf(fp, "[%d] %s\n", |
2130 | i + kdso->has_build_id, vmlinux_path[i]); | ||
2112 | 2131 | ||
2113 | return printed; | 2132 | return printed; |
2114 | } | 2133 | } |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 5d25b5eb1456..5e02d2c17154 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -216,6 +216,6 @@ int machines__create_guest_kernel_maps(struct rb_root *self); | |||
216 | int symbol__init(void); | 216 | int symbol__init(void); |
217 | bool symbol_type__is_a(char symbol_type, enum map_type map_type); | 217 | bool symbol_type__is_a(char symbol_type, enum map_type map_type); |
218 | 218 | ||
219 | size_t vmlinux_path__fprintf(FILE *fp); | 219 | size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp); |
220 | 220 | ||
221 | #endif /* __PERF_SYMBOL */ | 221 | #endif /* __PERF_SYMBOL */ |