3b9d24dc0edadfbf2469dcab426881d8365ae65c
[safe/jmp/linux-2.6] / tools / perf / builtin-report.c
1 /*
2  * builtin-report.c
3  *
4  * Builtin report 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"
9
10 #include "util/util.h"
11
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"
18 #include "util/callchain.h"
19 #include "util/strlist.h"
20 #include "util/values.h"
21
22 #include "perf.h"
23 #include "util/header.h"
24
25 #include "util/parse-options.h"
26 #include "util/parse-events.h"
27
28 #include "util/thread.h"
29
30 #define SHOW_KERNEL     1
31 #define SHOW_USER       2
32 #define SHOW_HV         4
33
34 static char             const *input_name = "perf.data";
35
36 static char             default_sort_order[] = "comm,dso,symbol";
37 static char             *sort_order = default_sort_order;
38 static char             *dso_list_str, *comm_list_str, *sym_list_str,
39                         *col_width_list_str;
40 static struct strlist   *dso_list, *comm_list, *sym_list;
41 static char             *field_sep;
42
43 static int              input;
44 static int              show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
45
46 static int              dump_trace = 0;
47 #define dprintf(x...)   do { if (dump_trace) printf(x); } while (0)
48 #define cdprintf(x...)  do { if (dump_trace) color_fprintf(stdout, color, x); } while (0)
49
50 static int              full_paths;
51 static int              show_nr_samples;
52
53 static int              show_threads;
54 static struct perf_read_values  show_threads_values;
55
56 static char             default_pretty_printing_style[] = "normal";
57 static char             *pretty_printing_style = default_pretty_printing_style;
58
59 static unsigned long    page_size;
60 static unsigned long    mmap_window = 32;
61
62 static char             default_parent_pattern[] = "^sys_|^do_page_fault";
63 static char             *parent_pattern = default_parent_pattern;
64 static regex_t          parent_regex;
65
66 static int              exclude_other = 1;
67
68 static char             callchain_default_opt[] = "fractal,0.5";
69
70 static int              callchain;
71
72 static char             __cwd[PATH_MAX];
73 static char             *cwd = __cwd;
74 static int              cwdlen;
75
76 static struct rb_root   threads;
77 static struct thread    *last_match;
78
79 static
80 struct callchain_param  callchain_param = {
81         .mode   = CHAIN_GRAPH_REL,
82         .min_percent = 0.5
83 };
84
85 static u64              sample_type;
86
87 static int repsep_fprintf(FILE *fp, const char *fmt, ...)
88 {
89         int n;
90         va_list ap;
91
92         va_start(ap, fmt);
93         if (!field_sep)
94                 n = vfprintf(fp, fmt, ap);
95         else {
96                 char *bf = NULL;
97                 n = vasprintf(&bf, fmt, ap);
98                 if (n > 0) {
99                         char *sep = bf;
100
101                         while (1) {
102                                 sep = strchr(sep, *field_sep);
103                                 if (sep == NULL)
104                                         break;
105                                 *sep = '.';
106                         }
107                 }
108                 fputs(bf, fp);
109                 free(bf);
110         }
111         va_end(ap);
112         return n;
113 }
114
115 static unsigned int dsos__col_width,
116                     comms__col_width,
117                     threads__col_width;
118
119 /*
120  * histogram, sorted on item, collects counts
121  */
122
123 static struct rb_root hist;
124
125 struct hist_entry {
126         struct rb_node          rb_node;
127
128         struct thread           *thread;
129         struct map              *map;
130         struct dso              *dso;
131         struct symbol           *sym;
132         struct symbol           *parent;
133         u64                     ip;
134         char                    level;
135         struct callchain_node   callchain;
136         struct rb_root          sorted_chain;
137
138         u64                     count;
139 };
140
141 /*
142  * configurable sorting bits
143  */
144
145 struct sort_entry {
146         struct list_head list;
147
148         const char *header;
149
150         int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
151         int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
152         size_t  (*print)(FILE *fp, struct hist_entry *, unsigned int width);
153         unsigned int *width;
154         bool    elide;
155 };
156
157 static int64_t cmp_null(void *l, void *r)
158 {
159         if (!l && !r)
160                 return 0;
161         else if (!l)
162                 return -1;
163         else
164                 return 1;
165 }
166
167 /* --sort pid */
168
169 static int64_t
170 sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
171 {
172         return right->thread->pid - left->thread->pid;
173 }
174
175 static size_t
176 sort__thread_print(FILE *fp, struct hist_entry *self, unsigned int width)
177 {
178         return repsep_fprintf(fp, "%*s:%5d", width - 6,
179                               self->thread->comm ?: "", self->thread->pid);
180 }
181
182 static struct sort_entry sort_thread = {
183         .header = "Command:  Pid",
184         .cmp    = sort__thread_cmp,
185         .print  = sort__thread_print,
186         .width  = &threads__col_width,
187 };
188
189 /* --sort comm */
190
191 static int64_t
192 sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
193 {
194         return right->thread->pid - left->thread->pid;
195 }
196
197 static int64_t
198 sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
199 {
200         char *comm_l = left->thread->comm;
201         char *comm_r = right->thread->comm;
202
203         if (!comm_l || !comm_r)
204                 return cmp_null(comm_l, comm_r);
205
206         return strcmp(comm_l, comm_r);
207 }
208
209 static size_t
210 sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width)
211 {
212         return repsep_fprintf(fp, "%*s", width, self->thread->comm);
213 }
214
215 static struct sort_entry sort_comm = {
216         .header         = "Command",
217         .cmp            = sort__comm_cmp,
218         .collapse       = sort__comm_collapse,
219         .print          = sort__comm_print,
220         .width          = &comms__col_width,
221 };
222
223 /* --sort dso */
224
225 static int64_t
226 sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
227 {
228         struct dso *dso_l = left->dso;
229         struct dso *dso_r = right->dso;
230
231         if (!dso_l || !dso_r)
232                 return cmp_null(dso_l, dso_r);
233
234         return strcmp(dso_l->name, dso_r->name);
235 }
236
237 static size_t
238 sort__dso_print(FILE *fp, struct hist_entry *self, unsigned int width)
239 {
240         if (self->dso)
241                 return repsep_fprintf(fp, "%-*s", width, self->dso->name);
242
243         return repsep_fprintf(fp, "%*llx", width, (u64)self->ip);
244 }
245
246 static struct sort_entry sort_dso = {
247         .header = "Shared Object",
248         .cmp    = sort__dso_cmp,
249         .print  = sort__dso_print,
250         .width  = &dsos__col_width,
251 };
252
253 /* --sort symbol */
254
255 static int64_t
256 sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
257 {
258         u64 ip_l, ip_r;
259
260         if (left->sym == right->sym)
261                 return 0;
262
263         ip_l = left->sym ? left->sym->start : left->ip;
264         ip_r = right->sym ? right->sym->start : right->ip;
265
266         return (int64_t)(ip_r - ip_l);
267 }
268
269 static size_t
270 sort__sym_print(FILE *fp, struct hist_entry *self, unsigned int width __used)
271 {
272         size_t ret = 0;
273
274         if (verbose)
275                 ret += repsep_fprintf(fp, "%#018llx %c ", (u64)self->ip,
276                                       dso__symtab_origin(self->dso));
277
278         ret += repsep_fprintf(fp, "[%c] ", self->level);
279         if (self->sym) {
280                 ret += repsep_fprintf(fp, "%s", self->sym->name);
281
282                 if (self->sym->module)
283                         ret += repsep_fprintf(fp, "\t[%s]",
284                                              self->sym->module->name);
285         } else {
286                 ret += repsep_fprintf(fp, "%#016llx", (u64)self->ip);
287         }
288
289         return ret;
290 }
291
292 static struct sort_entry sort_sym = {
293         .header = "Symbol",
294         .cmp    = sort__sym_cmp,
295         .print  = sort__sym_print,
296 };
297
298 /* --sort parent */
299
300 static int64_t
301 sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
302 {
303         struct symbol *sym_l = left->parent;
304         struct symbol *sym_r = right->parent;
305
306         if (!sym_l || !sym_r)
307                 return cmp_null(sym_l, sym_r);
308
309         return strcmp(sym_l->name, sym_r->name);
310 }
311
312 static size_t
313 sort__parent_print(FILE *fp, struct hist_entry *self, unsigned int width)
314 {
315         return repsep_fprintf(fp, "%-*s", width,
316                               self->parent ? self->parent->name : "[other]");
317 }
318
319 static unsigned int parent_symbol__col_width;
320
321 static struct sort_entry sort_parent = {
322         .header = "Parent symbol",
323         .cmp    = sort__parent_cmp,
324         .print  = sort__parent_print,
325         .width  = &parent_symbol__col_width,
326 };
327
328 static int sort__need_collapse = 0;
329 static int sort__has_parent = 0;
330
331 struct sort_dimension {
332         const char              *name;
333         struct sort_entry       *entry;
334         int                     taken;
335 };
336
337 static struct sort_dimension sort_dimensions[] = {
338         { .name = "pid",        .entry = &sort_thread,  },
339         { .name = "comm",       .entry = &sort_comm,    },
340         { .name = "dso",        .entry = &sort_dso,     },
341         { .name = "symbol",     .entry = &sort_sym,     },
342         { .name = "parent",     .entry = &sort_parent,  },
343 };
344
345 static LIST_HEAD(hist_entry__sort_list);
346
347 static int sort_dimension__add(const char *tok)
348 {
349         unsigned int i;
350
351         for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
352                 struct sort_dimension *sd = &sort_dimensions[i];
353
354                 if (sd->taken)
355                         continue;
356
357                 if (strncasecmp(tok, sd->name, strlen(tok)))
358                         continue;
359
360                 if (sd->entry->collapse)
361                         sort__need_collapse = 1;
362
363                 if (sd->entry == &sort_parent) {
364                         int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
365                         if (ret) {
366                                 char err[BUFSIZ];
367
368                                 regerror(ret, &parent_regex, err, sizeof(err));
369                                 fprintf(stderr, "Invalid regex: %s\n%s",
370                                         parent_pattern, err);
371                                 exit(-1);
372                         }
373                         sort__has_parent = 1;
374                 }
375
376                 list_add_tail(&sd->entry->list, &hist_entry__sort_list);
377                 sd->taken = 1;
378
379                 return 0;
380         }
381
382         return -ESRCH;
383 }
384
385 static int64_t
386 hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
387 {
388         struct sort_entry *se;
389         int64_t cmp = 0;
390
391         list_for_each_entry(se, &hist_entry__sort_list, list) {
392                 cmp = se->cmp(left, right);
393                 if (cmp)
394                         break;
395         }
396
397         return cmp;
398 }
399
400 static int64_t
401 hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
402 {
403         struct sort_entry *se;
404         int64_t cmp = 0;
405
406         list_for_each_entry(se, &hist_entry__sort_list, list) {
407                 int64_t (*f)(struct hist_entry *, struct hist_entry *);
408
409                 f = se->collapse ?: se->cmp;
410
411                 cmp = f(left, right);
412                 if (cmp)
413                         break;
414         }
415
416         return cmp;
417 }
418
419 static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask)
420 {
421         int i;
422         size_t ret = 0;
423
424         ret += fprintf(fp, "%s", "                ");
425
426         for (i = 0; i < depth; i++)
427                 if (depth_mask & (1 << i))
428                         ret += fprintf(fp, "|          ");
429                 else
430                         ret += fprintf(fp, "           ");
431
432         ret += fprintf(fp, "\n");
433
434         return ret;
435 }
436 static size_t
437 ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth,
438                        int depth_mask, int count, u64 total_samples,
439                        int hits)
440 {
441         int i;
442         size_t ret = 0;
443
444         ret += fprintf(fp, "%s", "                ");
445         for (i = 0; i < depth; i++) {
446                 if (depth_mask & (1 << i))
447                         ret += fprintf(fp, "|");
448                 else
449                         ret += fprintf(fp, " ");
450                 if (!count && i == depth - 1) {
451                         double percent;
452
453                         percent = hits * 100.0 / total_samples;
454                         ret += percent_color_fprintf(fp, "--%2.2f%%-- ", percent);
455                 } else
456                         ret += fprintf(fp, "%s", "          ");
457         }
458         if (chain->sym)
459                 ret += fprintf(fp, "%s\n", chain->sym->name);
460         else
461                 ret += fprintf(fp, "%p\n", (void *)(long)chain->ip);
462
463         return ret;
464 }
465
466 static struct symbol *rem_sq_bracket;
467 static struct callchain_list rem_hits;
468
469 static void init_rem_hits(void)
470 {
471         rem_sq_bracket = malloc(sizeof(*rem_sq_bracket) + 6);
472         if (!rem_sq_bracket) {
473                 fprintf(stderr, "Not enough memory to display remaining hits\n");
474                 return;
475         }
476
477         strcpy(rem_sq_bracket->name, "[...]");
478         rem_hits.sym = rem_sq_bracket;
479 }
480
481 static size_t
482 callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
483                         u64 total_samples, int depth, int depth_mask)
484 {
485         struct rb_node *node, *next;
486         struct callchain_node *child;
487         struct callchain_list *chain;
488         int new_depth_mask = depth_mask;
489         u64 new_total;
490         u64 remaining;
491         size_t ret = 0;
492         int i;
493
494         if (callchain_param.mode == CHAIN_GRAPH_REL)
495                 new_total = self->children_hit;
496         else
497                 new_total = total_samples;
498
499         remaining = new_total;
500
501         node = rb_first(&self->rb_root);
502         while (node) {
503                 u64 cumul;
504
505                 child = rb_entry(node, struct callchain_node, rb_node);
506                 cumul = cumul_hits(child);
507                 remaining -= cumul;
508
509                 /*
510                  * The depth mask manages the output of pipes that show
511                  * the depth. We don't want to keep the pipes of the current
512                  * level for the last child of this depth.
513                  * Except if we have remaining filtered hits. They will
514                  * supersede the last child
515                  */
516                 next = rb_next(node);
517                 if (!next && (callchain_param.mode != CHAIN_GRAPH_REL || !remaining))
518                         new_depth_mask &= ~(1 << (depth - 1));
519
520                 /*
521                  * But we keep the older depth mask for the line seperator
522                  * to keep the level link until we reach the last child
523                  */
524                 ret += ipchain__fprintf_graph_line(fp, depth, depth_mask);
525                 i = 0;
526                 list_for_each_entry(chain, &child->val, list) {
527                         if (chain->ip >= PERF_CONTEXT_MAX)
528                                 continue;
529                         ret += ipchain__fprintf_graph(fp, chain, depth,
530                                                       new_depth_mask, i++,
531                                                       new_total,
532                                                       cumul);
533                 }
534                 ret += callchain__fprintf_graph(fp, child, new_total,
535                                                 depth + 1,
536                                                 new_depth_mask | (1 << depth));
537                 node = next;
538         }
539
540         if (callchain_param.mode == CHAIN_GRAPH_REL &&
541                 remaining && remaining != new_total) {
542
543                 if (!rem_sq_bracket)
544                         return ret;
545
546                 new_depth_mask &= ~(1 << (depth - 1));
547
548                 ret += ipchain__fprintf_graph(fp, &rem_hits, depth,
549                                               new_depth_mask, 0, new_total,
550                                               remaining);
551         }
552
553         return ret;
554 }
555
556 static size_t
557 callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
558                         u64 total_samples)
559 {
560         struct callchain_list *chain;
561         size_t ret = 0;
562
563         if (!self)
564                 return 0;
565
566         ret += callchain__fprintf_flat(fp, self->parent, total_samples);
567
568
569         list_for_each_entry(chain, &self->val, list) {
570                 if (chain->ip >= PERF_CONTEXT_MAX)
571                         continue;
572                 if (chain->sym)
573                         ret += fprintf(fp, "                %s\n", chain->sym->name);
574                 else
575                         ret += fprintf(fp, "                %p\n",
576                                         (void *)(long)chain->ip);
577         }
578
579         return ret;
580 }
581
582 static size_t
583 hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
584                               u64 total_samples)
585 {
586         struct rb_node *rb_node;
587         struct callchain_node *chain;
588         size_t ret = 0;
589
590         rb_node = rb_first(&self->sorted_chain);
591         while (rb_node) {
592                 double percent;
593
594                 chain = rb_entry(rb_node, struct callchain_node, rb_node);
595                 percent = chain->hit * 100.0 / total_samples;
596                 switch (callchain_param.mode) {
597                 case CHAIN_FLAT:
598                         ret += percent_color_fprintf(fp, "           %6.2f%%\n",
599                                                      percent);
600                         ret += callchain__fprintf_flat(fp, chain, total_samples);
601                         break;
602                 case CHAIN_GRAPH_ABS: /* Falldown */
603                 case CHAIN_GRAPH_REL:
604                         ret += callchain__fprintf_graph(fp, chain,
605                                                         total_samples, 1, 1);
606                 case CHAIN_NONE:
607                 default:
608                         break;
609                 }
610                 ret += fprintf(fp, "\n");
611                 rb_node = rb_next(rb_node);
612         }
613
614         return ret;
615 }
616
617
618 static size_t
619 hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
620 {
621         struct sort_entry *se;
622         size_t ret;
623
624         if (exclude_other && !self->parent)
625                 return 0;
626
627         if (total_samples)
628                 ret = percent_color_fprintf(fp,
629                                             field_sep ? "%.2f" : "   %6.2f%%",
630                                         (self->count * 100.0) / total_samples);
631         else
632                 ret = fprintf(fp, field_sep ? "%lld" : "%12lld ", self->count);
633
634         if (show_nr_samples) {
635                 if (field_sep)
636                         fprintf(fp, "%c%lld", *field_sep, self->count);
637                 else
638                         fprintf(fp, "%11lld", self->count);
639         }
640
641         list_for_each_entry(se, &hist_entry__sort_list, list) {
642                 if (se->elide)
643                         continue;
644
645                 fprintf(fp, "%s", field_sep ?: "  ");
646                 ret += se->print(fp, self, se->width ? *se->width : 0);
647         }
648
649         ret += fprintf(fp, "\n");
650
651         if (callchain)
652                 hist_entry_callchain__fprintf(fp, self, total_samples);
653
654         return ret;
655 }
656
657 /*
658  *
659  */
660
661 static void dso__calc_col_width(struct dso *self)
662 {
663         if (!col_width_list_str && !field_sep &&
664             (!dso_list || strlist__has_entry(dso_list, self->name))) {
665                 unsigned int slen = strlen(self->name);
666                 if (slen > dsos__col_width)
667                         dsos__col_width = slen;
668         }
669
670         self->slen_calculated = 1;
671 }
672
673 static struct symbol *
674 resolve_symbol(struct thread *thread, struct map **mapp,
675                struct dso **dsop, u64 *ipp)
676 {
677         struct dso *dso = dsop ? *dsop : NULL;
678         struct map *map = mapp ? *mapp : NULL;
679         u64 ip = *ipp;
680
681         if (!thread)
682                 return NULL;
683
684         if (dso)
685                 goto got_dso;
686
687         if (map)
688                 goto got_map;
689
690         map = thread__find_map(thread, ip);
691         if (map != NULL) {
692                 /*
693                  * We have to do this here as we may have a dso
694                  * with no symbol hit that has a name longer than
695                  * the ones with symbols sampled.
696                  */
697                 if (!sort_dso.elide && !map->dso->slen_calculated)
698                         dso__calc_col_width(map->dso);
699
700                 if (mapp)
701                         *mapp = map;
702 got_map:
703                 ip = map->map_ip(map, ip);
704
705                 dso = map->dso;
706         } else {
707                 /*
708                  * If this is outside of all known maps,
709                  * and is a negative address, try to look it
710                  * up in the kernel dso, as it might be a
711                  * vsyscall (which executes in user-mode):
712                  */
713                 if ((long long)ip < 0)
714                 dso = kernel_dso;
715         }
716         dprintf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
717         dprintf(" ...... map: %Lx -> %Lx\n", *ipp, ip);
718         *ipp  = ip;
719
720         if (dsop)
721                 *dsop = dso;
722
723         if (!dso)
724                 return NULL;
725 got_dso:
726         return dso->find_symbol(dso, ip);
727 }
728
729 static int call__match(struct symbol *sym)
730 {
731         if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
732                 return 1;
733
734         return 0;
735 }
736
737 static struct symbol **
738 resolve_callchain(struct thread *thread, struct map *map __used,
739                     struct ip_callchain *chain, struct hist_entry *entry)
740 {
741         u64 context = PERF_CONTEXT_MAX;
742         struct symbol **syms = NULL;
743         unsigned int i;
744
745         if (callchain) {
746                 syms = calloc(chain->nr, sizeof(*syms));
747                 if (!syms) {
748                         fprintf(stderr, "Can't allocate memory for symbols\n");
749                         exit(-1);
750                 }
751         }
752
753         for (i = 0; i < chain->nr; i++) {
754                 u64 ip = chain->ips[i];
755                 struct dso *dso = NULL;
756                 struct symbol *sym;
757
758                 if (ip >= PERF_CONTEXT_MAX) {
759                         context = ip;
760                         continue;
761                 }
762
763                 switch (context) {
764                 case PERF_CONTEXT_HV:
765                         dso = hypervisor_dso;
766                         break;
767                 case PERF_CONTEXT_KERNEL:
768                         dso = kernel_dso;
769                         break;
770                 default:
771                         break;
772                 }
773
774                 sym = resolve_symbol(thread, NULL, &dso, &ip);
775
776                 if (sym) {
777                         if (sort__has_parent && call__match(sym) &&
778                             !entry->parent)
779                                 entry->parent = sym;
780                         if (!callchain)
781                                 break;
782                         syms[i] = sym;
783                 }
784         }
785
786         return syms;
787 }
788
789 /*
790  * collect histogram counts
791  */
792
793 static int
794 hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
795                 struct symbol *sym, u64 ip, struct ip_callchain *chain,
796                 char level, u64 count)
797 {
798         struct rb_node **p = &hist.rb_node;
799         struct rb_node *parent = NULL;
800         struct hist_entry *he;
801         struct symbol **syms = NULL;
802         struct hist_entry entry = {
803                 .thread = thread,
804                 .map    = map,
805                 .dso    = dso,
806                 .sym    = sym,
807                 .ip     = ip,
808                 .level  = level,
809                 .count  = count,
810                 .parent = NULL,
811                 .sorted_chain = RB_ROOT
812         };
813         int cmp;
814
815         if ((sort__has_parent || callchain) && chain)
816                 syms = resolve_callchain(thread, map, chain, &entry);
817
818         while (*p != NULL) {
819                 parent = *p;
820                 he = rb_entry(parent, struct hist_entry, rb_node);
821
822                 cmp = hist_entry__cmp(&entry, he);
823
824                 if (!cmp) {
825                         he->count += count;
826                         if (callchain) {
827                                 append_chain(&he->callchain, chain, syms);
828                                 free(syms);
829                         }
830                         return 0;
831                 }
832
833                 if (cmp < 0)
834                         p = &(*p)->rb_left;
835                 else
836                         p = &(*p)->rb_right;
837         }
838
839         he = malloc(sizeof(*he));
840         if (!he)
841                 return -ENOMEM;
842         *he = entry;
843         if (callchain) {
844                 callchain_init(&he->callchain);
845                 append_chain(&he->callchain, chain, syms);
846                 free(syms);
847         }
848         rb_link_node(&he->rb_node, parent, p);
849         rb_insert_color(&he->rb_node, &hist);
850
851         return 0;
852 }
853
854 static void hist_entry__free(struct hist_entry *he)
855 {
856         free(he);
857 }
858
859 /*
860  * collapse the histogram
861  */
862
863 static struct rb_root collapse_hists;
864
865 static void collapse__insert_entry(struct hist_entry *he)
866 {
867         struct rb_node **p = &collapse_hists.rb_node;
868         struct rb_node *parent = NULL;
869         struct hist_entry *iter;
870         int64_t cmp;
871
872         while (*p != NULL) {
873                 parent = *p;
874                 iter = rb_entry(parent, struct hist_entry, rb_node);
875
876                 cmp = hist_entry__collapse(iter, he);
877
878                 if (!cmp) {
879                         iter->count += he->count;
880                         hist_entry__free(he);
881                         return;
882                 }
883
884                 if (cmp < 0)
885                         p = &(*p)->rb_left;
886                 else
887                         p = &(*p)->rb_right;
888         }
889
890         rb_link_node(&he->rb_node, parent, p);
891         rb_insert_color(&he->rb_node, &collapse_hists);
892 }
893
894 static void collapse__resort(void)
895 {
896         struct rb_node *next;
897         struct hist_entry *n;
898
899         if (!sort__need_collapse)
900                 return;
901
902         next = rb_first(&hist);
903         while (next) {
904                 n = rb_entry(next, struct hist_entry, rb_node);
905                 next = rb_next(&n->rb_node);
906
907                 rb_erase(&n->rb_node, &hist);
908                 collapse__insert_entry(n);
909         }
910 }
911
912 /*
913  * reverse the map, sort on count.
914  */
915
916 static struct rb_root output_hists;
917
918 static void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits)
919 {
920         struct rb_node **p = &output_hists.rb_node;
921         struct rb_node *parent = NULL;
922         struct hist_entry *iter;
923
924         if (callchain)
925                 callchain_param.sort(&he->sorted_chain, &he->callchain,
926                                       min_callchain_hits, &callchain_param);
927
928         while (*p != NULL) {
929                 parent = *p;
930                 iter = rb_entry(parent, struct hist_entry, rb_node);
931
932                 if (he->count > iter->count)
933                         p = &(*p)->rb_left;
934                 else
935                         p = &(*p)->rb_right;
936         }
937
938         rb_link_node(&he->rb_node, parent, p);
939         rb_insert_color(&he->rb_node, &output_hists);
940 }
941
942 static void output__resort(u64 total_samples)
943 {
944         struct rb_node *next;
945         struct hist_entry *n;
946         struct rb_root *tree = &hist;
947         u64 min_callchain_hits;
948
949         min_callchain_hits = total_samples * (callchain_param.min_percent / 100);
950
951         if (sort__need_collapse)
952                 tree = &collapse_hists;
953
954         next = rb_first(tree);
955
956         while (next) {
957                 n = rb_entry(next, struct hist_entry, rb_node);
958                 next = rb_next(&n->rb_node);
959
960                 rb_erase(&n->rb_node, tree);
961                 output__insert_entry(n, min_callchain_hits);
962         }
963 }
964
965 static size_t output__fprintf(FILE *fp, u64 total_samples)
966 {
967         struct hist_entry *pos;
968         struct sort_entry *se;
969         struct rb_node *nd;
970         size_t ret = 0;
971         unsigned int width;
972         char *col_width = col_width_list_str;
973         int raw_printing_style;
974
975         raw_printing_style = !strcmp(pretty_printing_style, "raw");
976
977         init_rem_hits();
978
979         fprintf(fp, "# Samples: %Ld\n", (u64)total_samples);
980         fprintf(fp, "#\n");
981
982         fprintf(fp, "# Overhead");
983         if (show_nr_samples) {
984                 if (field_sep)
985                         fprintf(fp, "%cSamples", *field_sep);
986                 else
987                         fputs("  Samples  ", fp);
988         }
989         list_for_each_entry(se, &hist_entry__sort_list, list) {
990                 if (se->elide)
991                         continue;
992                 if (field_sep) {
993                         fprintf(fp, "%c%s", *field_sep, se->header);
994                         continue;
995                 }
996                 width = strlen(se->header);
997                 if (se->width) {
998                         if (col_width_list_str) {
999                                 if (col_width) {
1000                                         *se->width = atoi(col_width);
1001                                         col_width = strchr(col_width, ',');
1002                                         if (col_width)
1003                                                 ++col_width;
1004                                 }
1005                         }
1006                         width = *se->width = max(*se->width, width);
1007                 }
1008                 fprintf(fp, "  %*s", width, se->header);
1009         }
1010         fprintf(fp, "\n");
1011
1012         if (field_sep)
1013                 goto print_entries;
1014
1015         fprintf(fp, "# ........");
1016         if (show_nr_samples)
1017                 fprintf(fp, " ..........");
1018         list_for_each_entry(se, &hist_entry__sort_list, list) {
1019                 unsigned int i;
1020
1021                 if (se->elide)
1022                         continue;
1023
1024                 fprintf(fp, "  ");
1025                 if (se->width)
1026                         width = *se->width;
1027                 else
1028                         width = strlen(se->header);
1029                 for (i = 0; i < width; i++)
1030                         fprintf(fp, ".");
1031         }
1032         fprintf(fp, "\n");
1033
1034         fprintf(fp, "#\n");
1035
1036 print_entries:
1037         for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) {
1038                 pos = rb_entry(nd, struct hist_entry, rb_node);
1039                 ret += hist_entry__fprintf(fp, pos, total_samples);
1040         }
1041
1042         if (sort_order == default_sort_order &&
1043                         parent_pattern == default_parent_pattern) {
1044                 fprintf(fp, "#\n");
1045                 fprintf(fp, "# (For a higher level overview, try: perf report --sort comm,dso)\n");
1046                 fprintf(fp, "#\n");
1047         }
1048         fprintf(fp, "\n");
1049
1050         free(rem_sq_bracket);
1051
1052         if (show_threads)
1053                 perf_read_values_display(fp, &show_threads_values,
1054                                          raw_printing_style);
1055
1056         return ret;
1057 }
1058
1059 static void register_idle_thread(void)
1060 {
1061         struct thread *thread = threads__findnew(0, &threads, &last_match);
1062
1063         if (thread == NULL ||
1064                         thread__set_comm(thread, "[idle]")) {
1065                 fprintf(stderr, "problem inserting idle task.\n");
1066                 exit(-1);
1067         }
1068 }
1069
1070 static unsigned long total = 0,
1071                      total_mmap = 0,
1072                      total_comm = 0,
1073                      total_fork = 0,
1074                      total_unknown = 0,
1075                      total_lost = 0;
1076
1077 static int validate_chain(struct ip_callchain *chain, event_t *event)
1078 {
1079         unsigned int chain_size;
1080
1081         chain_size = event->header.size;
1082         chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event;
1083
1084         if (chain->nr*sizeof(u64) > chain_size)
1085                 return -1;
1086
1087         return 0;
1088 }
1089
1090 static int
1091 process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1092 {
1093         char level;
1094         int show = 0;
1095         struct dso *dso = NULL;
1096         struct thread *thread;
1097         u64 ip = event->ip.ip;
1098         u64 period = 1;
1099         struct map *map = NULL;
1100         void *more_data = event->ip.__more_data;
1101         struct ip_callchain *chain = NULL;
1102         int cpumode;
1103
1104         thread = threads__findnew(event->ip.pid, &threads, &last_match);
1105
1106         if (sample_type & PERF_SAMPLE_PERIOD) {
1107                 period = *(u64 *)more_data;
1108                 more_data += sizeof(u64);
1109         }
1110
1111         dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
1112                 (void *)(offset + head),
1113                 (void *)(long)(event->header.size),
1114                 event->header.misc,
1115                 event->ip.pid, event->ip.tid,
1116                 (void *)(long)ip,
1117                 (long long)period);
1118
1119         if (sample_type & PERF_SAMPLE_CALLCHAIN) {
1120                 unsigned int i;
1121
1122                 chain = (void *)more_data;
1123
1124                 dprintf("... chain: nr:%Lu\n", chain->nr);
1125
1126                 if (validate_chain(chain, event) < 0) {
1127                         eprintf("call-chain problem with event, skipping it.\n");
1128                         return 0;
1129                 }
1130
1131                 if (dump_trace) {
1132                         for (i = 0; i < chain->nr; i++)
1133                                 dprintf("..... %2d: %016Lx\n", i, chain->ips[i]);
1134                 }
1135         }
1136
1137         dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid);
1138
1139         if (thread == NULL) {
1140                 eprintf("problem processing %d event, skipping it.\n",
1141                         event->header.type);
1142                 return -1;
1143         }
1144
1145         if (comm_list && !strlist__has_entry(comm_list, thread->comm))
1146                 return 0;
1147
1148         cpumode = event->header.misc & PERF_EVENT_MISC_CPUMODE_MASK;
1149
1150         if (cpumode == PERF_EVENT_MISC_KERNEL) {
1151                 show = SHOW_KERNEL;
1152                 level = 'k';
1153
1154                 dso = kernel_dso;
1155
1156                 dprintf(" ...... dso: %s\n", dso->name);
1157
1158         } else if (cpumode == PERF_EVENT_MISC_USER) {
1159
1160                 show = SHOW_USER;
1161                 level = '.';
1162
1163         } else {
1164                 show = SHOW_HV;
1165                 level = 'H';
1166
1167                 dso = hypervisor_dso;
1168
1169                 dprintf(" ...... dso: [hypervisor]\n");
1170         }
1171
1172         if (show & show_mask) {
1173                 struct symbol *sym = resolve_symbol(thread, &map, &dso, &ip);
1174
1175                 if (dso_list && (!dso || !dso->name ||
1176                                  !strlist__has_entry(dso_list, dso->name)))
1177                         return 0;
1178
1179                 if (sym_list && (!sym || !strlist__has_entry(sym_list, sym->name)))
1180                         return 0;
1181
1182                 if (hist_entry__add(thread, map, dso, sym, ip, chain, level, period)) {
1183                         eprintf("problem incrementing symbol count, skipping event\n");
1184                         return -1;
1185                 }
1186         }
1187         total += period;
1188
1189         return 0;
1190 }
1191
1192 static int
1193 process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
1194 {
1195         struct thread *thread;
1196         struct map *map = map__new(&event->mmap, cwd, cwdlen);
1197
1198         thread = threads__findnew(event->mmap.pid, &threads, &last_match);
1199
1200         dprintf("%p [%p]: PERF_EVENT_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
1201                 (void *)(offset + head),
1202                 (void *)(long)(event->header.size),
1203                 event->mmap.pid,
1204                 event->mmap.tid,
1205                 (void *)(long)event->mmap.start,
1206                 (void *)(long)event->mmap.len,
1207                 (void *)(long)event->mmap.pgoff,
1208                 event->mmap.filename);
1209
1210         if (thread == NULL || map == NULL) {
1211                 dprintf("problem processing PERF_EVENT_MMAP, skipping event.\n");
1212                 return 0;
1213         }
1214
1215         thread__insert_map(thread, map);
1216         total_mmap++;
1217
1218         return 0;
1219 }
1220
1221 static int
1222 process_comm_event(event_t *event, unsigned long offset, unsigned long head)
1223 {
1224         struct thread *thread;
1225
1226         thread = threads__findnew(event->comm.pid, &threads, &last_match);
1227
1228         dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
1229                 (void *)(offset + head),
1230                 (void *)(long)(event->header.size),
1231                 event->comm.comm, event->comm.pid);
1232
1233         if (thread == NULL ||
1234             thread__set_comm(thread, event->comm.comm)) {
1235                 dprintf("problem processing PERF_EVENT_COMM, skipping event.\n");
1236                 return -1;
1237         }
1238         total_comm++;
1239
1240         return 0;
1241 }
1242
1243 static int
1244 process_task_event(event_t *event, unsigned long offset, unsigned long head)
1245 {
1246         struct thread *thread;
1247         struct thread *parent;
1248
1249         thread = threads__findnew(event->fork.pid, &threads, &last_match);
1250         parent = threads__findnew(event->fork.ppid, &threads, &last_match);
1251
1252         dprintf("%p [%p]: PERF_EVENT_%s: (%d:%d):(%d:%d)\n",
1253                 (void *)(offset + head),
1254                 (void *)(long)(event->header.size),
1255                 event->header.type == PERF_EVENT_FORK ? "FORK" : "EXIT",
1256                 event->fork.pid, event->fork.tid,
1257                 event->fork.ppid, event->fork.ptid);
1258
1259         /*
1260          * A thread clone will have the same PID for both
1261          * parent and child.
1262          */
1263         if (thread == parent)
1264                 return 0;
1265
1266         if (event->header.type == PERF_EVENT_EXIT)
1267                 return 0;
1268
1269         if (!thread || !parent || thread__fork(thread, parent)) {
1270                 dprintf("problem processing PERF_EVENT_FORK, skipping event.\n");
1271                 return -1;
1272         }
1273         total_fork++;
1274
1275         return 0;
1276 }
1277
1278 static int
1279 process_lost_event(event_t *event, unsigned long offset, unsigned long head)
1280 {
1281         dprintf("%p [%p]: PERF_EVENT_LOST: id:%Ld: lost:%Ld\n",
1282                 (void *)(offset + head),
1283                 (void *)(long)(event->header.size),
1284                 event->lost.id,
1285                 event->lost.lost);
1286
1287         total_lost += event->lost.lost;
1288
1289         return 0;
1290 }
1291
1292 static void trace_event(event_t *event)
1293 {
1294         unsigned char *raw_event = (void *)event;
1295         const char *color = PERF_COLOR_BLUE;
1296         int i, j;
1297
1298         if (!dump_trace)
1299                 return;
1300
1301         dprintf(".");
1302         cdprintf("\n. ... raw event: size %d bytes\n", event->header.size);
1303
1304         for (i = 0; i < event->header.size; i++) {
1305                 if ((i & 15) == 0) {
1306                         dprintf(".");
1307                         cdprintf("  %04x: ", i);
1308                 }
1309
1310                 cdprintf(" %02x", raw_event[i]);
1311
1312                 if (((i & 15) == 15) || i == event->header.size-1) {
1313                         cdprintf("  ");
1314                         for (j = 0; j < 15-(i & 15); j++)
1315                                 cdprintf("   ");
1316                         for (j = 0; j < (i & 15); j++) {
1317                                 if (isprint(raw_event[i-15+j]))
1318                                         cdprintf("%c", raw_event[i-15+j]);
1319                                 else
1320                                         cdprintf(".");
1321                         }
1322                         cdprintf("\n");
1323                 }
1324         }
1325         dprintf(".\n");
1326 }
1327
1328 static struct perf_header       *header;
1329
1330 static struct perf_counter_attr *perf_header__find_attr(u64 id)
1331 {
1332         int i;
1333
1334         for (i = 0; i < header->attrs; i++) {
1335                 struct perf_header_attr *attr = header->attr[i];
1336                 int j;
1337
1338                 for (j = 0; j < attr->ids; j++) {
1339                         if (attr->id[j] == id)
1340                                 return &attr->attr;
1341                 }
1342         }
1343
1344         return NULL;
1345 }
1346
1347 static int
1348 process_read_event(event_t *event, unsigned long offset, unsigned long head)
1349 {
1350         struct perf_counter_attr *attr = perf_header__find_attr(event->read.id);
1351
1352         if (show_threads) {
1353                 const char *name = attr ? __event_name(attr->type, attr->config)
1354                                    : "unknown";
1355                 perf_read_values_add_value(&show_threads_values,
1356                                            event->read.pid, event->read.tid,
1357                                            event->read.id,
1358                                            name,
1359                                            event->read.value);
1360         }
1361
1362         dprintf("%p [%p]: PERF_EVENT_READ: %d %d %s %Lu\n",
1363                         (void *)(offset + head),
1364                         (void *)(long)(event->header.size),
1365                         event->read.pid,
1366                         event->read.tid,
1367                         attr ? __event_name(attr->type, attr->config)
1368                              : "FAIL",
1369                         event->read.value);
1370
1371         return 0;
1372 }
1373
1374 static int
1375 process_event(event_t *event, unsigned long offset, unsigned long head)
1376 {
1377         trace_event(event);
1378
1379         switch (event->header.type) {
1380         case PERF_EVENT_SAMPLE:
1381                 return process_sample_event(event, offset, head);
1382
1383         case PERF_EVENT_MMAP:
1384                 return process_mmap_event(event, offset, head);
1385
1386         case PERF_EVENT_COMM:
1387                 return process_comm_event(event, offset, head);
1388
1389         case PERF_EVENT_FORK:
1390         case PERF_EVENT_EXIT:
1391                 return process_task_event(event, offset, head);
1392
1393         case PERF_EVENT_LOST:
1394                 return process_lost_event(event, offset, head);
1395
1396         case PERF_EVENT_READ:
1397                 return process_read_event(event, offset, head);
1398
1399         /*
1400          * We dont process them right now but they are fine:
1401          */
1402
1403         case PERF_EVENT_THROTTLE:
1404         case PERF_EVENT_UNTHROTTLE:
1405                 return 0;
1406
1407         default:
1408                 return -1;
1409         }
1410
1411         return 0;
1412 }
1413
1414 static u64 perf_header__sample_type(void)
1415 {
1416         u64 type = 0;
1417         int i;
1418
1419         for (i = 0; i < header->attrs; i++) {
1420                 struct perf_header_attr *attr = header->attr[i];
1421
1422                 if (!type)
1423                         type = attr->attr.sample_type;
1424                 else if (type != attr->attr.sample_type)
1425                         die("non matching sample_type");
1426         }
1427
1428         return type;
1429 }
1430
1431 static int __cmd_report(void)
1432 {
1433         int ret, rc = EXIT_FAILURE;
1434         unsigned long offset = 0;
1435         unsigned long head, shift;
1436         struct stat input_stat;
1437         event_t *event;
1438         uint32_t size;
1439         char *buf;
1440
1441         register_idle_thread();
1442
1443         if (show_threads)
1444                 perf_read_values_init(&show_threads_values);
1445
1446         input = open(input_name, O_RDONLY);
1447         if (input < 0) {
1448                 fprintf(stderr, " failed to open file: %s", input_name);
1449                 if (!strcmp(input_name, "perf.data"))
1450                         fprintf(stderr, "  (try 'perf record' first)");
1451                 fprintf(stderr, "\n");
1452                 exit(-1);
1453         }
1454
1455         ret = fstat(input, &input_stat);
1456         if (ret < 0) {
1457                 perror("failed to stat file");
1458                 exit(-1);
1459         }
1460
1461         if (!input_stat.st_size) {
1462                 fprintf(stderr, "zero-sized file, nothing to do!\n");
1463                 exit(0);
1464         }
1465
1466         header = perf_header__read(input);
1467         head = header->data_offset;
1468
1469         sample_type = perf_header__sample_type();
1470
1471         if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
1472                 if (sort__has_parent) {
1473                         fprintf(stderr, "selected --sort parent, but no"
1474                                         " callchain data. Did you call"
1475                                         " perf record without -g?\n");
1476                         exit(-1);
1477                 }
1478                 if (callchain) {
1479                         fprintf(stderr, "selected -c but no callchain data."
1480                                         " Did you call perf record without"
1481                                         " -g?\n");
1482                         exit(-1);
1483                 }
1484         } else if (callchain_param.mode != CHAIN_NONE && !callchain) {
1485                         callchain = 1;
1486                         if (register_callchain_param(&callchain_param) < 0) {
1487                                 fprintf(stderr, "Can't register callchain"
1488                                                 " params\n");
1489                                 exit(-1);
1490                         }
1491         }
1492
1493         if (load_kernel() < 0) {
1494                 perror("failed to load kernel symbols");
1495                 return EXIT_FAILURE;
1496         }
1497
1498         if (!full_paths) {
1499                 if (getcwd(__cwd, sizeof(__cwd)) == NULL) {
1500                         perror("failed to get the current directory");
1501                         return EXIT_FAILURE;
1502                 }
1503                 cwdlen = strlen(cwd);
1504         } else {
1505                 cwd = NULL;
1506                 cwdlen = 0;
1507         }
1508
1509         shift = page_size * (head / page_size);
1510         offset += shift;
1511         head -= shift;
1512
1513 remap:
1514         buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
1515                            MAP_SHARED, input, offset);
1516         if (buf == MAP_FAILED) {
1517                 perror("failed to mmap file");
1518                 exit(-1);
1519         }
1520
1521 more:
1522         event = (event_t *)(buf + head);
1523
1524         size = event->header.size;
1525         if (!size)
1526                 size = 8;
1527
1528         if (head + event->header.size >= page_size * mmap_window) {
1529                 int munmap_ret;
1530
1531                 shift = page_size * (head / page_size);
1532
1533                 munmap_ret = munmap(buf, page_size * mmap_window);
1534                 assert(munmap_ret == 0);
1535
1536                 offset += shift;
1537                 head -= shift;
1538                 goto remap;
1539         }
1540
1541         size = event->header.size;
1542
1543         dprintf("\n%p [%p]: event: %d\n",
1544                         (void *)(offset + head),
1545                         (void *)(long)event->header.size,
1546                         event->header.type);
1547
1548         if (!size || process_event(event, offset, head) < 0) {
1549
1550                 dprintf("%p [%p]: skipping unknown header type: %d\n",
1551                         (void *)(offset + head),
1552                         (void *)(long)(event->header.size),
1553                         event->header.type);
1554
1555                 total_unknown++;
1556
1557                 /*
1558                  * assume we lost track of the stream, check alignment, and
1559                  * increment a single u64 in the hope to catch on again 'soon'.
1560                  */
1561
1562                 if (unlikely(head & 7))
1563                         head &= ~7ULL;
1564
1565                 size = 8;
1566         }
1567
1568         head += size;
1569
1570         if (offset + head >= header->data_offset + header->data_size)
1571                 goto done;
1572
1573         if (offset + head < (unsigned long)input_stat.st_size)
1574                 goto more;
1575
1576 done:
1577         rc = EXIT_SUCCESS;
1578         close(input);
1579
1580         dprintf("      IP events: %10ld\n", total);
1581         dprintf("    mmap events: %10ld\n", total_mmap);
1582         dprintf("    comm events: %10ld\n", total_comm);
1583         dprintf("    fork events: %10ld\n", total_fork);
1584         dprintf("    lost events: %10ld\n", total_lost);
1585         dprintf(" unknown events: %10ld\n", total_unknown);
1586
1587         if (dump_trace)
1588                 return 0;
1589
1590         if (verbose >= 3)
1591                 threads__fprintf(stdout, &threads);
1592
1593         if (verbose >= 2)
1594                 dsos__fprintf(stdout);
1595
1596         collapse__resort();
1597         output__resort(total);
1598         output__fprintf(stdout, total);
1599
1600         if (show_threads)
1601                 perf_read_values_destroy(&show_threads_values);
1602
1603         return rc;
1604 }
1605
1606 static int
1607 parse_callchain_opt(const struct option *opt __used, const char *arg,
1608                     int unset __used)
1609 {
1610         char *tok;
1611         char *endptr;
1612
1613         callchain = 1;
1614
1615         if (!arg)
1616                 return 0;
1617
1618         tok = strtok((char *)arg, ",");
1619         if (!tok)
1620                 return -1;
1621
1622         /* get the output mode */
1623         if (!strncmp(tok, "graph", strlen(arg)))
1624                 callchain_param.mode = CHAIN_GRAPH_ABS;
1625
1626         else if (!strncmp(tok, "flat", strlen(arg)))
1627                 callchain_param.mode = CHAIN_FLAT;
1628
1629         else if (!strncmp(tok, "fractal", strlen(arg)))
1630                 callchain_param.mode = CHAIN_GRAPH_REL;
1631
1632         else if (!strncmp(tok, "none", strlen(arg))) {
1633                 callchain_param.mode = CHAIN_NONE;
1634                 callchain = 0;
1635
1636                 return 0;
1637         }
1638
1639         else
1640                 return -1;
1641
1642         /* get the min percentage */
1643         tok = strtok(NULL, ",");
1644         if (!tok)
1645                 goto setup;
1646
1647         callchain_param.min_percent = strtod(tok, &endptr);
1648         if (tok == endptr)
1649                 return -1;
1650
1651 setup:
1652         if (register_callchain_param(&callchain_param) < 0) {
1653                 fprintf(stderr, "Can't register callchain params\n");
1654                 return -1;
1655         }
1656         return 0;
1657 }
1658
1659 static const char * const report_usage[] = {
1660         "perf report [<options>] <command>",
1661         NULL
1662 };
1663
1664 static const struct option options[] = {
1665         OPT_STRING('i', "input", &input_name, "file",
1666                     "input file name"),
1667         OPT_BOOLEAN('v', "verbose", &verbose,
1668                     "be more verbose (show symbol address, etc)"),
1669         OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1670                     "dump raw trace in ASCII"),
1671         OPT_STRING('k', "vmlinux", &vmlinux_name, "file", "vmlinux pathname"),
1672         OPT_BOOLEAN('m', "modules", &modules,
1673                     "load module symbols - WARNING: use only with -k and LIVE kernel"),
1674         OPT_BOOLEAN('n', "show-nr-samples", &show_nr_samples,
1675                     "Show a column with the number of samples"),
1676         OPT_BOOLEAN('T', "threads", &show_threads,
1677                     "Show per-thread event counters"),
1678         OPT_STRING(0, "pretty", &pretty_printing_style, "key",
1679                    "pretty printing style key: normal raw"),
1680         OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
1681                    "sort by key(s): pid, comm, dso, symbol, parent"),
1682         OPT_BOOLEAN('P', "full-paths", &full_paths,
1683                     "Don't shorten the pathnames taking into account the cwd"),
1684         OPT_STRING('p', "parent", &parent_pattern, "regex",
1685                    "regex filter to identify parent, see: '--sort parent'"),
1686         OPT_BOOLEAN('x', "exclude-other", &exclude_other,
1687                     "Only display entries with parent-match"),
1688         OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
1689                      "Display callchains using output_type and min percent threshold. "
1690                      "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt),
1691         OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]",
1692                    "only consider symbols in these dsos"),
1693         OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]",
1694                    "only consider symbols in these comms"),
1695         OPT_STRING('S', "symbols", &sym_list_str, "symbol[,symbol...]",
1696                    "only consider these symbols"),
1697         OPT_STRING('w', "column-widths", &col_width_list_str,
1698                    "width[,width...]",
1699                    "don't try to adjust column width, use these fixed values"),
1700         OPT_STRING('t', "field-separator", &field_sep, "separator",
1701                    "separator for columns, no spaces will be added between "
1702                    "columns '.' is reserved."),
1703         OPT_END()
1704 };
1705
1706 static void setup_sorting(void)
1707 {
1708         char *tmp, *tok, *str = strdup(sort_order);
1709
1710         for (tok = strtok_r(str, ", ", &tmp);
1711                         tok; tok = strtok_r(NULL, ", ", &tmp)) {
1712                 if (sort_dimension__add(tok) < 0) {
1713                         error("Unknown --sort key: `%s'", tok);
1714                         usage_with_options(report_usage, options);
1715                 }
1716         }
1717
1718         free(str);
1719 }
1720
1721 static void setup_list(struct strlist **list, const char *list_str,
1722                        struct sort_entry *se, const char *list_name,
1723                        FILE *fp)
1724 {
1725         if (list_str) {
1726                 *list = strlist__new(true, list_str);
1727                 if (!*list) {
1728                         fprintf(stderr, "problems parsing %s list\n",
1729                                 list_name);
1730                         exit(129);
1731                 }
1732                 if (strlist__nr_entries(*list) == 1) {
1733                         fprintf(fp, "# %s: %s\n", list_name,
1734                                 strlist__entry(*list, 0)->s);
1735                         se->elide = true;
1736                 }
1737         }
1738 }
1739
1740 int cmd_report(int argc, const char **argv, const char *prefix __used)
1741 {
1742         symbol__init();
1743
1744         page_size = getpagesize();
1745
1746         argc = parse_options(argc, argv, options, report_usage, 0);
1747
1748         setup_sorting();
1749
1750         if (parent_pattern != default_parent_pattern) {
1751                 sort_dimension__add("parent");
1752                 sort_parent.elide = 1;
1753         } else
1754                 exclude_other = 0;
1755
1756         /*
1757          * Any (unrecognized) arguments left?
1758          */
1759         if (argc)
1760                 usage_with_options(report_usage, options);
1761
1762         setup_pager();
1763
1764         setup_list(&dso_list, dso_list_str, &sort_dso, "dso", stdout);
1765         setup_list(&comm_list, comm_list_str, &sort_comm, "comm", stdout);
1766         setup_list(&sym_list, sym_list_str, &sort_sym, "symbol", stdout);
1767
1768         if (field_sep && *field_sep == '.') {
1769                 fputs("'.' is the only non valid --field-separator argument\n",
1770                       stderr);
1771                 exit(129);
1772         }
1773
1774         return __cmd_report();
1775 }