aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung.kim@lge.com>2012-12-27 04:11:46 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-01-24 14:40:26 -0500
commitfc5871ed0dcf8c76dd1b3b36ff0f70112d2f0e74 (patch)
treec0ebaf638bb6d51afc2e24dd6a4c3d35fe64a54a
parent6f38cf25a6af5b21da1d52a94d9f56f5af2a215b (diff)
perf sort: Separate out branch stack specific sort keys
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' Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reported-by: Stefan Beller <stefanbeller@googlemail.com> Acked-by: Jiri Olsa <jolsa@redhat.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1356599507-14226-10-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/sort.c64
-rw-r--r--tools/perf/util/sort.h8
2 files changed, 58 insertions, 14 deletions
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 39b1ab0967f4..7ad62393aa88 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -480,30 +480,40 @@ struct sort_dimension {
480 480
481#define DIM(d, n, func) [d] = { .name = n, .entry = &(func) } 481#define DIM(d, n, func) [d] = { .name = n, .entry = &(func) }
482 482
483static struct sort_dimension sort_dimensions[] = { 483static struct sort_dimension common_sort_dimensions[] = {
484 DIM(SORT_PID, "pid", sort_thread), 484 DIM(SORT_PID, "pid", sort_thread),
485 DIM(SORT_COMM, "comm", sort_comm), 485 DIM(SORT_COMM, "comm", sort_comm),
486 DIM(SORT_DSO, "dso", sort_dso), 486 DIM(SORT_DSO, "dso", sort_dso),
487 DIM(SORT_DSO_FROM, "dso_from", sort_dso_from),
488 DIM(SORT_DSO_TO, "dso_to", sort_dso_to),
489 DIM(SORT_SYM, "symbol", sort_sym), 487 DIM(SORT_SYM, "symbol", sort_sym),
490 DIM(SORT_SYM_TO, "symbol_from", sort_sym_from),
491 DIM(SORT_SYM_FROM, "symbol_to", sort_sym_to),
492 DIM(SORT_PARENT, "parent", sort_parent), 488 DIM(SORT_PARENT, "parent", sort_parent),
493 DIM(SORT_CPU, "cpu", sort_cpu), 489 DIM(SORT_CPU, "cpu", sort_cpu),
494 DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
495 DIM(SORT_SRCLINE, "srcline", sort_srcline), 490 DIM(SORT_SRCLINE, "srcline", sort_srcline),
496}; 491};
497 492
493#undef DIM
494
495#define DIM(d, n, func) [d - __SORT_BRANCH_STACK] = { .name = n, .entry = &(func) }
496
497static struct sort_dimension bstack_sort_dimensions[] = {
498 DIM(SORT_DSO_FROM, "dso_from", sort_dso_from),
499 DIM(SORT_DSO_TO, "dso_to", sort_dso_to),
500 DIM(SORT_SYM_FROM, "symbol_from", sort_sym_from),
501 DIM(SORT_SYM_TO, "symbol_to", sort_sym_to),
502 DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
503};
504
505#undef DIM
506
498int sort_dimension__add(const char *tok) 507int sort_dimension__add(const char *tok)
499{ 508{
500 unsigned int i; 509 unsigned int i;
501 510
502 for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) { 511 for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++) {
503 struct sort_dimension *sd = &sort_dimensions[i]; 512 struct sort_dimension *sd = &common_sort_dimensions[i];
504 513
505 if (strncasecmp(tok, sd->name, strlen(tok))) 514 if (strncasecmp(tok, sd->name, strlen(tok)))
506 continue; 515 continue;
516
507 if (sd->entry == &sort_parent) { 517 if (sd->entry == &sort_parent) {
508 int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED); 518 int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
509 if (ret) { 519 if (ret) {
@@ -514,9 +524,7 @@ int sort_dimension__add(const char *tok)
514 return -EINVAL; 524 return -EINVAL;
515 } 525 }
516 sort__has_parent = 1; 526 sort__has_parent = 1;
517 } else if (sd->entry == &sort_sym || 527 } else if (sd->entry == &sort_sym) {
518 sd->entry == &sort_sym_from ||
519 sd->entry == &sort_sym_to) {
520 sort__has_sym = 1; 528 sort__has_sym = 1;
521 } 529 }
522 530
@@ -534,6 +542,34 @@ int sort_dimension__add(const char *tok)
534 542
535 return 0; 543 return 0;
536 } 544 }
545
546 for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) {
547 struct sort_dimension *sd = &bstack_sort_dimensions[i];
548
549 if (strncasecmp(tok, sd->name, strlen(tok)))
550 continue;
551
552 if (sort__branch_mode != 1)
553 return -EINVAL;
554
555 if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
556 sort__has_sym = 1;
557
558 if (sd->taken)
559 return 0;
560
561 if (sd->entry->se_collapse)
562 sort__need_collapse = 1;
563
564 if (list_empty(&hist_entry__sort_list))
565 sort__first_dimension = i + __SORT_BRANCH_STACK;
566
567 list_add_tail(&sd->entry->list, &hist_entry__sort_list);
568 sd->taken = 1;
569
570 return 0;
571 }
572
537 return -ESRCH; 573 return -ESRCH;
538} 574}
539 575
@@ -543,7 +579,11 @@ void setup_sorting(const char * const usagestr[], const struct option *opts)
543 579
544 for (tok = strtok_r(str, ", ", &tmp); 580 for (tok = strtok_r(str, ", ", &tmp);
545 tok; tok = strtok_r(NULL, ", ", &tmp)) { 581 tok; tok = strtok_r(NULL, ", ", &tmp)) {
546 if (sort_dimension__add(tok) < 0) { 582 int ret = sort_dimension__add(tok);
583 if (ret == -EINVAL) {
584 error("Invalid --sort key: `%s'", tok);
585 usage_with_options(usagestr, opts);
586 } else if (ret == -ESRCH) {
547 error("Unknown --sort key: `%s'", tok); 587 error("Unknown --sort key: `%s'", tok);
548 usage_with_options(usagestr, opts); 588 usage_with_options(usagestr, opts);
549 } 589 }
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index a1c0d56b6885..e994ad3e9897 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -122,18 +122,22 @@ static inline void hist_entry__add_pair(struct hist_entry *he,
122} 122}
123 123
124enum sort_type { 124enum sort_type {
125 /* common sort keys */
125 SORT_PID, 126 SORT_PID,
126 SORT_COMM, 127 SORT_COMM,
127 SORT_DSO, 128 SORT_DSO,
128 SORT_SYM, 129 SORT_SYM,
129 SORT_PARENT, 130 SORT_PARENT,
130 SORT_CPU, 131 SORT_CPU,
131 SORT_DSO_FROM, 132 SORT_SRCLINE,
133
134 /* branch stack specific sort keys */
135 __SORT_BRANCH_STACK,
136 SORT_DSO_FROM = __SORT_BRANCH_STACK,
132 SORT_DSO_TO, 137 SORT_DSO_TO,
133 SORT_SYM_FROM, 138 SORT_SYM_FROM,
134 SORT_SYM_TO, 139 SORT_SYM_TO,
135 SORT_MISPREDICT, 140 SORT_MISPREDICT,
136 SORT_SRCLINE,
137}; 141};
138 142
139/* 143/*