Skip to content

Commit

Permalink
perf stat: fix NULL pointer reference bug with event unit
Browse files Browse the repository at this point in the history
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 <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
Stephane Eranian authored and acmel committed Jan 20, 2014
1 parent 3a46817 commit 8a39889
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 6 deletions.
2 changes: 1 addition & 1 deletion tools/perf/util/parse-events.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
24 changes: 20 additions & 4 deletions tools/perf/util/pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/pmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 8a39889

Please sign in to comment.