2012-12-27

From: Namhyung Kim

Current perf report gets segmentation fault when a branch stack

specific sort key is provided by --sort option to a perf.data file

which contains no branch infomation. It's because those sort keys

reference branch info of a hist entry unconditionally. Maybe we can

change it checks whether such branch info is valid or not. But if the

branch stacks are not recorded, it'd be nop. Thus it'd be better to

make those keys are unselectable.

This patch separates those keys to a different dimension array, so

that if user passes such a key to a file which has no branch stack

will get following message rather than a segfault.

Error: Invalid --sort key: `symbol_from'

Reported-by: Stefan Beller

Cc: Stephane Eranian

Signed-off-by: Namhyung Kim

---

tools/perf/util/sort.c | 64 ++++++++++++++++++++++++++++++++++++++++----------

tools/perf/util/sort.h | 8 +++++--

2 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c

index a5e732a03bda..012a077fbce9 100644

--- a/tools/perf/util/sort.c

+++ b/tools/perf/util/sort.c

@@ -469,30 +469,40 @@ struct sort_dimension {

#define DIM(d, n, func) [d] = { .name = n, .entry = &(func) }

-static struct sort_dimension sort_dimensions[] = {

+static struct sort_dimension common_sort_dimensions[] = {

DIM(SORT_PID, "pid", sort_thread),

DIM(SORT_COMM, "comm", sort_comm),

DIM(SORT_DSO, "dso", sort_dso),

- DIM(SORT_DSO_FROM, "dso_from", sort_dso_from),

- DIM(SORT_DSO_TO, "dso_to", sort_dso_to),

DIM(SORT_SYM, "symbol", sort_sym),

- DIM(SORT_SYM_TO, "symbol_from", sort_sym_from),

- DIM(SORT_SYM_FROM, "symbol_to", sort_sym_to),

DIM(SORT_PARENT, "parent", sort_parent),

DIM(SORT_CPU, "cpu", sort_cpu),

- DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),

DIM(SORT_SRCLINE, "srcline", sort_srcline),

};

+#undef DIM

+

+#define DIM(d, n, func) [d - __SORT_BRANCH_STACK] = { .name = n, .entry = &(func) }

+

+static struct sort_dimension bstack_sort_dimensions[] = {

+ DIM(SORT_DSO_FROM, "dso_from", sort_dso_from),

+ DIM(SORT_DSO_TO, "dso_to", sort_dso_to),

+ DIM(SORT_SYM_FROM, "symbol_from", sort_sym_from),

+ DIM(SORT_SYM_TO, "symbol_to", sort_sym_to),

+ DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),

+};

+

+#undef DIM

+

int sort_dimension__add(const char *tok)

{

unsigned int i;

- for (i = 0; i
name, strlen(tok)))

continue;

+

if (sd->entry == &sort_parent) {

int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);

if (ret) {

@@ -503,9 +513,7 @@ int sort_dimension__add(const char *tok)

return -EINVAL;

}

sort__has_parent = 1;

- } else if (sd->entry == &sort_sym ||

- sd->entry == &sort_sym_from ||

- sd->entry == &sort_sym_to) {

+ } else if (sd->entry == &sort_sym) {

sort__has_sym = 1;

}

@@ -523,6 +531,34 @@ int sort_dimension__add(const char *tok)

return 0;

}

+

+ for (i = 0; i
name, strlen(tok)))

+ continue;

+

+ if (sort__branch_mode != 1)

+ return -EINVAL;

+

+ if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)

+ sort__has_sym = 1;

+

+ if (sd->taken)

+ return 0;

+

+ if (sd->entry->se_collapse)

+ sort__need_collapse = 1;

+

+ if (list_empty(&hist_entry__sort_list))

+ sort__first_dimension = i + __SORT_BRANCH_STACK;

+

+ list_add_tail(&sd->entry->list, &hist_entry__sort_list);

+ sd->taken = 1;

+

+ return 0;

+ }

+

return -ESRCH;

}

@@ -537,7 +573,11 @@ void setup_sorting(const char * const usagestr[], const struct option *opts)

for (tok = strtok_r(str, ", ", &tmp);

tok; tok = strtok_r(NULL, ", ", &tmp)) {

- if (sort_dimension__add(tok)

Show more