perf top: Exit if specified --vmlinux can't be used
Arnaldo Carvalho de Melo [Wed, 27 Jan 2010 23:05:49 +0000 (21:05 -0200)]
As we do lazy loading of symtabs we only will know if the
specified vmlinux file is invalid when we actually have a hit in
kernel space and then try to load it. So if we get kernel hits
and there are _no_ symbols in the DSO backing the kernel map,
bail out.

Reported-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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>
LKML-Reference: <1264633557-17597-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

tools/perf/builtin-top.c

index 2227b84..78f9c45 100644 (file)
@@ -951,9 +951,31 @@ static void event__process_sample(const event_t *self,
        }
 
        if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 ||
-           al.sym == NULL || al.filtered)
+           al.filtered)
                return;
 
+       if (al.sym == NULL) {
+               /*
+                * As we do lazy loading of symtabs we only will know if the
+                * specified vmlinux file is invalid when we actually have a
+                * hit in kernel space and then try to load it. So if we get
+                * here and there are _no_ symbols in the DSO backing the
+                * kernel map, bail out.
+                *
+                * We may never get here, for instance, if we use -K/
+                * --hide-kernel-symbols, even if the user specifies an
+                * invalid --vmlinux ;-)
+                */
+               if (al.map == session->vmlinux_maps[MAP__FUNCTION] &&
+                   RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
+                       pr_err("The %s file can't be used\n",
+                              symbol_conf.vmlinux_name);
+                       exit(1);
+               }
+
+               return;
+       }
+
        syme = symbol__priv(al.sym);
        if (!syme->skip) {
                syme->count[counter]++;