Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e96dac7 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Arnaldo Carvalho de Melo
Browse files

perf probe: Add error checks to offline probe post-processing



Add error check codes on post processing and improve it for offline
probe events as:

 - post processing fails if no matched symbol found in map(-ENOENT)
   or strdup() failed(-ENOMEM).

 - Even if the symbol name is the same, it updates symbol address
   and offset.

Signed-off-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/148411443738.9978.4617979132625405545.stgit@devbox


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d2d4edbe
Loading
Loading
Loading
Loading
+33 −17
Original line number Diff line number Diff line
@@ -610,6 +610,33 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
	return ret ? : -ENOENT;
}

/* Adjust symbol name and address */
static int post_process_probe_trace_point(struct probe_trace_point *tp,
					   struct map *map, unsigned long offs)
{
	struct symbol *sym;
	u64 addr = tp->address + tp->offset - offs;

	sym = map__find_symbol(map, addr);
	if (!sym)
		return -ENOENT;

	if (strcmp(sym->name, tp->symbol)) {
		/* If we have no realname, use symbol for it */
		if (!tp->realname)
			tp->realname = tp->symbol;
		else
			free(tp->symbol);
		tp->symbol = strdup(sym->name);
		if (!tp->symbol)
			return -ENOMEM;
	}
	tp->offset = addr - sym->start;
	tp->address -= offs;

	return 0;
}

/*
 * Rename DWARF symbols to ELF symbols -- gcc sometimes optimizes functions
 * and generate new symbols with suffixes such as .constprop.N or .isra.N
@@ -622,11 +649,9 @@ static int
post_process_offline_probe_trace_events(struct probe_trace_event *tevs,
					int ntevs, const char *pathname)
{
	struct symbol *sym;
	struct map *map;
	unsigned long stext = 0;
	u64 addr;
	int i;
	int i, ret = 0;

	/* Prepare a map for offline binary */
	map = dso__new_map(pathname);
@@ -636,23 +661,14 @@ post_process_offline_probe_trace_events(struct probe_trace_event *tevs,
	}

	for (i = 0; i < ntevs; i++) {
		addr = tevs[i].point.address + tevs[i].point.offset - stext;
		sym = map__find_symbol(map, addr);
		if (!sym)
			continue;
		if (!strcmp(sym->name, tevs[i].point.symbol))
			continue;
		/* If we have no realname, use symbol for it */
		if (!tevs[i].point.realname)
			tevs[i].point.realname = tevs[i].point.symbol;
		else
			free(tevs[i].point.symbol);
		tevs[i].point.symbol = strdup(sym->name);
		tevs[i].point.offset = addr - sym->start;
		ret = post_process_probe_trace_point(&tevs[i].point,
						     map, stext);
		if (ret < 0)
			break;
	}
	map__put(map);

	return 0;
	return ret;
}

static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,