perf tools: Fix branch report segfaults
Jiri Olsa
reviewercover perf tools: Fix branch report segfaults
hi,
adding some branch_info checks to prevent segfaults on data without branch info.
jirka
--- tools/perf/util/sort.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 26 deletions(-)
Jiri Olsa
reviewerPATCH 1/7 perf tools: Fix report -F abort for data without branch info
The branch field sorting code assumes hist_entry::branch_info is allocated, which is wrong and following perf session ends up with report segfault.
$ perf record ls $ perf report -F abort perf: Segmentation fault
Checking that hist_entry::branch_info is valid and display "N/A" string in snprint callback if it's not.
--- tools/perf/util/sort.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
tools/perf/util/sort.c +11 -3
@@ -989,6 +989,9 @@ struct sort_entry sort_mem_dcacheline = {static int64_t sort__abort_cmp (struct hist_entry *left,struct hist_entry *right) { +if (!left->branch_info || !right->branch_info) +return 0 ; +return left->branch_info->flags.abort != right->branch_info->flags.abort; }
@@ -996,10 +999,15 @@ sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)static int hist_entry__abort_snprintf (struct hist_entry *he,char *bf,size_t size,unsigned int width) { -static const char *out ="." ; +static const char *out ="N/A" ; + +if (he->branch_info) { +if (he->branch_info->flags.abort) + out ="A" ; +else + out ="." ; + } -if (he->branch_info->flags.abort) - out ="A" ;return repsep_snprintf (bf, size,"%-*s" , width, out); }
Signature · 1 line
1.9.3
Jiri Olsa
reviewerPATCH 2/7 perf tools: Fix report -F in_tx for data without branch info
In reply to Jiri OlsaThe branch field sorting code assumes hist_entry::branch_info is allocated, which is wrong and following perf session ends up with report segfault.
$ perf record ls $ perf report -F in_tx perf: Segmentation fault
Checking that hist_entry::branch_info is valid and display "N/A" string in snprint callback if it's not.
--- tools/perf/util/sort.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
tools/perf/util/sort.c +10 -3
@@ -1021,6 +1021,9 @@ struct sort_entry sort_abort = {static int64_t sort__in_tx_cmp (struct hist_entry *left,struct hist_entry *right) { +if (!left->branch_info || !right->branch_info) +return 0 ; +return left->branch_info->flags.in_tx != right->branch_info->flags.in_tx; }
@@ -1028,10 +1031,14 @@ sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right)static int hist_entry__in_tx_snprintf (struct hist_entry *he,char *bf,size_t size,unsigned int width) { -static const char *out ="." ; +static const char *out ="N/A" ; -if (he->branch_info->flags.in_tx) - out ="T" ; +if (he->branch_info) { +if (he->branch_info->flags.in_tx) + out ="T" ; +else + out ="." ; + }return repsep_snprintf (bf, size,"%-*s" , width, out); }
Signature · 1 line
1.9.3
Jiri Olsa
reviewerPATCH 3/7 perf tools: Fix report -F mispredict for data without branch info
In reply to Jiri OlsaThe branch field sorting code assumes hist_entry::branch_info is allocated, which is wrong and following perf session ends up with report segfault.
$ perf record ls $ perf report -F mispredict perf: Segmentation fault
Checking that hist_entry::branch_info is valid and display "N/A" string in snprint callback if it's not.
--- tools/perf/util/sort.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
tools/perf/util/sort.c +12 -8
@@ -471,11 +471,13 @@ struct sort_entry sort_sym_to = {static int64_t sort__mispredict_cmp (struct hist_entry *left,struct hist_entry *right) { -const unsigned char mp = left->branch_info->flags.mispred != - right->branch_info->flags.mispred; -const unsigned char p = left->branch_info->flags.predicted != - right->branch_info->flags.predicted; +unsigned char mp, p; +if (!left->branch_info || !right->branch_info) +return 0 ; + + mp = left->branch_info->flags.mispred != right->branch_info->flags.mispred; + p = left->branch_info->flags.predicted != right->branch_info->flags.predicted;return mp || p; }
@@ -483,10 +485,12 @@ static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width){static const char *out ="N/A" ; -if (he->branch_info->flags.predicted) - out ="N" ; -else if (he->branch_info->flags.mispred) - out ="Y" ; +if (he->branch_info) { +if (he->branch_info->flags.predicted) + out ="N" ; +else if (he->branch_info->flags.mispred) + out ="Y" ; + }return repsep_snprintf (bf, size,"%-*.*s" , width, width, out); }
Signature · 1 line
1.9.3
Jiri Olsa
reviewerPATCH 4/7 perf tools: Fix report -F symbol_to for data without branch info
In reply to Jiri OlsaThe branch field sorting code assumes hist_entry::branch_info is allocated, which is wrong and following perf session ends up with report segfault.
$ perf record ls $ perf report -F symbol_to perf: Segmentation fault
Checking that hist_entry::branch_info is valid and display "N/A" string in snprint callback if it's not.
--- tools/perf/util/sort.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
tools/perf/util/sort.c +14 -5
@@ -413,8 +413,13 @@ sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)static int64_t sort__sym_to_cmp (struct hist_entry *left,struct hist_entry *right) { -struct addr_map_symbol *to_l = &left->branch_info->to; -struct addr_map_symbol *to_r = &right->branch_info->to; +struct addr_map_symbol *to_l, *to_r; + +if (!left->branch_info || !right->branch_info) +return 0 ; + + to_l = &left->branch_info->to; + to_r = &right->branch_info->to;if (!to_l->sym && !to_r->sym)return _sort__addr_cmp (to_l->addr, to_r->addr);
@@ -434,10 +439,14 @@ static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,static int hist_entry__sym_to_snprintf (struct hist_entry *he,char *bf,size_t size,unsigned int width) { -struct addr_map_symbol *to = &he->branch_info->to; -return _hist_entry__sym_snprintf (to->map, to->sym, to->addr, - he->level, bf, size, width); +if (he->branch_info) { +struct addr_map_symbol *to = &he->branch_info->to; + +return _hist_entry__sym_snprintf (to->map, to->sym, to->addr, + he->level, bf, size, width); + } +return repsep_snprintf (bf, size,"%-*.*s" , width, width,"N/A" ); }struct sort_entry sort_dso_from = {
Signature · 1 line
1.9.3
Jiri Olsa
reviewerPATCH 5/7 perf tools: Fix report -F symbol_from for data without branch info
In reply to Jiri OlsaThe branch field sorting code assumes hist_entry::branch_info is allocated, which is wrong and following perf session ends up with report segfault.
$ perf record ls $ perf report -F symbol_from perf: Segmentation fault
Checking that hist_entry::branch_info is valid and display "N/A" string in snprint callback if it's not.
--- tools/perf/util/sort.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
tools/perf/util/sort.c +13 -3
@@ -404,6 +404,12 @@ sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)struct addr_map_symbol *from_l = &left->branch_info->from;struct addr_map_symbol *from_r = &right->branch_info->from; +if (!left->branch_info || !right->branch_info) +return 0 ; + + from_l = &left->branch_info->from; + from_r = &right->branch_info->from; +if (!from_l->sym && !from_r->sym)return _sort__addr_cmp (from_l->addr, from_r->addr);
@@ -430,10 +436,14 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)static int hist_entry__sym_from_snprintf (struct hist_entry *he,char *bf,size_t size,unsigned int width) { -struct addr_map_symbol *from = &he->branch_info->from; -return _hist_entry__sym_snprintf (from->map, from->sym, from->addr, - he->level, bf, size, width); +if (he->branch_info) { +struct addr_map_symbol *from = &he->branch_info->from; +return _hist_entry__sym_snprintf (from->map, from->sym, from->addr, + he->level, bf, size, width); + } + +return repsep_snprintf (bf, size,"%-*.*s" , width, width,"N/A" ); } static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
Signature · 1 line
1.9.3
Jiri Olsa
reviewerPATCH 6/7 perf tools: Fix report -F dso_to for data without branch info
In reply to Jiri OlsaThe branch field sorting code assumes hist_entry::branch_info is allocated, which is wrong and following perf session ends up with report segfault.
$ perf record ls $ perf report -F dso_to perf: Segmentation fault
Checking that hist_entry::branch_info is valid and display "N/A" string in snprint callback if it's not.
--- tools/perf/util/sort.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
tools/perf/util/sort.c +8 -2
@@ -387,6 +387,9 @@ static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,static int64_t sort__dso_to_cmp (struct hist_entry *left,struct hist_entry *right) { +if (!left->branch_info || !right->branch_info) +return 0 ; +return _sort__dso_cmp (left->branch_info->to.map, right->branch_info->to.map); }
@@ -394,8 +397,11 @@ sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)static int hist_entry__dso_to_snprintf (struct hist_entry *he,char *bf,size_t size,unsigned int width) { -return _hist_entry__dso_snprintf (he->branch_info->to.map, - bf, size, width); +if (he->branch_info) +return _hist_entry__dso_snprintf (he->branch_info->to.map, + bf, size, width); +else +return repsep_snprintf (bf, size,"%-*.*s" , width, width,"N/A" ); } static int64_t
Signature · 1 line
1.9.3
Jiri Olsa
reviewerPATCH 7/7 perf tools: Fix report -F dso_from for data without branch info
In reply to Jiri OlsaThe branch field sorting code assumes hist_entry::branch_info is allocated, which is wrong and following perf session ends up with report segfault.
$ perf record ls $ perf report -F dso_from perf: Segmentation fault
Checking that hist_entry::branch_info is valid and display "N/A" string in snprint callback if it's not.
--- tools/perf/util/sort.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
tools/perf/util/sort.c +8 -2
@@ -373,6 +373,9 @@ struct sort_entry sort_cpu = {static int64_t sort__dso_from_cmp (struct hist_entry *left,struct hist_entry *right) { +if (!left->branch_info || !right->branch_info) +return 0 ; +return _sort__dso_cmp (left->branch_info->from.map, right->branch_info->from.map); }
@@ -380,8 +383,11 @@ sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right)static int hist_entry__dso_from_snprintf (struct hist_entry *he,char *bf,size_t size,unsigned int width) { -return _hist_entry__dso_snprintf (he->branch_info->from.map, - bf, size, width); +if (he->branch_info) +return _hist_entry__dso_snprintf (he->branch_info->from.map, + bf, size, width); +else +return repsep_snprintf (bf, size,"%-*.*s" , width, width,"N/A" ); } static int64_t
Signature · 1 line
1.9.3