diff options
author | Stephane Eranian <eranian@google.com> | 2014-01-17 16:34:05 +0100 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-01-20 16:19:08 -0300 |
commit | 8a398897ff21f73cb8b15a19514660f032926882 (patch) | |
tree | bb08e1fcfe48e09b30ec21f67b7b7fbb5fb7f176 /tools/perf/util/pmu.c | |
parent | 3a46817f674389d5fb2f4dce19fbc73ebd1976bb (diff) | |
download | blackbird-op-linux-8a398897ff21f73cb8b15a19514660f032926882.tar.gz blackbird-op-linux-8a398897ff21f73cb8b15a19514660f032926882.zip |
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: Stephane 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: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/pmu.c')
-rw-r--r-- | tools/perf/util/pmu.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index d9cab4d27192..b752ecb40d86 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -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; } |