Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / tools / perf / builtin-top.c
index e3c63aef8efc6a334728ee9864c8243415c478be..8ef59f8262bb37a28c2e83724dbe62b88df349e7 100644 (file)
@@ -42,6 +42,7 @@
 #include "util/debug.h"
 
 #include <assert.h>
+#include <elf.h>
 #include <fcntl.h>
 
 #include <stdio.h>
@@ -59,6 +60,7 @@
 #include <sys/prctl.h>
 #include <sys/wait.h>
 #include <sys/uio.h>
+#include <sys/utsname.h>
 #include <sys/mman.h>
 
 #include <linux/unistd.h>
@@ -162,12 +164,40 @@ static void __zero_source_counters(struct hist_entry *he)
        symbol__annotate_zero_histograms(sym);
 }
 
+static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip)
+{
+       struct utsname uts;
+       int err = uname(&uts);
+
+       ui__warning("Out of bounds address found:\n\n"
+                   "Addr:   %" PRIx64 "\n"
+                   "DSO:    %s %c\n"
+                   "Map:    %" PRIx64 "-%" PRIx64 "\n"
+                   "Symbol: %" PRIx64 "-%" PRIx64 " %c %s\n"
+                   "Arch:   %s\n"
+                   "Kernel: %s\n"
+                   "Tools:  %s\n\n"
+                   "Not all samples will be on the annotation output.\n\n"
+                   "Please report to linux-kernel@vger.kernel.org\n",
+                   ip, map->dso->long_name, dso__symtab_origin(map->dso),
+                   map->start, map->end, sym->start, sym->end,
+                   sym->binding == STB_GLOBAL ? 'g' :
+                   sym->binding == STB_LOCAL  ? 'l' : 'w', sym->name,
+                   err ? "[unknown]" : uts.machine,
+                   err ? "[unknown]" : uts.release, perf_version_string);
+       if (use_browser <= 0)
+               sleep(5);
+       
+       map->erange_warned = true;
+}
+
 static void perf_top__record_precise_ip(struct perf_top *top,
                                        struct hist_entry *he,
                                        int counter, u64 ip)
 {
        struct annotation *notes;
        struct symbol *sym;
+       int err;
 
        if (he == NULL || he->ms.sym == NULL ||
            ((top->sym_filter_entry == NULL ||
@@ -189,9 +219,12 @@ static void perf_top__record_precise_ip(struct perf_top *top,
        }
 
        ip = he->ms.map->map_ip(he->ms.map, ip);
-       symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
+       err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
 
        pthread_mutex_unlock(&notes->lock);
+
+       if (err == -ERANGE && !he->ms.map->erange_warned)
+               ui__warn_map_erange(he->ms.map, sym, ip);
 }
 
 static void perf_top__show_details(struct perf_top *top)
@@ -615,6 +648,7 @@ process_hotkey:
 
 /* Tag samples to be skipped. */
 static const char *skip_symbols[] = {
+       "intel_idle",
        "default_idle",
        "native_safe_halt",
        "cpu_idle",