diff options
Diffstat (limited to 'tools/perf/util')
| -rw-r--r-- | tools/perf/util/annotate.c | 16 | ||||
| -rw-r--r-- | tools/perf/util/hist.c | 12 | ||||
| -rw-r--r-- | tools/perf/util/map.c | 1 | ||||
| -rw-r--r-- | tools/perf/util/map.h | 1 | ||||
| -rw-r--r-- | tools/perf/util/parse-events.l | 2 | ||||
| -rw-r--r-- | tools/perf/util/session.c | 16 | ||||
| -rw-r--r-- | tools/perf/util/symbol.c | 13 | ||||
| -rw-r--r-- | tools/perf/util/ui/browsers/hists.c | 3 | 
8 files changed, 42 insertions, 22 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 199f69ec656..08c6d138a65 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -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); @@ -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];  	}  } diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 2ec4b60aff6..9f6d630d531 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -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;  		} diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index dea6d1c1a95..35ae56864e4 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -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, diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index b100c20b7f9..81371bad4ef 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -33,6 +33,7 @@ struct map {  	u64			end;  	u8 /* enum map_type */	type;  	bool			referenced; +	bool			erange_warned;  	u32			priv;  	u64			pgoff; diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 05d766e3ecb..1fcf1bbc545 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -54,7 +54,7 @@ num_dec		[0-9]+  num_hex		0x[a-fA-F0-9]+  num_raw_hex	[a-fA-F0-9]+  name		[a-zA-Z_*?][a-zA-Z0-9_*?]* -modifier_event	[ukhp]{1,5} +modifier_event	[ukhpGH]{1,8}  modifier_bp	[rwx]  %% diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 9412e3b05f6..1efd3bee633 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -826,8 +826,16 @@ static struct machine *  {  	const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; -	if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) -		return perf_session__find_machine(session, event->ip.pid); +	if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { +		u32 pid; + +		if (event->header.type == PERF_RECORD_MMAP) +			pid = event->mmap.pid; +		else +			pid = event->ip.pid; + +		return perf_session__find_machine(session, pid); +	}  	return perf_session__find_host_machine(session);  } @@ -868,11 +876,11 @@ static int perf_session_deliver_event(struct perf_session *session,  		dump_sample(session, event, sample);  		if (evsel == NULL) {  			++session->hists.stats.nr_unknown_id; -			return -1; +			return 0;  		}  		if (machine == NULL) {  			++session->hists.stats.nr_unprocessable_samples; -			return -1; +			return 0;  		}  		return tool->sample(tool, event, sample, evsel, machine);  	case PERF_RECORD_MMAP: diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index c0a028c3eba..ab9867b2b43 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -977,8 +977,9 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,   * And always look at the original dso, not at debuginfo packages, that   * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).   */ -static int dso__synthesize_plt_symbols(struct  dso *dso, struct map *map, -				       symbol_filter_t filter) +static int +dso__synthesize_plt_symbols(struct dso *dso, char *name, struct map *map, +			    symbol_filter_t filter)  {  	uint32_t nr_rel_entries, idx;  	GElf_Sym sym; @@ -993,10 +994,7 @@ static int dso__synthesize_plt_symbols(struct  dso *dso, struct map *map,  	char sympltname[1024];  	Elf *elf;  	int nr = 0, symidx, fd, err = 0; -	char name[PATH_MAX]; -	snprintf(name, sizeof(name), "%s%s", -		 symbol_conf.symfs, dso->long_name);  	fd = open(name, O_RDONLY);  	if (fd < 0)  		goto out; @@ -1703,8 +1701,9 @@ restart:  			continue;  		if (ret > 0) { -			int nr_plt = dso__synthesize_plt_symbols(dso, map, -								 filter); +			int nr_plt; + +			nr_plt = dso__synthesize_plt_symbols(dso, name, map, filter);  			if (nr_plt > 0)  				ret += nr_plt;  			break; diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index d7a1c4afe28..2f83e5dc996 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c @@ -125,6 +125,9 @@ static int callchain__count_rows(struct rb_root *chain)  static bool map_symbol__toggle_fold(struct map_symbol *self)  { +	if (!self) +		return false; +  	if (!self->has_children)  		return false;  |