aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/sort.c
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 /tools/perf/util/sort.c
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>
Diffstat (limited to 'tools/perf/util/sort.c')
-rw-r--r--tools/perf/util/sort.c64
1 files changed, 52 insertions, 12 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 }