Example #1
0
static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym,
				 struct disasm_line *dl, int evidx)
{
	struct sym_hist *symhist;
	double percent = 0.0;
	const char *markup;
	int ret = 0;

	strcpy(buf, "");

	if (dl->offset == (s64) -1)
		return 0;

	symhist = annotation__histogram(symbol__annotation(sym), evidx);
	if (!symbol_conf.event_group && !symhist->addr[dl->offset])
		return 0;

	percent = 100.0 * symhist->addr[dl->offset] / symhist->sum;

	markup = perf_gtk__get_percent_color(percent);
	if (markup)
		ret += scnprintf(buf, size, "%s", markup);
	ret += scnprintf(buf + ret, size - ret, "%6.2f%%", percent);
	if (markup)
		ret += scnprintf(buf + ret, size - ret, "</span>");

	return ret;
}
Example #2
0
static int perf_session__add_hist_entry(struct perf_session *session,
					struct addr_location *al,
					struct perf_sample *sample,
					struct perf_evsel *evsel)
{
	struct symbol *parent = NULL;
	int err = 0;
	struct hist_entry *he;

	if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) {
		err = perf_session__resolve_callchain(session, al->thread,
						      sample->callchain, &parent);
		if (err)
			return err;
	}

	he = __hists__add_entry(&evsel->hists, al, parent, sample->period);
	if (he == NULL)
		return -ENOMEM;

	if (symbol_conf.use_callchain) {
		err = callchain_append(he->callchain, &session->callchain_cursor,
				       sample->period);
		if (err)
			return err;
	}
	/*
	 * Only in the newt browser we are doing integrated annotation,
	 * so we don't allocated the extra space needed because the stdio
	 * code will not use it.
	 */
	if (al->sym != NULL && use_browser > 0) {
		struct annotation *notes = symbol__annotation(he->ms.sym);

		assert(evsel != NULL);

		err = -ENOMEM;
		if (notes->src == NULL &&
		    symbol__alloc_hist(he->ms.sym, session->evlist->nr_entries) < 0)
			goto out;

		err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
	}

	evsel->hists.stats.total_period += sample->period;
	hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
out:
	return err;
}
Example #3
0
static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
{
	struct perf_evsel *evsel = hists_to_evsel(he->hists);
	struct symbol *sym;
	struct annotation *notes;
	struct map *map;
	int err = -1;

	if (!he || !he->ms.sym)
		return -1;

	sym = he->ms.sym;
	map = he->ms.map;

	/*
	 * We can't annotate with just /proc/kallsyms
	 */
	if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
	    !dso__is_kcore(map->dso)) {
		pr_err("Can't annotate %s: No vmlinux file was found in the "
		       "path\n", sym->name);
		sleep(1);
		return -1;
	}

	notes = symbol__annotation(sym);
	pthread_mutex_lock(&notes->lock);

	if (!symbol__hists(sym, top->evlist->nr_entries)) {
		pthread_mutex_unlock(&notes->lock);
		pr_err("Not enough memory for annotating '%s' symbol!\n",
		       sym->name);
		sleep(1);
		return err;
	}

	err = symbol__annotate(sym, map, evsel, 0, &top->annotation_opts, NULL);
	if (err == 0) {
		top->sym_filter_entry = he;
	} else {
		char msg[BUFSIZ];
		symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
		pr_err("Couldn't annotate %s: %s\n", sym->name, msg);
	}

	pthread_mutex_unlock(&notes->lock);
	return err;
}
Example #4
0
static void perf_top__record_precise_ip(struct perf_top *top,
					struct hist_entry *he,
					struct perf_sample *sample,
					struct perf_evsel *evsel, u64 ip)
{
	struct annotation *notes;
	struct symbol *sym = he->ms.sym;
	int err = 0;

	if (sym == NULL || (use_browser == 0 &&
			    (top->sym_filter_entry == NULL ||
			     top->sym_filter_entry->ms.sym != sym)))
		return;

