diff options
Diffstat (limited to 'tools/perf/builtin-top.c')
| -rw-r--r-- | tools/perf/builtin-top.c | 36 | 
1 files changed, 35 insertions, 1 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index e3c63aef8ef..8ef59f8262b 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -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(¬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) @@ -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",  |