Skip to content

Commit 8a39889

Browse files
Stephane Eranianacmel
authored andcommitted
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>
1 parent 3a46817 commit 8a39889

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

tools/perf/util/parse-events.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
635635
struct perf_event_attr attr;
636636
struct perf_pmu *pmu;
637637
struct perf_evsel *evsel;
638-
char *unit;
638+
const char *unit;
639639
double scale;
640640

641641
pmu = perf_pmu__find(name);

tools/perf/util/pmu.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
105105
char scale[128];
106106
int fd, ret = -1;
107107
char path[PATH_MAX];
108-
char *lc;
108+
const char *lc;
109109

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

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

610610

611611
static int check_unit_scale(struct perf_pmu_alias *alias,
612-
char **unit, double *scale)
612+
const char **unit, double *scale)
613613
{
614614
/*
615615
* Only one term in event definition can
@@ -634,14 +634,18 @@ static int check_unit_scale(struct perf_pmu_alias *alias,
634634
* defined for the alias
635635
*/
636636
int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
637-
char **unit, double *scale)
637+
const char **unit, double *scale)
638638
{
639639
struct parse_events_term *term, *h;
640640
struct perf_pmu_alias *alias;
641641
int ret;
642642

643+
/*
644+
* Mark unit and scale as not set
645+
* (different from default values, see below)
646+
*/
643647
*unit = NULL;
644-
*scale = 0;
648+
*scale = 0.0;
645649

646650
list_for_each_entry_safe(term, h, head_terms, list) {
647651
alias = pmu_find_alias(pmu, term);
@@ -658,6 +662,18 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
658662
list_del(&term->list);
659663
free(term);
660664
}
665+
666+
/*
667+
* if no unit or scale foundin aliases, then
668+
* set defaults as for evsel
669+
* unit cannot left to NULL
670+
*/
671+
if (*unit == NULL)
672+
*unit = "";
673+
674+
if (*scale == 0.0)
675+
*scale = 1.0;
676+
661677
return 0;
662678
}
663679

tools/perf/util/pmu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ int perf_pmu__config_terms(struct list_head *formats,
2929
struct perf_event_attr *attr,
3030
struct list_head *head_terms);
3131
int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
32-
char **unit, double *scale);
32+
const char **unit, double *scale);
3333
struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
3434
struct list_head *head_terms);
3535
int perf_pmu_wrap(void);

0 commit comments

Comments
 (0)