diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-10-24 09:25:09 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-10-29 08:32:48 -0400 |
commit | 7e4772dc99a3ebfc53708eff262f7a8155485e85 (patch) | |
tree | 4a19434e3eb635a9c42948e6503554cb675d44cb | |
parent | 46b1fa85ff5a2e03423770b3931b97266e8ac6cf (diff) |
perf pmu: Add proper error handling to print_pmu_events()
It was silently returning or printing "(null)" when no memory was
available at various points. Fix it by checking and warning the user
when that happens.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-835udmf66x9nza504cu6irz9@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/pmu.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 91dca604c422..881b75490533 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
@@ -753,9 +753,9 @@ void print_pmu_events(const char *event_glob, bool name_only) | |||
753 | if (pmu->selectable) | 753 | if (pmu->selectable) |
754 | len++; | 754 | len++; |
755 | } | 755 | } |
756 | aliases = malloc(sizeof(char *) * len); | 756 | aliases = zalloc(sizeof(char *) * len); |
757 | if (!aliases) | 757 | if (!aliases) |
758 | return; | 758 | goto out_enomem; |
759 | pmu = NULL; | 759 | pmu = NULL; |
760 | j = 0; | 760 | j = 0; |
761 | while ((pmu = perf_pmu__scan(pmu)) != NULL) { | 761 | while ((pmu = perf_pmu__scan(pmu)) != NULL) { |
@@ -768,16 +768,20 @@ void print_pmu_events(const char *event_glob, bool name_only) | |||
768 | (!is_cpu && strglobmatch(alias->name, | 768 | (!is_cpu && strglobmatch(alias->name, |
769 | event_glob)))) | 769 | event_glob)))) |
770 | continue; | 770 | continue; |
771 | aliases[j] = name; | 771 | |
772 | if (is_cpu && !name_only) | 772 | if (is_cpu && !name_only) |
773 | aliases[j] = format_alias_or(buf, sizeof(buf), | 773 | name = format_alias_or(buf, sizeof(buf), pmu, alias); |
774 | pmu, alias); | 774 | |
775 | aliases[j] = strdup(aliases[j]); | 775 | aliases[j] = strdup(name); |
776 | if (aliases[j] == NULL) | ||
777 | goto out_enomem; | ||
776 | j++; | 778 | j++; |
777 | } | 779 | } |
778 | if (pmu->selectable) { | 780 | if (pmu->selectable) { |
779 | scnprintf(buf, sizeof(buf), "%s//", pmu->name); | 781 | char *s; |
780 | aliases[j] = strdup(buf); | 782 | if (asprintf(&s, "%s//", pmu->name) < 0) |
783 | goto out_enomem; | ||
784 | aliases[j] = s; | ||
781 | j++; | 785 | j++; |
782 | } | 786 | } |
783 | } | 787 | } |
@@ -789,12 +793,20 @@ void print_pmu_events(const char *event_glob, bool name_only) | |||
789 | continue; | 793 | continue; |
790 | } | 794 | } |
791 | printf(" %-50s [Kernel PMU event]\n", aliases[j]); | 795 | printf(" %-50s [Kernel PMU event]\n", aliases[j]); |
792 | zfree(&aliases[j]); | ||
793 | printed++; | 796 | printed++; |
794 | } | 797 | } |
795 | if (printed) | 798 | if (printed) |
796 | printf("\n"); | 799 | printf("\n"); |
797 | free(aliases); | 800 | out_free: |
801 | for (j = 0; j < len; j++) | ||
802 | zfree(&aliases[j]); | ||
803 | zfree(&aliases); | ||
804 | return; | ||
805 | |||
806 | out_enomem: | ||
807 | printf("FATAL: not enough memory to print PMU events\n"); | ||
808 | if (aliases) | ||
809 | goto out_free; | ||
798 | } | 810 | } |
799 | 811 | ||
800 | bool pmu_have_event(const char *pname, const char *name) | 812 | bool pmu_have_event(const char *pname, const char *name) |