aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorStephane Eranian <eranian@google.com>2014-01-17 10:34:05 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-01-20 14:19:08 -0500
commit8a398897ff21f73cb8b15a19514660f032926882 (patch)
treebb08e1fcfe48e09b30ec21f67b7b7fbb5fb7f176 /tools
parent3a46817f674389d5fb2f4dce19fbc73ebd1976bb (diff)
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')
-rw-r--r--tools/perf/util/parse-events.c2
-rw-r--r--tools/perf/util/pmu.c24
-rw-r--r--tools/perf/util/pmu.h2
3 files changed, 22 insertions, 6 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index a7f1b6a91fdd..d248fca6d7ed 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -635,7 +635,7 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
635 struct perf_event_attr attr; 635 struct perf_event_attr attr;
636 struct perf_pmu *pmu; 636 struct perf_pmu *pmu;
637 struct perf_evsel *evsel; 637 struct perf_evsel *evsel;
638 char *unit; 638 const char *unit;
639 double scale; 639 double scale;
640 640
641 pmu = perf_pmu__find(name); 641 pmu = perf_pmu__find(name);
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 *
105 char scale[128]; 105 char scale[128];
106 int fd, ret = -1; 106 int fd, ret = -1;
107 char path[PATH_MAX]; 107 char path[PATH_MAX];
108 char *lc; 108 const char *lc;
109 109
110 snprintf(path, PATH_MAX, "%s/%s.scale", dir, name); 110 snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
111 111
@@ -609,7 +609,7 @@ static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
609 609
610 610
611static int check_unit_scale(struct perf_pmu_alias *alias, 611static int check_unit_scale(struct perf_pmu_alias *alias,
612 char **unit, double *scale) 612 const char **unit, double *scale)
613{ 613{
614 /* 614 /*
615 * Only one term in event definition can 615 * Only one term in event definition can
@@ -634,14 +634,18 @@ static int check_unit_scale(struct perf_pmu_alias *alias,
634 * defined for the alias 634 * defined for the alias
635 */ 635 */
636int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, 636int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
637 char **unit, double *scale) 637 const char **unit, double *scale)
638{ 638{
639 struct parse_events_term *term, *h; 639 struct parse_events_term *term, *h;
640 struct perf_pmu_alias *alias; 640 struct perf_pmu_alias *alias;
641 int ret; 641 int ret;
642 642
643 /*
644 * Mark unit and scale as not set
645 * (different from default values, see below)
646 */
643 *unit = NULL; 647 *unit = NULL;
644 *scale = 0; 648 *scale = 0.0;
645 649
646 list_for_each_entry_safe(term, h, head_terms, list) { 650 list_for_each_entry_safe(term, h, head_terms, list) {
647 alias = pmu_find_alias(pmu, term); 651 alias = pmu_find_alias(pmu, term);
@@ -658,6 +662,18 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
658 list_del(&term->list); 662 list_del(&term->list);
659 free(term); 663 free(term);
660 } 664 }
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
661 return 0; 677 return 0;
662} 678}
663 679
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 9183380e2038..8b64125a9281 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -29,7 +29,7 @@ int perf_pmu__config_terms(struct list_head *formats,
29 struct perf_event_attr *attr, 29 struct perf_event_attr *attr,
30 struct list_head *head_terms); 30 struct list_head *head_terms);
31int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, 31int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
32 char **unit, double *scale); 32 const char **unit, double *scale);
33struct list_head *perf_pmu__alias(struct perf_pmu *pmu, 33struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
34 struct list_head *head_terms); 34 struct list_head *head_terms);
35int perf_pmu_wrap(void); 35int perf_pmu_wrap(void);