perf: Enable more compiler warnings
[linux-2.6/btrfs-unstable.git] / tools / perf / builtin-annotate.c
blob32ff9838351efa727f0cff7fc9aeaceeffb08b61
1 /*
2 * builtin-annotate.c
4 * Builtin annotate command: Analyze the perf.data input file,
5 * look up and read DSOs and symbol information and display
6 * a histogram of results, along various sorting keys.
7 */
8 #include "builtin.h"
10 #include "util/util.h"
12 #include "util/color.h"
13 #include <linux/list.h>
14 #include "util/cache.h"
15 #include <linux/rbtree.h>
16 #include "util/symbol.h"
17 #include "util/string.h"
19 #include "perf.h"
21 #include "util/parse-options.h"
22 #include "util/parse-events.h"
23 #include "util/thread.h"
25 #define SHOW_KERNEL 1
26 #define SHOW_USER 2
27 #define SHOW_HV 4
29 static char const *input_name = "perf.data";
31 static char default_sort_order[] = "comm,symbol";
32 static char *sort_order = default_sort_order;
34 static int input;
35 static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
37 static int dump_trace = 0;
38 #define dprintf(x...) do { if (dump_trace) printf(x); } while (0)
41 static int full_paths;
43 static int print_line;
45 static unsigned long page_size;
46 static unsigned long mmap_window = 32;
48 static struct rb_root threads;
49 static struct thread *last_match;
52 struct sym_ext {
53 struct rb_node node;
54 double percent;
55 char *path;
59 * histogram, sorted on item, collects counts
62 static struct rb_root hist;
64 struct hist_entry {
65 struct rb_node rb_node;
67 struct thread *thread;
68 struct map *map;
69 struct dso *dso;
70 struct symbol *sym;
71 u64 ip;
72 char level;
74 uint32_t count;
78 * configurable sorting bits
81 struct sort_entry {
82 struct list_head list;
84 const char *header;
86 int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
87 int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
88 size_t (*print)(FILE *fp, struct hist_entry *);
91 /* --sort pid */
93 static int64_t
94 sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
96 return right->thread->pid - left->thread->pid;
99 static size_t
100 sort__thread_print(FILE *fp, struct hist_entry *self)
102 return fprintf(fp, "%16s:%5d", self->thread->comm ?: "", self->thread->pid);
105 static struct sort_entry sort_thread = {
106 .header = " Command: Pid",
107 .cmp = sort__thread_cmp,
108 .print = sort__thread_print,
111 /* --sort comm */
113 static int64_t
114 sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
116 return right->thread->pid - left->thread->pid;
119 static int64_t
120 sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
122 char *comm_l = left->thread->comm;
123 char *comm_r = right->thread->comm;
125 if (!comm_l || !comm_r) {
126 if (!comm_l && !comm_r)
127 return 0;
128 else if (!comm_l)
129 return -1;
130 else
131 return 1;
134 return strcmp(comm_l, comm_r);
137 static size_t
138 sort__comm_print(FILE *fp, struct hist_entry *self)
140 return fprintf(fp, "%16s", self->thread->comm);
143 static struct sort_entry sort_comm = {
144 .header = " Command",
145 .cmp = sort__comm_cmp,
146 .collapse = sort__comm_collapse,
147 .print = sort__comm_print,
150 /* --sort dso */
152 static int64_t
153 sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
155 struct dso *dso_l = left->dso;
156 struct dso *dso_r = right->dso;
158 if (!dso_l || !dso_r) {
159 if (!dso_l && !dso_r)
160 return 0;
161 else if (!dso_l)
162 return -1;
163 else
164 return 1;
167 return strcmp(dso_l->name, dso_r->name);
170 static size_t
171 sort__dso_print(FILE *fp, struct hist_entry *self)
173 if (self->dso)
174 return fprintf(fp, "%-25s", self->dso->name);
176 return fprintf(fp, "%016llx ", (u64)self->ip);
179 static struct sort_entry sort_dso = {
180 .header = "Shared Object ",
181 .cmp = sort__dso_cmp,
182 .print = sort__dso_print,
185 /* --sort symbol */
187 static int64_t
188 sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
190 u64 ip_l, ip_r;
192 if (left->sym == right->sym)
193 return 0;
195 ip_l = left->sym ? left->sym->start : left->ip;
196 ip_r = right->sym ? right->sym->start : right->ip;
198 return (int64_t)(ip_r - ip_l);
201 static size_t
202 sort__sym_print(FILE *fp, struct hist_entry *self)
204 size_t ret = 0;
206 if (verbose)
207 ret += fprintf(fp, "%#018llx ", (u64)self->ip);
209 if (self->sym) {
210 ret += fprintf(fp, "[%c] %s",
211 self->dso == kernel_dso ? 'k' : '.', self->sym->name);
212 } else {
213 ret += fprintf(fp, "%#016llx", (u64)self->ip);
216 return ret;
219 static struct sort_entry sort_sym = {
220 .header = "Symbol",
221 .cmp = sort__sym_cmp,
222 .print = sort__sym_print,
225 static int sort__need_collapse = 0;
227 struct sort_dimension {
228 const char *name;
229 struct sort_entry *entry;
230 int taken;
233 static struct sort_dimension sort_dimensions[] = {
234 { .name = "pid", .entry = &sort_thread, },
235 { .name = "comm", .entry = &sort_comm, },
236 { .name = "dso", .entry = &sort_dso, },
237 { .name = "symbol", .entry = &sort_sym, },
240 static LIST_HEAD(hist_entry__sort_list);
242 static int sort_dimension__add(char *tok)
244 unsigned int i;
246 for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
247 struct sort_dimension *sd = &sort_dimensions[i];
249 if (sd->taken)
250 continue;
252 if (strncasecmp(tok, sd->name, strlen(tok)))
253 continue;
255 if (sd->entry->collapse)
256 sort__need_collapse = 1;
258 list_add_tail(&sd->entry->list, &hist_entry__sort_list);
259 sd->taken = 1;
261 return 0;
264 return -ESRCH;
267 static int64_t
268 hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
270 struct sort_entry *se;
271 int64_t cmp = 0;
273 list_for_each_entry(se, &hist_entry__sort_list, list) {
274 cmp = se->cmp(left, right);
275 if (cmp)
276 break;
279 return cmp;
282 static int64_t
283 hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
285 struct sort_entry *se;
286 int64_t cmp = 0;
288 list_for_each_entry(se, &hist_entry__sort_list, list) {
289 int64_t (*f)(struct hist_entry *, struct hist_entry *);
291 f = se->collapse ?: se->cmp;
293 cmp = f(left, right);
294 if (cmp)
295 break;
298 return cmp;
302 * collect histogram counts
304 static void hist_hit(struct hist_entry *he, u64 ip)
306 unsigned int sym_size, offset;
307 struct symbol *sym = he->sym;
309 he->count++;
311 if (!sym || !sym->hist)
312 return;
314 sym_size = sym->end - sym->start;
315 offset = ip - sym->start;
317 if (offset >= sym_size)
318 return;
320 sym->hist_sum++;
321 sym->hist[offset]++;
323 if (verbose >= 3)
324 printf("%p %s: count++ [ip: %p, %08Lx] => %Ld\n",
325 (void *)(unsigned long)he->sym->start,
326 he->sym->name,
327 (void *)(unsigned long)ip, ip - he->sym->start,
328 sym->hist[offset]);
331 static int
332 hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
333 struct symbol *sym, u64 ip, char level)
335 struct rb_node **p = &hist.rb_node;
336 struct rb_node *parent = NULL;
337 struct hist_entry *he;
338 struct hist_entry entry = {
339 .thread = thread,
340 .map = map,
341 .dso = dso,
342 .sym = sym,
343 .ip = ip,
344 .level = level,
345 .count = 1,
347 int cmp;
349 while (*p != NULL) {
350 parent = *p;
351 he = rb_entry(parent, struct hist_entry, rb_node);
353 cmp = hist_entry__cmp(&entry, he);
355 if (!cmp) {
356 hist_hit(he, ip);
358 return 0;
361 if (cmp < 0)
362 p = &(*p)->rb_left;
363 else
364 p = &(*p)->rb_right;
367 he = malloc(sizeof(*he));
368 if (!he)
369 return -ENOMEM;
370 *he = entry;
371 rb_link_node(&he->rb_node, parent, p);
372 rb_insert_color(&he->rb_node, &hist);
374 return 0;
377 static void hist_entry__free(struct hist_entry *he)
379 free(he);
383 * collapse the histogram
386 static struct rb_root collapse_hists;
388 static void collapse__insert_entry(struct hist_entry *he)
390 struct rb_node **p = &collapse_hists.rb_node;
391 struct rb_node *parent = NULL;
392 struct hist_entry *iter;
393 int64_t cmp;
395 while (*p != NULL) {
396 parent = *p;
397 iter = rb_entry(parent, struct hist_entry, rb_node);
399 cmp = hist_entry__collapse(iter, he);
401 if (!cmp) {
402 iter->count += he->count;
403 hist_entry__free(he);
404 return;
407 if (cmp < 0)
408 p = &(*p)->rb_left;
409 else
410 p = &(*p)->rb_right;
413 rb_link_node(&he->rb_node, parent, p);
414 rb_insert_color(&he->rb_node, &collapse_hists);
417 static void collapse__resort(void)
419 struct rb_node *next;
420 struct hist_entry *n;
422 if (!sort__need_collapse)
423 return;
425 next = rb_first(&hist);
426 while (next) {
427 n = rb_entry(next, struct hist_entry, rb_node);
428 next = rb_next(&n->rb_node);
430 rb_erase(&n->rb_node, &hist);
431 collapse__insert_entry(n);
436 * reverse the map, sort on count.
439 static struct rb_root output_hists;
441 static void output__insert_entry(struct hist_entry *he)
443 struct rb_node **p = &output_hists.rb_node;
444 struct rb_node *parent = NULL;
445 struct hist_entry *iter;
447 while (*p != NULL) {
448 parent = *p;
449 iter = rb_entry(parent, struct hist_entry, rb_node);
451 if (he->count > iter->count)
452 p = &(*p)->rb_left;
453 else
454 p = &(*p)->rb_right;
457 rb_link_node(&he->rb_node, parent, p);
458 rb_insert_color(&he->rb_node, &output_hists);
461 static void output__resort(void)
463 struct rb_node *next;
464 struct hist_entry *n;
465 struct rb_root *tree = &hist;
467 if (sort__need_collapse)
468 tree = &collapse_hists;
470 next = rb_first(tree);
472 while (next) {
473 n = rb_entry(next, struct hist_entry, rb_node);
474 next = rb_next(&n->rb_node);
476 rb_erase(&n->rb_node, tree);
477 output__insert_entry(n);
481 static void register_idle_thread(void)
483 struct thread *thread = threads__findnew(0, &threads, &last_match);
485 if (thread == NULL ||
486 thread__set_comm(thread, "[idle]")) {
487 fprintf(stderr, "problem inserting idle task.\n");
488 exit(-1);
492 static unsigned long total = 0,
493 total_mmap = 0,
494 total_comm = 0,
495 total_fork = 0,
496 total_unknown = 0;
498 static int
499 process_sample_event(event_t *event, unsigned long offset, unsigned long head)
501 char level;
502 int show = 0;
503 struct dso *dso = NULL;
504 struct thread *thread;
505 u64 ip = event->ip.ip;
506 struct map *map = NULL;
508 thread = threads__findnew(event->ip.pid, &threads, &last_match);
510 dprintf("%p [%p]: PERF_EVENT (IP, %d): %d: %p\n",
511 (void *)(offset + head),
512 (void *)(long)(event->header.size),
513 event->header.misc,
514 event->ip.pid,
515 (void *)(long)ip);
517 dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid);
519 if (thread == NULL) {
520 fprintf(stderr, "problem processing %d event, skipping it.\n",
521 event->header.type);
522 return -1;
525 if (event->header.misc & PERF_EVENT_MISC_KERNEL) {
526 show = SHOW_KERNEL;
527 level = 'k';
529 dso = kernel_dso;
531 dprintf(" ...... dso: %s\n", dso->name);
533 } else if (event->header.misc & PERF_EVENT_MISC_USER) {
535 show = SHOW_USER;
536 level = '.';
538 map = thread__find_map(thread, ip);
539 if (map != NULL) {
540 ip = map->map_ip(map, ip);
541 dso = map->dso;
542 } else {
544 * If this is outside of all known maps,
545 * and is a negative address, try to look it
546 * up in the kernel dso, as it might be a
547 * vsyscall (which executes in user-mode):
549 if ((long long)ip < 0)
550 dso = kernel_dso;
552 dprintf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
554 } else {
555 show = SHOW_HV;
556 level = 'H';
557 dprintf(" ...... dso: [hypervisor]\n");
560 if (show & show_mask) {
561 struct symbol *sym = NULL;
563 if (dso)
564 sym = dso->find_symbol(dso, ip);
566 if (hist_entry__add(thread, map, dso, sym, ip, level)) {
567 fprintf(stderr,
568 "problem incrementing symbol count, skipping event\n");
569 return -1;
572 total++;
574 return 0;
577 static int
578 process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
580 struct thread *thread;
581 struct map *map = map__new(&event->mmap, NULL, 0);
583 thread = threads__findnew(event->mmap.pid, &threads, &last_match);
585 dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
586 (void *)(offset + head),
587 (void *)(long)(event->header.size),
588 event->mmap.pid,
589 (void *)(long)event->mmap.start,
590 (void *)(long)event->mmap.len,
591 (void *)(long)event->mmap.pgoff,
592 event->mmap.filename);
594 if (thread == NULL || map == NULL) {
595 dprintf("problem processing PERF_EVENT_MMAP, skipping event.\n");
596 return 0;
599 thread__insert_map(thread, map);
600 total_mmap++;
602 return 0;
605 static int
606 process_comm_event(event_t *event, unsigned long offset, unsigned long head)
608 struct thread *thread;
610 thread = threads__findnew(event->comm.pid, &threads, &last_match);
611 dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
612 (void *)(offset + head),
613 (void *)(long)(event->header.size),
614 event->comm.comm, event->comm.pid);
616 if (thread == NULL ||
617 thread__set_comm(thread, event->comm.comm)) {
618 dprintf("problem processing PERF_EVENT_COMM, skipping event.\n");
619 return -1;
621 total_comm++;
623 return 0;
626 static int
627 process_fork_event(event_t *event, unsigned long offset, unsigned long head)
629 struct thread *thread;
630 struct thread *parent;
632 thread = threads__findnew(event->fork.pid, &threads, &last_match);
633 parent = threads__findnew(event->fork.ppid, &threads, &last_match);
634 dprintf("%p [%p]: PERF_EVENT_FORK: %d:%d\n",
635 (void *)(offset + head),
636 (void *)(long)(event->header.size),
637 event->fork.pid, event->fork.ppid);
639 if (!thread || !parent || thread__fork(thread, parent)) {
640 dprintf("problem processing PERF_EVENT_FORK, skipping event.\n");
641 return -1;
643 total_fork++;
645 return 0;
648 static int
649 process_event(event_t *event, unsigned long offset, unsigned long head)
651 switch (event->header.type) {
652 case PERF_EVENT_SAMPLE:
653 return process_sample_event(event, offset, head);
655 case PERF_EVENT_MMAP:
656 return process_mmap_event(event, offset, head);
658 case PERF_EVENT_COMM:
659 return process_comm_event(event, offset, head);
661 case PERF_EVENT_FORK:
662 return process_fork_event(event, offset, head);
664 * We dont process them right now but they are fine:
667 case PERF_EVENT_THROTTLE:
668 case PERF_EVENT_UNTHROTTLE:
669 return 0;
671 default:
672 return -1;
675 return 0;
678 static int
679 parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
681 char *line = NULL, *tmp, *tmp2;
682 static const char *prev_line;
683 static const char *prev_color;
684 unsigned int offset;
685 size_t line_len;
686 s64 line_ip;
687 int ret;
688 char *c;
690 if (getline(&line, &line_len, file) < 0)
691 return -1;
692 if (!line)
693 return -1;
695 c = strchr(line, '\n');
696 if (c)
697 *c = 0;
699 line_ip = -1;
700 offset = 0;
701 ret = -2;
704 * Strip leading spaces:
706 tmp = line;
707 while (*tmp) {
708 if (*tmp != ' ')
709 break;
710 tmp++;
713 if (*tmp) {
715 * Parse hexa addresses followed by ':'
717 line_ip = strtoull(tmp, &tmp2, 16);
718 if (*tmp2 != ':')
719 line_ip = -1;
722 if (line_ip != -1) {
723 const char *path = NULL;
724 unsigned int hits = 0;
725 double percent = 0.0;
726 const char *color;
727 struct sym_ext *sym_ext = sym->priv;
729 offset = line_ip - start;
730 if (offset < len)
731 hits = sym->hist[offset];
733 if (offset < len && sym_ext) {
734 path = sym_ext[offset].path;
735 percent = sym_ext[offset].percent;
736 } else if (sym->hist_sum)
737 percent = 100.0 * hits / sym->hist_sum;
739 color = get_percent_color(percent);
742 * Also color the filename and line if needed, with
743 * the same color than the percentage. Don't print it
744 * twice for close colored ip with the same filename:line
746 if (path) {
747 if (!prev_line || strcmp(prev_line, path)
748 || color != prev_color) {
749 color_fprintf(stdout, color, " %s", path);
750 prev_line = path;
751 prev_color = color;
755 color_fprintf(stdout, color, " %7.2f", percent);
756 printf(" : ");
757 color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", line);
758 } else {
759 if (!*line)
760 printf(" :\n");
761 else
762 printf(" : %s\n", line);
765 return 0;
768 static struct rb_root root_sym_ext;
770 static void insert_source_line(struct sym_ext *sym_ext)
772 struct sym_ext *iter;
773 struct rb_node **p = &root_sym_ext.rb_node;
774 struct rb_node *parent = NULL;
776 while (*p != NULL) {
777 parent = *p;
778 iter = rb_entry(parent, struct sym_ext, node);
780 if (sym_ext->percent > iter->percent)
781 p = &(*p)->rb_left;
782 else
783 p = &(*p)->rb_right;
786 rb_link_node(&sym_ext->node, parent, p);
787 rb_insert_color(&sym_ext->node, &root_sym_ext);
790 static void free_source_line(struct symbol *sym, int len)
792 struct sym_ext *sym_ext = sym->priv;
793 int i;
795 if (!sym_ext)
796 return;
798 for (i = 0; i < len; i++)
799 free(sym_ext[i].path);
800 free(sym_ext);
802 sym->priv = NULL;
803 root_sym_ext = RB_ROOT;
806 /* Get the filename:line for the colored entries */
807 static void
808 get_source_line(struct symbol *sym, u64 start, int len, const char *filename)
810 int i;
811 char cmd[PATH_MAX * 2];
812 struct sym_ext *sym_ext;
814 if (!sym->hist_sum)
815 return;
817 sym->priv = calloc(len, sizeof(struct sym_ext));
818 if (!sym->priv)
819 return;
821 sym_ext = sym->priv;
823 for (i = 0; i < len; i++) {
824 char *path = NULL;
825 size_t line_len;
826 u64 offset;
827 FILE *fp;
829 sym_ext[i].percent = 100.0 * sym->hist[i] / sym->hist_sum;
830 if (sym_ext[i].percent <= 0.5)
831 continue;
833 offset = start + i;
834 sprintf(cmd, "addr2line -e %s %016llx", filename, offset);
835 fp = popen(cmd, "r");
836 if (!fp)
837 continue;
839 if (getline(&path, &line_len, fp) < 0 || !line_len)
840 goto next;
842 sym_ext[i].path = malloc(sizeof(char) * line_len + 1);
843 if (!sym_ext[i].path)
844 goto next;
846 strcpy(sym_ext[i].path, path);
847 insert_source_line(&sym_ext[i]);
849 next:
850 pclose(fp);
854 static void print_summary(const char *filename)
856 struct sym_ext *sym_ext;
857 struct rb_node *node;
859 printf("\nSorted summary for file %s\n", filename);
860 printf("----------------------------------------------\n\n");
862 if (RB_EMPTY_ROOT(&root_sym_ext)) {
863 printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
864 return;
867 node = rb_first(&root_sym_ext);
868 while (node) {
869 double percent;
870 const char *color;
871 char *path;
873 sym_ext = rb_entry(node, struct sym_ext, node);
874 percent = sym_ext->percent;
875 color = get_percent_color(percent);
876 path = sym_ext->path;
878 color_fprintf(stdout, color, " %7.2f %s", percent, path);
879 node = rb_next(node);
883 static void annotate_sym(struct dso *dso, struct symbol *sym)
885 const char *filename = dso->name, *d_filename;
886 u64 start, end, len;
887 char command[PATH_MAX*2];
888 FILE *file;
890 if (!filename)
891 return;
892 if (sym->module)
893 filename = sym->module->path;
894 else if (dso == kernel_dso)
895 filename = vmlinux_name;
897 start = sym->obj_start;
898 if (!start)
899 start = sym->start;
900 if (full_paths)
901 d_filename = filename;
902 else
903 d_filename = basename(filename);
905 end = start + sym->end - sym->start + 1;
906 len = sym->end - sym->start;
908 if (print_line) {
909 get_source_line(sym, start, len, filename);
910 print_summary(filename);
913 printf("\n\n------------------------------------------------\n");
914 printf(" Percent | Source code & Disassembly of %s\n", d_filename);
915 printf("------------------------------------------------\n");
917 if (verbose >= 2)
918 printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
920 sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s",
921 (u64)start, (u64)end, filename, filename);
923 if (verbose >= 3)
924 printf("doing: %s\n", command);
926 file = popen(command, "r");
927 if (!file)
928 return;
930 while (!feof(file)) {
931 if (parse_line(file, sym, start, len) < 0)
932 break;
935 pclose(file);
936 if (print_line)
937 free_source_line(sym, len);
940 static void find_annotations(void)
942 struct rb_node *nd;
943 struct dso *dso;
944 int count = 0;
946 list_for_each_entry(dso, &dsos, node) {
948 for (nd = rb_first(&dso->syms); nd; nd = rb_next(nd)) {
949 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
951 if (sym->hist) {
952 annotate_sym(dso, sym);
953 count++;
958 if (!count)
959 printf(" Error: symbol '%s' not present amongst the samples.\n", sym_hist_filter);
962 static int __cmd_annotate(void)
964 int ret, rc = EXIT_FAILURE;
965 unsigned long offset = 0;
966 unsigned long head = 0;
967 struct stat input_stat;
968 event_t *event;
969 uint32_t size;
970 char *buf;
972 register_idle_thread();
974 input = open(input_name, O_RDONLY);
975 if (input < 0) {
976 perror("failed to open file");
977 exit(-1);
980 ret = fstat(input, &input_stat);
981 if (ret < 0) {
982 perror("failed to stat file");
983 exit(-1);
986 if (!input_stat.st_size) {
987 fprintf(stderr, "zero-sized file, nothing to do!\n");
988 exit(0);
991 if (load_kernel() < 0) {
992 perror("failed to load kernel symbols");
993 return EXIT_FAILURE;
996 remap:
997 buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
998 MAP_SHARED, input, offset);
999 if (buf == MAP_FAILED) {
1000 perror("failed to mmap file");
1001 exit(-1);
1004 more:
1005 event = (event_t *)(buf + head);
1007 size = event->header.size;
1008 if (!size)
1009 size = 8;
1011 if (head + event->header.size >= page_size * mmap_window) {
1012 unsigned long shift = page_size * (head / page_size);
1013 int munmap_ret;
1015 munmap_ret = munmap(buf, page_size * mmap_window);
1016 assert(munmap_ret == 0);
1018 offset += shift;
1019 head -= shift;
1020 goto remap;
1023 size = event->header.size;
1025 dprintf("%p [%p]: event: %d\n",
1026 (void *)(offset + head),
1027 (void *)(long)event->header.size,
1028 event->header.type);
1030 if (!size || process_event(event, offset, head) < 0) {
1032 dprintf("%p [%p]: skipping unknown header type: %d\n",
1033 (void *)(offset + head),
1034 (void *)(long)(event->header.size),
1035 event->header.type);
1037 total_unknown++;
1040 * assume we lost track of the stream, check alignment, and
1041 * increment a single u64 in the hope to catch on again 'soon'.
1044 if (unlikely(head & 7))
1045 head &= ~7ULL;
1047 size = 8;
1050 head += size;
1052 if (offset + head < (unsigned long)input_stat.st_size)
1053 goto more;
1055 rc = EXIT_SUCCESS;
1056 close(input);
1058 dprintf(" IP events: %10ld\n", total);
1059 dprintf(" mmap events: %10ld\n", total_mmap);
1060 dprintf(" comm events: %10ld\n", total_comm);
1061 dprintf(" fork events: %10ld\n", total_fork);
1062 dprintf(" unknown events: %10ld\n", total_unknown);
1064 if (dump_trace)
1065 return 0;
1067 if (verbose >= 3)
1068 threads__fprintf(stdout, &threads);
1070 if (verbose >= 2)
1071 dsos__fprintf(stdout);
1073 collapse__resort();
1074 output__resort();
1076 find_annotations();
1078 return rc;
1081 static const char * const annotate_usage[] = {
1082 "perf annotate [<options>] <command>",
1083 NULL
1086 static const struct option options[] = {
1087 OPT_STRING('i', "input", &input_name, "file",
1088 "input file name"),
1089 OPT_STRING('s', "symbol", &sym_hist_filter, "symbol",
1090 "symbol to annotate"),
1091 OPT_BOOLEAN('v', "verbose", &verbose,
1092 "be more verbose (show symbol address, etc)"),
1093 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1094 "dump raw trace in ASCII"),
1095 OPT_STRING('k', "vmlinux", &vmlinux_name, "file", "vmlinux pathname"),
1096 OPT_BOOLEAN('m', "modules", &modules,
1097 "load module symbols - WARNING: use only with -k and LIVE kernel"),
1098 OPT_BOOLEAN('l', "print-line", &print_line,
1099 "print matching source lines (may be slow)"),
1100 OPT_BOOLEAN('P', "full-paths", &full_paths,
1101 "Don't shorten the displayed pathnames"),
1102 OPT_END()
1105 static void setup_sorting(void)
1107 char *tmp, *tok, *str = strdup(sort_order);
1109 for (tok = strtok_r(str, ", ", &tmp);
1110 tok; tok = strtok_r(NULL, ", ", &tmp)) {
1111 if (sort_dimension__add(tok) < 0) {
1112 error("Unknown --sort key: `%s'", tok);
1113 usage_with_options(annotate_usage, options);
1117 free(str);
1120 int cmd_annotate(int argc, const char **argv, const char *prefix __used)
1122 symbol__init();
1124 page_size = getpagesize();
1126 argc = parse_options(argc, argv, options, annotate_usage, 0);
1128 setup_sorting();
1130 if (argc) {
1132 * Special case: if there's an argument left then assume tha
1133 * it's a symbol filter:
1135 if (argc > 1)
1136 usage_with_options(annotate_usage, options);
1138 sym_hist_filter = argv[0];
1141 if (!sym_hist_filter)
1142 usage_with_options(annotate_usage, options);
1144 setup_pager();
1146 return __cmd_annotate();