Loading tools/perf/builtin-top.c +35 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include "util/debug.h" #include <assert.h> #include <elf.h> #include <fcntl.h> #include <stdio.h> Loading @@ -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> Loading Loading @@ -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 || Loading @@ -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(¬es->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) Loading Loading @@ -615,6 +648,7 @@ static void *display_thread(void *arg) /* Tag samples to be skipped. */ static const char *skip_symbols[] = { "intel_idle", "default_idle", "native_safe_halt", "cpu_idle", Loading tools/perf/util/annotate.c +6 −10 Original line number Diff line number Diff line Loading @@ -64,8 +64,8 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map, pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); if (addr > sym->end) return 0; if (addr < sym->start || addr > sym->end) return -ERANGE; offset = addr - sym->start; h = annotation__histogram(notes, evidx); Loading Loading @@ -561,16 +561,12 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) { struct annotation *notes = symbol__annotation(sym); struct sym_hist *h = annotation__histogram(notes, evidx); struct objdump_line *pos; int len = sym->end - sym->start; int len = sym->end - sym->start, offset; h->sum = 0; list_for_each_entry(pos, ¬es->src->source, node) { if (pos->offset != -1 && pos->offset < len) { h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8; h->sum += h->addr[pos->offset]; } for (offset = 0; offset < len; ++offset) { h->addr[offset] = h->addr[offset] * 7 / 8; h->sum += h->addr[offset]; } } Loading tools/perf/util/hist.c +12 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,18 @@ static struct hist_entry *add_hist_entry(struct hists *hists, if (!cmp) { he->period += period; ++he->nr_events; /* If the map of an existing hist_entry has * become out-of-date due to an exec() or * similar, update it. Otherwise we will * mis-adjust symbol addresses when computing * the history counter to increment. */ if (he->ms.map != entry->ms.map) { he->ms.map = entry->ms.map; if (he->ms.map) he->ms.map->referenced = true; } goto out; } Loading tools/perf/util/map.c +1 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ void map__init(struct map *self, enum map_type type, RB_CLEAR_NODE(&self->rb_node); self->groups = NULL; self->referenced = false; self->erange_warned = false; } struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, Loading tools/perf/util/map.h +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct map { u64 end; u8 /* enum map_type */ type; bool referenced; bool erange_warned; u32 priv; u64 pgoff; Loading Loading
tools/perf/builtin-top.c +35 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include "util/debug.h" #include <assert.h> #include <elf.h> #include <fcntl.h> #include <stdio.h> Loading @@ -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> Loading Loading @@ -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 || Loading @@ -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(¬es->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) Loading Loading @@ -615,6 +648,7 @@ static void *display_thread(void *arg) /* Tag samples to be skipped. */ static const char *skip_symbols[] = { "intel_idle", "default_idle", "native_safe_halt", "cpu_idle", Loading
tools/perf/util/annotate.c +6 −10 Original line number Diff line number Diff line Loading @@ -64,8 +64,8 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map, pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); if (addr > sym->end) return 0; if (addr < sym->start || addr > sym->end) return -ERANGE; offset = addr - sym->start; h = annotation__histogram(notes, evidx); Loading Loading @@ -561,16 +561,12 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) { struct annotation *notes = symbol__annotation(sym); struct sym_hist *h = annotation__histogram(notes, evidx); struct objdump_line *pos; int len = sym->end - sym->start; int len = sym->end - sym->start, offset; h->sum = 0; list_for_each_entry(pos, ¬es->src->source, node) { if (pos->offset != -1 && pos->offset < len) { h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8; h->sum += h->addr[pos->offset]; } for (offset = 0; offset < len; ++offset) { h->addr[offset] = h->addr[offset] * 7 / 8; h->sum += h->addr[offset]; } } Loading
tools/perf/util/hist.c +12 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,18 @@ static struct hist_entry *add_hist_entry(struct hists *hists, if (!cmp) { he->period += period; ++he->nr_events; /* If the map of an existing hist_entry has * become out-of-date due to an exec() or * similar, update it. Otherwise we will * mis-adjust symbol addresses when computing * the history counter to increment. */ if (he->ms.map != entry->ms.map) { he->ms.map = entry->ms.map; if (he->ms.map) he->ms.map->referenced = true; } goto out; } Loading
tools/perf/util/map.c +1 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ void map__init(struct map *self, enum map_type type, RB_CLEAR_NODE(&self->rb_node); self->groups = NULL; self->referenced = false; self->erange_warned = false; } struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, Loading
tools/perf/util/map.h +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct map { u64 end; u8 /* enum map_type */ type; bool referenced; bool erange_warned; u32 priv; u64 pgoff; Loading