	notes = symbol__annotation(sym);

	if (pthread_mutex_trylock(&notes->lock))
		return;

	err = hist_entry__inc_addr_samples(he, sample, evsel, ip);

	pthread_mutex_unlock(&notes->lock);

	if (unlikely(err)) {
		/*
		 * This function is now called with he->hists->lock held.
		 * Release it before going to sleep.
		 */
		pthread_mutex_unlock(&he->hists->lock);

		if (err == -ERANGE && !he->ms.map->erange_warned)
			ui__warn_map_erange(he->ms.map, sym, ip);
		else if (err == -ENOMEM) {
			pr_err("Not enough memory for annotating '%s' symbol!\n",
			       sym->name);
			sleep(1);
		}

		pthread_mutex_lock(&he->hists->lock);
	}
}
Example #5
0
static void perf_top__show_details(struct perf_top *top)
{
	struct hist_entry *he = top->sym_filter_entry;
	struct perf_evsel *evsel = hists_to_evsel(he->hists);
	struct annotation *notes;
	struct symbol *symbol;
	int more;

	if (!he)
		return;

	symbol = he->ms.sym;
	notes = symbol__annotation(symbol);

	pthread_mutex_lock(&notes->lock);

	symbol__calc_percent(symbol, evsel);

	if (notes->src == NULL)
		goto out_unlock;

	printf("Showing %s for %s\n", perf_evsel__name(top->sym_evsel), symbol->name);
	printf("  Events  Pcnt (>=%d%%)\n", top->annotation_opts.min_pcnt);

	more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel, &top->annotation_opts);

	if (top->evlist->enabled) {
		if (top->zero)
			symbol__annotate_zero_histogram(symbol, top->sym_evsel->idx);
		else
			symbol__annotate_decay_histogram(symbol, top->sym_evsel->idx);
	}
	if (more != 0)
		printf("%d lines not displayed, maybe increase display entries [e]\n", more);
out_unlock:
	pthread_mutex_unlock(&notes->lock);
}
Example #6
0
}

static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
				struct map *map, struct perf_evsel *evsel,
				struct hist_browser_timer *hbt __maybe_unused)
{
	struct disasm_line *pos, *n;
	struct annotation *notes;
	GType col_types[MAX_ANN_COLS];
	GtkCellRenderer *renderer;
	GtkListStore *store;
	GtkWidget *view;
	int i;
	char s[512];

	notes = symbol__annotation(sym);

	for (i = 0; i < MAX_ANN_COLS; i++) {
		col_types[i] = G_TYPE_STRING;
	}
	store = gtk_list_store_newv(MAX_ANN_COLS, col_types);

	view = gtk_tree_view_new();
	renderer = gtk_cell_renderer_text_new();

	for (i = 0; i < MAX_ANN_COLS; i++) {
		gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
					-1, col_names[i], renderer, "markup",
					i, NULL);
	}
Example #7
0
 */

#include "util.h"
#include "build-id.h"
#include "color.h"
#include "cache.h"
#include "symbol.h"
#include "debug.h"
#include "annotate.h"
#include <pthread.h>

const char 	*disassembler_style;

int symbol__annotate_init(struct map *map __used, struct symbol *sym)
{
	struct annotation *notes = symbol__annotation(sym);
	pthread_mutex_init(&notes->lock, NULL);
	return 0;
}

int symbol__alloc_hist(struct symbol *sym)
{
	struct annotation *notes = symbol__annotation(sym);
	size_t sizeof_sym_hist = (sizeof(struct sym_hist) +
				  (sym->end - sym->start) * sizeof(u64));

	notes->src = zalloc(sizeof(*notes->src) + symbol_conf.nr_events * sizeof_sym_hist);
	if (notes->src == NULL)
		return -1;
	notes->src->sizeof_sym_hist = sizeof_sym_hist;
	notes->src->nr_histograms   = symbol_conf.nr_events;