From f05082b5479d91ee5c04f311acaa394ce0c5e6d2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 4 Apr 2017 12:05:37 -0300 Subject: perf tools: Handle allocation failures gracefully The callers of perf_read_values__enlarge_counters() already propagate errors, so just print some debug diagnostics and handle allocation failures gracefully, not trying to do silly things like 'a = realloc(a)'. Link: http://lkml.kernel.org/n/tip-nsmmh7uzpg35rzcl9nq7yztp@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/values.c | 54 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 15 deletions(-) (limited to 'tools/perf/util') diff --git a/tools/perf/util/values.c b/tools/perf/util/values.c index 5074be4ed467..2a8efa7b7c48 100644 --- a/tools/perf/util/values.c +++ b/tools/perf/util/values.c @@ -108,24 +108,45 @@ static int perf_read_values__findnew_thread(struct perf_read_values *values, return i; } -static void perf_read_values__enlarge_counters(struct perf_read_values *values) +static int perf_read_values__enlarge_counters(struct perf_read_values *values) { - int i; + char **countername; + int i, counters_max = values->counters_max * 2; + u64 *counterrawid = realloc(values->counterrawid, counters_max * sizeof(*values->counterrawid)); + + if (!counterrawid) { + pr_debug("failed to enlarge read_values rawid array"); + goto out_enomem; + } - values->counters_max *= 2; - values->counterrawid = realloc(values->counterrawid, - values->counters_max * sizeof(*values->counterrawid)); - values->countername = realloc(values->countername, - values->counters_max * sizeof(*values->countername)); - if (!values->counterrawid || !values->countername) - die("failed to enlarge read_values counters arrays"); + countername = realloc(values->countername, counters_max * sizeof(*values->countername)); + if (!countername) { + pr_debug("failed to enlarge read_values rawid array"); + goto out_free_rawid; + } for (i = 0; i < values->threads; i++) { - values->value[i] = realloc(values->value[i], - values->counters_max * sizeof(**values->value)); - if (!values->value[i]) - die("failed to enlarge read_values counters arrays"); + u64 *value = realloc(values->value[i], counters_max * sizeof(**values->value)); + + if (value) { + pr_debug("failed to enlarge read_values ->values array"); + goto out_free_name; + } + + values->value[i] = value; } + + values->counters_max = counters_max; + values->counterrawid = counterrawid; + values->countername = countername; + + return 0; +out_free_name: + free(countername); +out_free_rawid: + free(counterrawid); +out_enomem: + return -ENOMEM; } static int perf_read_values__findnew_counter(struct perf_read_values *values, @@ -137,8 +158,11 @@ static int perf_read_values__findnew_counter(struct perf_read_values *values, if (values->counterrawid[i] == rawid) return i; - if (values->counters == values->counters_max) - perf_read_values__enlarge_counters(values); + if (values->counters == values->counters_max) { + i = perf_read_values__enlarge_counters(values); + if (i) + return i; + } i = values->counters++; values->counterrawid[i] = rawid; -- cgit v1.2.3 From 9c0899f15766158df8b3bd152f5da0b6c1bd2806 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 4 Apr 2017 12:11:07 -0300 Subject: perf tools: Don't die on a print function Trying to remove die() calls from library functions, postponing exiting to the tool main code. Link: http://lkml.kernel.org/n/tip-ackxq5nqe39gunln3tkczs42@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/values.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tools/perf/util') diff --git a/tools/perf/util/values.c b/tools/perf/util/values.c index 2a8efa7b7c48..5de2e15e2eda 100644 --- a/tools/perf/util/values.c +++ b/tools/perf/util/values.c @@ -1,4 +1,7 @@ +#include +#include #include +#include #include "util.h" #include "values.h" @@ -196,8 +199,10 @@ static void perf_read_values__display_pretty(FILE *fp, int *counterwidth; counterwidth = malloc(values->counters * sizeof(*counterwidth)); - if (!counterwidth) - die("failed to allocate counterwidth array"); + if (!counterwidth) { + fprintf(fp, "INTERNAL ERROR: Failed to allocate counterwidth array\n"); + return; + } tidwidth = 3; pidwidth = 3; for (j = 0; j < values->counters; j++) -- cgit v1.2.3 From 99094a5e941fe88d95cbd594e6a41bee24003ecb Mon Sep 17 00:00:00 2001 From: Taeung Song Date: Tue, 28 Mar 2017 21:12:05 +0900 Subject: perf annotate: Fix missing number of samples for source_line_samples The option 'show-total-period' works fine without a option '-l'. But if running 'perf annotate --stdio -l --show-total-period', you can see a problem showing only zero '0' for number of samples. Before: $ perf annotate --stdio -l --show-total-period ... 0 : 400816: push %rbp 0 : 400817: mov %rsp,%rbp 0 : 40081a: mov %edi,-0x24(%rbp) 0 : 40081d: mov %rsi,-0x30(%rbp) 0 : 400821: mov -0x24(%rbp),%eax 0 : 400824: mov -0x30(%rbp),%rdx 0 : 400828: mov (%rdx),%esi 0 : 40082a: mov $0x0,%edx ... The reason is it was missed to set number of samples of source_line_samples, so set it ordinarily. After: $ perf annotate --stdio -l --show-total-period ... 3 : 400816: push %rbp 4 : 400817: mov %rsp,%rbp 0 : 40081a: mov %edi,-0x24(%rbp) 0 : 40081d: mov %rsi,-0x30(%rbp) 1 : 400821: mov -0x24(%rbp),%eax 2 : 400824: mov -0x30(%rbp),%rdx 0 : 400828: mov (%rdx),%esi 1 : 40082a: mov $0x0,%edx ... Signed-off-by: Taeung Song Cc: Jiri Olsa Cc: Martin Liska Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Wang Nan Fixes: 0c4a5bcea460 ("perf annotate: Display total number of samples with --show-total-period") Link: http://lkml.kernel.org/r/1490703125-13643-1-git-send-email-treeze.taeung@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 6 ++++-- tools/perf/util/annotate.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'tools/perf/util') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 11af5f0d56cc..a37032bd137d 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1665,7 +1665,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, start = map__rip_2objdump(map, sym->start); for (i = 0; i < len; i++) { - u64 offset; + u64 offset, nr_samples; double percent_max = 0.0; src_line->nr_pcnt = nr_pcnt; @@ -1674,12 +1674,14 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, double percent = 0.0; h = annotation__histogram(notes, evidx + k); + nr_samples = h->addr[i]; if (h->sum) - percent = 100.0 * h->addr[i] / h->sum; + percent = 100.0 * nr_samples / h->sum; if (percent > percent_max) percent_max = percent; src_line->samples[k].percent = percent; + src_line->samples[k].nr = nr_samples; } if (percent_max <= 0.5) diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 09776b5af991..948aa8e6fd39 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -98,7 +98,7 @@ struct cyc_hist { struct source_line_samples { double percent; double percent_sum; - double nr; + u64 nr; }; struct source_line { -- cgit v1.2.3