Commit 5ad90e4ea4a096af9f0a362e34dfae5686a191ef

Authored by Arnaldo Carvalho de Melo
1 parent 62e3436b5f

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>

Showing 3 changed files with 25 additions and 6 deletions Side-by-side Diff

tools/perf/builtin-top.c
... ... @@ -1060,7 +1060,7 @@
1060 1060 pr_err("Can't annotate %s", sym->name);
1061 1061 if (sym_filter_entry->map->dso->origin == DSO__ORIG_KERNEL) {
1062 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 1064 } else
1065 1065 pr_err(".\n");
1066 1066 exit(1);
tools/perf/util/symbol.c
... ... @@ -1695,10 +1695,21 @@
1695 1695 symbol_filter_t filter)
1696 1696 {
1697 1697 int i, err = 0;
  1698 + char *filename;
1698 1699  
1699 1700 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1700   - vmlinux_path__nr_entries);
  1701 + vmlinux_path__nr_entries + 1);
1701 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 + }
  1712 +
1702 1713 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1703 1714 err = dso__load_vmlinux(self, map, vmlinux_path[i], filter);
1704 1715 if (err > 0) {
... ... @@ -1706,7 +1717,7 @@
1706 1717 break;
1707 1718 }
1708 1719 }
1709   -
  1720 +out:
1710 1721 return err;
1711 1722 }
1712 1723  
1713 1724  
1714 1725  
1715 1726  
... ... @@ -2102,13 +2113,21 @@
2102 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 2118 int i;
2108 2119 size_t printed = 0;
  2120 + struct dso *kdso = self->vmlinux_maps[MAP__FUNCTION]->dso;
2109 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 + }
  2127 +
2110 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 2132 return printed;
2114 2133 }
tools/perf/util/symbol.h
... ... @@ -216,7 +216,7 @@
216 216 int symbol__init(void);
217 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 221 #endif /* __PERF_SYMBOL */