diff options
Diffstat (limited to 'tools/perf/builtin-annotate.c')
| -rw-r--r-- | tools/perf/builtin-annotate.c | 66 |
1 files changed, 23 insertions, 43 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 21a78d30d53d..593ff25006de 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include "util/sort.h" | 26 | #include "util/sort.h" |
| 27 | #include "util/hist.h" | 27 | #include "util/hist.h" |
| 28 | #include "util/session.h" | 28 | #include "util/session.h" |
| 29 | #include "util/data_map.h" | ||
| 30 | 29 | ||
| 31 | static char const *input_name = "perf.data"; | 30 | static char const *input_name = "perf.data"; |
| 32 | 31 | ||
| @@ -52,11 +51,6 @@ struct sym_priv { | |||
| 52 | struct sym_ext *ext; | 51 | struct sym_ext *ext; |
| 53 | }; | 52 | }; |
| 54 | 53 | ||
| 55 | static struct symbol_conf symbol_conf = { | ||
| 56 | .priv_size = sizeof(struct sym_priv), | ||
| 57 | .try_vmlinux_path = true, | ||
| 58 | }; | ||
| 59 | |||
| 60 | static const char *sym_hist_filter; | 54 | static const char *sym_hist_filter; |
| 61 | 55 | ||
| 62 | static int symbol_filter(struct map *map __used, struct symbol *sym) | 56 | static int symbol_filter(struct map *map __used, struct symbol *sym) |
| @@ -122,30 +116,32 @@ static void hist_hit(struct hist_entry *he, u64 ip) | |||
| 122 | h->ip[offset]); | 116 | h->ip[offset]); |
| 123 | } | 117 | } |
| 124 | 118 | ||
| 125 | static int hist_entry__add(struct addr_location *al, u64 count) | 119 | static int perf_session__add_hist_entry(struct perf_session *self, |
| 120 | struct addr_location *al, u64 count) | ||
| 126 | { | 121 | { |
| 127 | bool hit; | 122 | bool hit; |
| 128 | struct hist_entry *he = __hist_entry__add(al, NULL, count, &hit); | 123 | struct hist_entry *he = __perf_session__add_hist_entry(self, al, NULL, |
| 124 | count, &hit); | ||
| 129 | if (he == NULL) | 125 | if (he == NULL) |
| 130 | return -ENOMEM; | 126 | return -ENOMEM; |
| 131 | hist_hit(he, al->addr); | 127 | hist_hit(he, al->addr); |
| 132 | return 0; | 128 | return 0; |
| 133 | } | 129 | } |
| 134 | 130 | ||
| 135 | static int process_sample_event(event_t *event) | 131 | static int process_sample_event(event_t *event, struct perf_session *session) |
| 136 | { | 132 | { |
| 137 | struct addr_location al; | 133 | struct addr_location al; |
| 138 | 134 | ||
| 139 | dump_printf("(IP, %d): %d: %p\n", event->header.misc, | 135 | dump_printf("(IP, %d): %d: %p\n", event->header.misc, |
| 140 | event->ip.pid, (void *)(long)event->ip.ip); | 136 | event->ip.pid, (void *)(long)event->ip.ip); |
| 141 | 137 | ||
| 142 | if (event__preprocess_sample(event, &al, symbol_filter) < 0) { | 138 | if (event__preprocess_sample(event, session, &al, symbol_filter) < 0) { |
| 143 | fprintf(stderr, "problem processing %d event, skipping it.\n", | 139 | fprintf(stderr, "problem processing %d event, skipping it.\n", |
| 144 | event->header.type); | 140 | event->header.type); |
| 145 | return -1; | 141 | return -1; |
| 146 | } | 142 | } |
| 147 | 143 | ||
| 148 | if (hist_entry__add(&al, 1)) { | 144 | if (!al.filtered && perf_session__add_hist_entry(session, &al, 1)) { |
| 149 | fprintf(stderr, "problem incrementing symbol count, " | 145 | fprintf(stderr, "problem incrementing symbol count, " |
| 150 | "skipping event\n"); | 146 | "skipping event\n"); |
| 151 | return -1; | 147 | return -1; |
| @@ -429,11 +425,11 @@ static void annotate_sym(struct hist_entry *he) | |||
| 429 | free_source_line(he, len); | 425 | free_source_line(he, len); |
| 430 | } | 426 | } |
| 431 | 427 | ||
| 432 | static void find_annotations(void) | 428 | static void perf_session__find_annotations(struct perf_session *self) |
| 433 | { | 429 | { |
| 434 | struct rb_node *nd; | 430 | struct rb_node *nd; |
| 435 | 431 | ||
| 436 | for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) { | 432 | for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) { |
| 437 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); | 433 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); |
| 438 | struct sym_priv *priv; | 434 | struct sym_priv *priv; |
| 439 | 435 | ||
| @@ -454,7 +450,7 @@ static void find_annotations(void) | |||
| 454 | } | 450 | } |
| 455 | } | 451 | } |
| 456 | 452 | ||
| 457 | static struct perf_file_handler file_handler = { | 453 | static struct perf_event_ops event_ops = { |
| 458 | .process_sample_event = process_sample_event, | 454 | .process_sample_event = process_sample_event, |
| 459 | .process_mmap_event = event__process_mmap, | 455 | .process_mmap_event = event__process_mmap, |
| 460 | .process_comm_event = event__process_comm, | 456 | .process_comm_event = event__process_comm, |
| @@ -463,17 +459,14 @@ static struct perf_file_handler file_handler = { | |||
| 463 | 459 | ||
| 464 | static int __cmd_annotate(void) | 460 | static int __cmd_annotate(void) |
| 465 | { | 461 | { |
| 466 | struct perf_session *session = perf_session__new(input_name, O_RDONLY, force); | ||
| 467 | struct thread *idle; | ||
| 468 | int ret; | 462 | int ret; |
| 463 | struct perf_session *session; | ||
| 469 | 464 | ||
| 465 | session = perf_session__new(input_name, O_RDONLY, force); | ||
| 470 | if (session == NULL) | 466 | if (session == NULL) |
| 471 | return -ENOMEM; | 467 | return -ENOMEM; |
| 472 | 468 | ||
| 473 | idle = register_idle_thread(); | 469 | ret = perf_session__process_events(session, &event_ops); |
| 474 | register_perf_file_handler(&file_handler); | ||
| 475 | |||
| 476 | ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); | ||
| 477 | if (ret) | 470 | if (ret) |
| 478 | goto out_delete; | 471 | goto out_delete; |
| 479 | 472 | ||
| @@ -483,15 +476,14 @@ static int __cmd_annotate(void) | |||
| 483 | } | 476 | } |
| 484 | 477 | ||
| 485 | if (verbose > 3) | 478 | if (verbose > 3) |
| 486 | threads__fprintf(stdout); | 479 | perf_session__fprintf(session, stdout); |
| 487 | 480 | ||
| 488 | if (verbose > 2) | 481 | if (verbose > 2) |
| 489 | dsos__fprintf(stdout); | 482 | dsos__fprintf(stdout); |
| 490 | 483 | ||
| 491 | collapse__resort(); | 484 | perf_session__collapse_resort(session); |
| 492 | output__resort(event__total[0]); | 485 | perf_session__output_resort(session, session->event_total[0]); |
| 493 | 486 | perf_session__find_annotations(session); | |
| 494 | find_annotations(); | ||
| 495 | out_delete: | 487 | out_delete: |
| 496 | perf_session__delete(session); | 488 | perf_session__delete(session); |
| 497 | 489 | ||
| @@ -524,29 +516,17 @@ static const struct option options[] = { | |||
| 524 | OPT_END() | 516 | OPT_END() |
| 525 | }; | 517 | }; |
| 526 | 518 | ||
| 527 | static void setup_sorting(void) | 519 | int cmd_annotate(int argc, const char **argv, const char *prefix __used) |
| 528 | { | 520 | { |
| 529 | char *tmp, *tok, *str = strdup(sort_order); | 521 | argc = parse_options(argc, argv, options, annotate_usage, 0); |
| 530 | |||
| 531 | for (tok = strtok_r(str, ", ", &tmp); | ||
| 532 | tok; tok = strtok_r(NULL, ", ", &tmp)) { | ||
| 533 | if (sort_dimension__add(tok) < 0) { | ||
| 534 | error("Unknown --sort key: `%s'", tok); | ||
| 535 | usage_with_options(annotate_usage, options); | ||
| 536 | } | ||
| 537 | } | ||
| 538 | 522 | ||
| 539 | free(str); | 523 | symbol_conf.priv_size = sizeof(struct sym_priv); |
| 540 | } | 524 | symbol_conf.try_vmlinux_path = true; |
| 541 | 525 | ||
| 542 | int cmd_annotate(int argc, const char **argv, const char *prefix __used) | 526 | if (symbol__init() < 0) |
| 543 | { | ||
| 544 | if (symbol__init(&symbol_conf) < 0) | ||
| 545 | return -1; | 527 | return -1; |
| 546 | 528 | ||
| 547 | argc = parse_options(argc, argv, options, annotate_usage, 0); | 529 | setup_sorting(annotate_usage, options); |
| 548 | |||
| 549 | setup_sorting(); | ||
| 550 | 530 | ||
| 551 | if (argc) { | 531 | if (argc) { |
| 552 | /* | 532 | /* |
