perf symbols: Add the build id cache to the vmlinux path
authorArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 26 May 2010 16:26:02 +0000 (13:26 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 26 May 2010 16:26:02 +0000 (13:26 -0300)
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>
tools/perf/builtin-top.c
tools/perf/util/symbol.c
tools/perf/util/symbol.h

index 397290a..a66f427 100644 (file)
@@ -1060,7 +1060,7 @@ static void event__process_sample(const event_t *self,
                        pr_err("Can't annotate %s", sym->name);
                        if (sym_filter_entry->map->dso->origin == DSO__ORIG_KERNEL) {
                                pr_err(": No vmlinux file was found in the path:\n");
-                               vmlinux_path__fprintf(stderr);
+                               machine__fprintf_vmlinux_path(machine, stderr);
                        } else
                                pr_err(".\n");
                        exit(1);
index aaa51ba..7fd6b15 100644 (file)
@@ -1695,9 +1695,20 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map,
                           symbol_filter_t filter)
 {
        int i, err = 0;
+       char *filename;
 
        pr_debug("Looking at the vmlinux_path (%d entries long)\n",
-                vmlinux_path__nr_entries);
+                vmlinux_path__nr_entries + 1);
+
+       filename = dso__build_id_filename(self, NULL, 0);
+       if (filename != NULL) {
+               err = dso__load_vmlinux(self, map, filename, filter);
+               if (err > 0) {
+                       dso__set_long_name(self, filename);
+                       goto out;
+               }
+               free(filename);
+       }
 
        for (i = 0; i < vmlinux_path__nr_entries; ++i) {
                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,
                        break;
                }
        }
-
+out:
        return err;
 }
 
@@ -2102,13 +2113,21 @@ out_fail:
        return -1;
 }
 
-size_t vmlinux_path__fprintf(FILE *fp)
+size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp)
 {
        int i;
        size_t printed = 0;
+       struct dso *kdso = self->vmlinux_maps[MAP__FUNCTION]->dso;
+
+       if (kdso->has_build_id) {
+               char filename[PATH_MAX];
+               if (dso__build_id_filename(kdso, filename, sizeof(filename)))
+                       printed += fprintf(fp, "[0] %s\n", filename);
+       }
 
        for (i = 0; i < vmlinux_path__nr_entries; ++i)
-               printed += fprintf(fp, "[%d] %s\n", i, vmlinux_path[i]);
+               printed += fprintf(fp, "[%d] %s\n",
+                                  i + kdso->has_build_id, vmlinux_path[i]);
 
        return printed;
 }
index 5d25b5e..5e02d2c 100644 (file)
@@ -216,6 +216,6 @@ int machines__create_guest_kernel_maps(struct rb_root *self);
 int symbol__init(void);
 bool symbol_type__is_a(char symbol_type, enum map_type map_type);
 
-size_t vmlinux_path__fprintf(FILE *fp);
+size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp);
 
 #endif /* __PERF_SYMBOL */