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

Commit 8a398897 authored by Stephane Eranian's avatar Stephane Eranian Committed by Arnaldo Carvalho de Melo
Browse files

perf stat: fix NULL pointer reference bug with event unit



This patch fixes a problem with the handling of the newly introduced
optional event unit. The following cmdline caused a segfault:

 $ perf stat -e cpu/event-0x3c/ ls

This patch fixes the problem with the default setting for alias->unit
which was eventually causing the segfault.

Signed-off-by: default avatarStephane Eranian <eranian@google.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1389972846-6566-2-git-send-email-eranian@google.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 3a46817f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -635,7 +635,7 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
	struct perf_event_attr attr;
	struct perf_pmu *pmu;
	struct perf_evsel *evsel;
	char *unit;
	const char *unit;
	double scale;

	pmu = perf_pmu__find(name);
+20 −4
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
	char scale[128];
	int fd, ret = -1;
	char path[PATH_MAX];
	char *lc;
	const char *lc;

	snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);

@@ -609,7 +609,7 @@ static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,


static int check_unit_scale(struct perf_pmu_alias *alias,
			    char **unit, double *scale)
			    const char **unit, double *scale)
{
	/*
	 * Only one term in event definition can
@@ -634,14 +634,18 @@ static int check_unit_scale(struct perf_pmu_alias *alias,
 * defined for the alias
 */
int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
			  char **unit, double *scale)
			  const char **unit, double *scale)
{
	struct parse_events_term *term, *h;
	struct perf_pmu_alias *alias;
	int ret;

	/*
	 * Mark unit and scale as not set
	 * (different from default values, see below)
	 */
	*unit   = NULL;
	*scale  = 0;
	*scale  = 0.0;

	list_for_each_entry_safe(term, h, head_terms, list) {
		alias = pmu_find_alias(pmu, term);
@@ -658,6 +662,18 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
		list_del(&term->list);
		free(term);
	}

	/*
	 * if no unit or scale foundin aliases, then
	 * set defaults as for evsel
	 * unit cannot left to NULL
	 */
	if (*unit == NULL)
		*unit   = "";

	if (*scale == 0.0)
		*scale  = 1.0;

	return 0;
}

+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ int perf_pmu__config_terms(struct list_head *formats,
			   struct perf_event_attr *attr,
			   struct list_head *head_terms);
int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
			  char **unit, double *scale);
			  const char **unit, double *scale);
struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
				  struct list_head *head_terms);
int perf_pmu_wrap(void);