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) |
