aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-report.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r--tools/perf/builtin-report.c719
1 files changed, 136 insertions, 583 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 8b2ec882e6e0..cdf9a8d27bb9 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -17,19 +17,18 @@
17#include "util/string.h" 17#include "util/string.h"
18#include "util/callchain.h" 18#include "util/callchain.h"
19#include "util/strlist.h" 19#include "util/strlist.h"
20#include "util/values.h"
20 21
21#include "perf.h" 22#include "perf.h"
23#include "util/debug.h"
22#include "util/header.h" 24#include "util/header.h"
23 25
24#include "util/parse-options.h" 26#include "util/parse-options.h"
25#include "util/parse-events.h" 27#include "util/parse-events.h"
26 28
27#define SHOW_KERNEL 1 29#include "util/thread.h"
28#define SHOW_USER 2
29#define SHOW_HV 4
30 30
31static char const *input_name = "perf.data"; 31static char const *input_name = "perf.data";
32static char *vmlinux = NULL;
33 32
34static char default_sort_order[] = "comm,dso,symbol"; 33static char default_sort_order[] = "comm,dso,symbol";
35static char *sort_order = default_sort_order; 34static char *sort_order = default_sort_order;
@@ -42,18 +41,15 @@ static int force;
42static int input; 41static int input;
43static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV; 42static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
44 43
45static int dump_trace = 0;
46#define dprintf(x...) do { if (dump_trace) printf(x); } while (0)
47#define cdprintf(x...) do { if (dump_trace) color_fprintf(stdout, color, x); } while (0)
48
49static int verbose;
50#define eprintf(x...) do { if (verbose) fprintf(stderr, x); } while (0)
51
52static int modules;
53
54static int full_paths; 44static int full_paths;
55static int show_nr_samples; 45static int show_nr_samples;
56 46
47static int show_threads;
48static struct perf_read_values show_threads_values;
49
50static char default_pretty_printing_style[] = "normal";
51static char *pretty_printing_style = default_pretty_printing_style;
52
57static unsigned long page_size; 53static unsigned long page_size;
58static unsigned long mmap_window = 32; 54static unsigned long mmap_window = 32;
59 55
@@ -67,6 +63,15 @@ static char callchain_default_opt[] = "fractal,0.5";
67 63
68static int callchain; 64static int callchain;
69 65
66static char __cwd[PATH_MAX];
67static char *cwd = __cwd;
68static int cwdlen;
69
70static struct rb_root threads;
71static struct thread *last_match;
72
73static struct perf_header *header;
74
70static 75static
71struct callchain_param callchain_param = { 76struct callchain_param callchain_param = {
72 .mode = CHAIN_GRAPH_REL, 77 .mode = CHAIN_GRAPH_REL,
@@ -75,59 +80,6 @@ struct callchain_param callchain_param = {
75 80
76static u64 sample_type; 81static u64 sample_type;
77 82
78struct ip_event {
79 struct perf_event_header header;
80 u64 ip;
81 u32 pid, tid;
82 unsigned char __more_data[];
83};
84
85struct mmap_event {
86 struct perf_event_header header;
87 u32 pid, tid;
88 u64 start;
89 u64 len;
90 u64 pgoff;
91 char filename[PATH_MAX];
92};
93
94struct comm_event {
95 struct perf_event_header header;
96 u32 pid, tid;
97 char comm[16];
98};
99
100struct fork_event {
101 struct perf_event_header header;
102 u32 pid, ppid;
103 u32 tid, ptid;
104};
105
106struct lost_event {
107 struct perf_event_header header;
108 u64 id;
109 u64 lost;
110};
111
112struct read_event {
113 struct perf_event_header header;
114 u32 pid,tid;
115 u64 value;
116 u64 time_enabled;
117 u64 time_running;
118 u64 id;
119};
120
121typedef union event_union {
122 struct perf_event_header header;
123 struct ip_event ip;
124 struct mmap_event mmap;
125 struct comm_event comm;
126 struct fork_event fork;
127 struct lost_event lost;
128 struct read_event read;
129} event_t;
130
131static int repsep_fprintf(FILE *fp, const char *fmt, ...) 83static int repsep_fprintf(FILE *fp, const char *fmt, ...)
132{ 84{
133 int n; 85 int n;
@@ -141,6 +93,7 @@ static int repsep_fprintf(FILE *fp, const char *fmt, ...)
141 n = vasprintf(&bf, fmt, ap); 93 n = vasprintf(&bf, fmt, ap);
142 if (n > 0) { 94 if (n > 0) {
143 char *sep = bf; 95 char *sep = bf;
96
144 while (1) { 97 while (1) {
145 sep = strchr(sep, *field_sep); 98 sep = strchr(sep, *field_sep);
146 if (sep == NULL) 99 if (sep == NULL)
@@ -155,396 +108,10 @@ static int repsep_fprintf(FILE *fp, const char *fmt, ...)
155 return n; 108 return n;
156} 109}
157 110
158static LIST_HEAD(dsos);
159static struct dso *kernel_dso;
160static struct dso *vdso;
161static struct dso *hypervisor_dso;
162
163static void dsos__add(struct dso *dso)
164{
165 list_add_tail(&dso->node, &dsos);
166}
167
168static struct dso *dsos__find(const char *name)
169{
170 struct dso *pos;
171
172 list_for_each_entry(pos, &dsos, node)
173 if (strcmp(pos->name, name) == 0)
174 return pos;
175 return NULL;
176}
177
178static struct dso *dsos__findnew(const char *name)
179{
180 struct dso *dso = dsos__find(name);
181 int nr;
182
183 if (dso)
184 return dso;
185
186 dso = dso__new(name, 0);
187 if (!dso)
188 goto out_delete_dso;
189
190 nr = dso__load(dso, NULL, verbose);
191 if (nr < 0) {
192 eprintf("Failed to open: %s\n", name);
193 goto out_delete_dso;
194 }
195 if (!nr)
196 eprintf("No symbols found in: %s, maybe install a debug package?\n", name);
197
198 dsos__add(dso);
199
200 return dso;
201
202out_delete_dso:
203 dso__delete(dso);
204 return NULL;
205}
206
207static void dsos__fprintf(FILE *fp)
208{
209 struct dso *pos;
210
211 list_for_each_entry(pos, &dsos, node)
212 dso__fprintf(pos, fp);
213}
214
215static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip)
216{
217 return dso__find_symbol(dso, ip);
218}
219
220static int load_kernel(void)
221{
222 int err;
223
224 kernel_dso = dso__new("[kernel]", 0);
225 if (!kernel_dso)
226 return -1;
227
228 err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules);
229 if (err <= 0) {
230 dso__delete(kernel_dso);
231 kernel_dso = NULL;
232 } else
233 dsos__add(kernel_dso);
234
235 vdso = dso__new("[vdso]", 0);
236 if (!vdso)
237 return -1;
238
239 vdso->find_symbol = vdso__find_symbol;
240
241 dsos__add(vdso);
242
243 hypervisor_dso = dso__new("[hypervisor]", 0);
244 if (!hypervisor_dso)
245 return -1;
246 dsos__add(hypervisor_dso);
247
248 return err;
249}
250
251static char __cwd[PATH_MAX];
252static char *cwd = __cwd;
253static int cwdlen;
254
255static int strcommon(const char *pathname)
256{
257 int n = 0;
258
259 while (n < cwdlen && pathname[n] == cwd[n])
260 ++n;
261
262 return n;
263}
264
265struct map {
266 struct list_head node;
267 u64 start;
268 u64 end;
269 u64 pgoff;
270 u64 (*map_ip)(struct map *, u64);
271 struct dso *dso;
272};
273
274static u64 map__map_ip(struct map *map, u64 ip)
275{
276 return ip - map->start + map->pgoff;
277}
278
279static u64 vdso__map_ip(struct map *map __used, u64 ip)
280{
281 return ip;
282}
283
284static inline int is_anon_memory(const char *filename)
285{
286 return strcmp(filename, "//anon") == 0;
287}
288
289static struct map *map__new(struct mmap_event *event)
290{
291 struct map *self = malloc(sizeof(*self));
292
293 if (self != NULL) {
294 const char *filename = event->filename;
295 char newfilename[PATH_MAX];
296 int anon;
297
298 if (cwd) {
299 int n = strcommon(filename);
300
301 if (n == cwdlen) {
302 snprintf(newfilename, sizeof(newfilename),
303 ".%s", filename + n);
304 filename = newfilename;
305 }
306 }
307
308 anon = is_anon_memory(filename);
309
310 if (anon) {
311 snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
312 filename = newfilename;
313 }
314
315 self->start = event->start;
316 self->end = event->start + event->len;
317 self->pgoff = event->pgoff;
318
319 self->dso = dsos__findnew(filename);
320 if (self->dso == NULL)
321 goto out_delete;
322
323 if (self->dso == vdso || anon)
324 self->map_ip = vdso__map_ip;
325 else
326 self->map_ip = map__map_ip;
327 }
328 return self;
329out_delete:
330 free(self);
331 return NULL;
332}
333
334static struct map *map__clone(struct map *self)
335{
336 struct map *map = malloc(sizeof(*self));
337
338 if (!map)
339 return NULL;
340
341 memcpy(map, self, sizeof(*self));
342
343 return map;
344}
345
346static int map__overlap(struct map *l, struct map *r)
347{
348 if (l->start > r->start) {
349 struct map *t = l;
350 l = r;
351 r = t;
352 }
353
354 if (l->end > r->start)
355 return 1;
356
357 return 0;
358}
359
360static size_t map__fprintf(struct map *self, FILE *fp)
361{
362 return fprintf(fp, " %Lx-%Lx %Lx %s\n",
363 self->start, self->end, self->pgoff, self->dso->name);
364}
365
366
367struct thread {
368 struct rb_node rb_node;
369 struct list_head maps;
370 pid_t pid;
371 char *comm;
372};
373
374static struct thread *thread__new(pid_t pid)
375{
376 struct thread *self = malloc(sizeof(*self));
377
378 if (self != NULL) {
379 self->pid = pid;
380 self->comm = malloc(32);
381 if (self->comm)
382 snprintf(self->comm, 32, ":%d", self->pid);
383 INIT_LIST_HEAD(&self->maps);
384 }
385
386 return self;
387}
388
389static unsigned int dsos__col_width, 111static unsigned int dsos__col_width,
390 comms__col_width, 112 comms__col_width,
391 threads__col_width; 113 threads__col_width;
392 114
393static int thread__set_comm(struct thread *self, const char *comm)
394{
395 if (self->comm)
396 free(self->comm);
397 self->comm = strdup(comm);
398 if (!self->comm)
399 return -ENOMEM;
400
401 if (!col_width_list_str && !field_sep &&
402 (!comm_list || strlist__has_entry(comm_list, comm))) {
403 unsigned int slen = strlen(comm);
404 if (slen > comms__col_width) {
405 comms__col_width = slen;
406 threads__col_width = slen + 6;
407 }
408 }
409
410 return 0;
411}
412
413static size_t thread__fprintf(struct thread *self, FILE *fp)
414{
415 struct map *pos;
416 size_t ret = fprintf(fp, "Thread %d %s\n", self->pid, self->comm);
417
418 list_for_each_entry(pos, &self->maps, node)
419 ret += map__fprintf(pos, fp);
420
421 return ret;
422}
423
424
425static struct rb_root threads;
426static struct thread *last_match;
427
428static struct thread *threads__findnew(pid_t pid)
429{
430 struct rb_node **p = &threads.rb_node;
431 struct rb_node *parent = NULL;
432 struct thread *th;
433
434 /*
435 * Font-end cache - PID lookups come in blocks,
436 * so most of the time we dont have to look up
437 * the full rbtree:
438 */
439 if (last_match && last_match->pid == pid)
440 return last_match;
441
442 while (*p != NULL) {
443 parent = *p;
444 th = rb_entry(parent, struct thread, rb_node);
445
446 if (th->pid == pid) {
447 last_match = th;
448 return th;
449 }
450
451 if (pid < th->pid)
452 p = &(*p)->rb_left;
453 else
454 p = &(*p)->rb_right;
455 }
456
457 th = thread__new(pid);
458 if (th != NULL) {
459 rb_link_node(&th->rb_node, parent, p);
460 rb_insert_color(&th->rb_node, &threads);
461 last_match = th;
462 }
463
464 return th;
465}
466
467static void thread__insert_map(struct thread *self, struct map *map)
468{
469 struct map *pos, *tmp;
470
471 list_for_each_entry_safe(pos, tmp, &self->maps, node) {
472 if (map__overlap(pos, map)) {
473 if (verbose >= 2) {
474 printf("overlapping maps:\n");
475 map__fprintf(map, stdout);
476 map__fprintf(pos, stdout);
477 }
478
479 if (map->start <= pos->start && map->end > pos->start)
480 pos->start = map->end;
481
482 if (map->end >= pos->end && map->start < pos->end)
483 pos->end = map->start;
484
485 if (verbose >= 2) {
486 printf("after collision:\n");
487 map__fprintf(pos, stdout);
488 }
489
490 if (pos->start >= pos->end) {
491 list_del_init(&pos->node);
492 free(pos);
493 }
494 }
495 }
496
497 list_add_tail(&map->node, &self->maps);
498}
499
500static int thread__fork(struct thread *self, struct thread *parent)
501{
502 struct map *map;
503
504 if (self->comm)
505 free(self->comm);
506 self->comm = strdup(parent->comm);
507 if (!self->comm)
508 return -ENOMEM;
509
510 list_for_each_entry(map, &parent->maps, node) {
511 struct map *new = map__clone(map);
512 if (!new)
513 return -ENOMEM;
514 thread__insert_map(self, new);
515 }
516
517 return 0;
518}
519
520static struct map *thread__find_map(struct thread *self, u64 ip)
521{
522 struct map *pos;
523
524 if (self == NULL)
525 return NULL;
526
527 list_for_each_entry(pos, &self->maps, node)
528 if (ip >= pos->start && ip <= pos->end)
529 return pos;
530
531 return NULL;
532}
533
534static size_t threads__fprintf(FILE *fp)
535{
536 size_t ret = 0;
537 struct rb_node *nd;
538
539 for (nd = rb_first(&threads); nd; nd = rb_next(nd)) {
540 struct thread *pos = rb_entry(nd, struct thread, rb_node);
541
542 ret += thread__fprintf(pos, fp);
543 }
544
545 return ret;
546}
547
548/* 115/*
549 * histogram, sorted on item, collects counts 116 * histogram, sorted on item, collects counts
550 */ 117 */
@@ -574,7 +141,7 @@ struct hist_entry {
574struct sort_entry { 141struct sort_entry {
575 struct list_head list; 142 struct list_head list;
576 143
577 char *header; 144 const char *header;
578 145
579 int64_t (*cmp)(struct hist_entry *, struct hist_entry *); 146 int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
580 int64_t (*collapse)(struct hist_entry *, struct hist_entry *); 147 int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
@@ -758,7 +325,7 @@ static int sort__need_collapse = 0;
758static int sort__has_parent = 0; 325static int sort__has_parent = 0;
759 326
760struct sort_dimension { 327struct sort_dimension {
761 char *name; 328 const char *name;
762 struct sort_entry *entry; 329 struct sort_entry *entry;
763 int taken; 330 int taken;
764}; 331};
@@ -773,7 +340,7 @@ static struct sort_dimension sort_dimensions[] = {
773 340
774static LIST_HEAD(hist_entry__sort_list); 341static LIST_HEAD(hist_entry__sort_list);
775 342
776static int sort_dimension__add(char *tok) 343static int sort_dimension__add(const char *tok)
777{ 344{
778 unsigned int i; 345 unsigned int i;
779 346
@@ -1032,6 +599,7 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
1032 case CHAIN_GRAPH_REL: 599 case CHAIN_GRAPH_REL:
1033 ret += callchain__fprintf_graph(fp, chain, 600 ret += callchain__fprintf_graph(fp, chain,
1034 total_samples, 1, 1); 601 total_samples, 1, 1);
602 case CHAIN_NONE:
1035 default: 603 default:
1036 break; 604 break;
1037 } 605 }
@@ -1098,6 +666,34 @@ static void dso__calc_col_width(struct dso *self)
1098 self->slen_calculated = 1; 666 self->slen_calculated = 1;
1099} 667}
1100 668
669static void thread__comm_adjust(struct thread *self)
670{
671 char *comm = self->comm;
672
673 if (!col_width_list_str && !field_sep &&
674 (!comm_list || strlist__has_entry(comm_list, comm))) {
675 unsigned int slen = strlen(comm);
676
677 if (slen > comms__col_width) {
678 comms__col_width = slen;
679 threads__col_width = slen + 6;
680 }
681 }
682}
683
684static int thread__set_comm_adjust(struct thread *self, const char *comm)
685{
686 int ret = thread__set_comm(self, comm);
687
688 if (ret)
689 return ret;
690
691 thread__comm_adjust(self);
692
693 return 0;
694}
695
696
1101static struct symbol * 697static struct symbol *
1102resolve_symbol(struct thread *thread, struct map **mapp, 698resolve_symbol(struct thread *thread, struct map **mapp,
1103 struct dso **dsop, u64 *ipp) 699 struct dso **dsop, u64 *ipp)
@@ -1141,8 +737,8 @@ got_map:
1141 if ((long long)ip < 0) 737 if ((long long)ip < 0)
1142 dso = kernel_dso; 738 dso = kernel_dso;
1143 } 739 }
1144 dprintf(" ...... dso: %s\n", dso ? dso->name : "<not found>"); 740 dump_printf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
1145 dprintf(" ...... map: %Lx -> %Lx\n", *ipp, ip); 741 dump_printf(" ...... map: %Lx -> %Lx\n", *ipp, ip);
1146 *ipp = ip; 742 *ipp = ip;
1147 743
1148 if (dsop) 744 if (dsop)
@@ -1398,6 +994,9 @@ static size_t output__fprintf(FILE *fp, u64 total_samples)
1398 size_t ret = 0; 994 size_t ret = 0;
1399 unsigned int width; 995 unsigned int width;
1400 char *col_width = col_width_list_str; 996 char *col_width = col_width_list_str;
997 int raw_printing_style;
998
999 raw_printing_style = !strcmp(pretty_printing_style, "raw");
1401 1000
1402 init_rem_hits(); 1001 init_rem_hits();
1403 1002
@@ -1474,18 +1073,11 @@ print_entries:
1474 1073
1475 free(rem_sq_bracket); 1074 free(rem_sq_bracket);
1476 1075
1477 return ret; 1076 if (show_threads)
1478} 1077 perf_read_values_display(fp, &show_threads_values,
1078 raw_printing_style);
1479 1079
1480static void register_idle_thread(void) 1080 return ret;
1481{
1482 struct thread *thread = threads__findnew(0);
1483
1484 if (thread == NULL ||
1485 thread__set_comm(thread, "[idle]")) {
1486 fprintf(stderr, "problem inserting idle task.\n");
1487 exit(-1);
1488 }
1489} 1081}
1490 1082
1491static unsigned long total = 0, 1083static unsigned long total = 0,
@@ -1514,7 +1106,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1514 char level; 1106 char level;
1515 int show = 0; 1107 int show = 0;
1516 struct dso *dso = NULL; 1108 struct dso *dso = NULL;
1517 struct thread *thread = threads__findnew(event->ip.pid); 1109 struct thread *thread;
1518 u64 ip = event->ip.ip; 1110 u64 ip = event->ip.ip;
1519 u64 period = 1; 1111 u64 period = 1;
1520 struct map *map = NULL; 1112 struct map *map = NULL;
@@ -1522,12 +1114,14 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1522 struct ip_callchain *chain = NULL; 1114 struct ip_callchain *chain = NULL;
1523 int cpumode; 1115 int cpumode;
1524 1116
1117 thread = threads__findnew(event->ip.pid, &threads, &last_match);
1118
1525 if (sample_type & PERF_SAMPLE_PERIOD) { 1119 if (sample_type & PERF_SAMPLE_PERIOD) {
1526 period = *(u64 *)more_data; 1120 period = *(u64 *)more_data;
1527 more_data += sizeof(u64); 1121 more_data += sizeof(u64);
1528 } 1122 }
1529 1123
1530 dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n", 1124 dump_printf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
1531 (void *)(offset + head), 1125 (void *)(offset + head),
1532 (void *)(long)(event->header.size), 1126 (void *)(long)(event->header.size),
1533 event->header.misc, 1127 event->header.misc,
@@ -1540,7 +1134,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1540 1134
1541 chain = (void *)more_data; 1135 chain = (void *)more_data;
1542 1136
1543 dprintf("... chain: nr:%Lu\n", chain->nr); 1137 dump_printf("... chain: nr:%Lu\n", chain->nr);
1544 1138
1545 if (validate_chain(chain, event) < 0) { 1139 if (validate_chain(chain, event) < 0) {
1546 eprintf("call-chain problem with event, skipping it.\n"); 1140 eprintf("call-chain problem with event, skipping it.\n");
@@ -1549,11 +1143,11 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1549 1143
1550 if (dump_trace) { 1144 if (dump_trace) {
1551 for (i = 0; i < chain->nr; i++) 1145 for (i = 0; i < chain->nr; i++)
1552 dprintf("..... %2d: %016Lx\n", i, chain->ips[i]); 1146 dump_printf("..... %2d: %016Lx\n", i, chain->ips[i]);
1553 } 1147 }
1554 } 1148 }
1555 1149
1556 dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid); 1150 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
1557 1151
1558 if (thread == NULL) { 1152 if (thread == NULL) {
1559 eprintf("problem processing %d event, skipping it.\n", 1153 eprintf("problem processing %d event, skipping it.\n",
@@ -1572,7 +1166,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1572 1166
1573 dso = kernel_dso; 1167 dso = kernel_dso;
1574 1168
1575 dprintf(" ...... dso: %s\n", dso->name); 1169 dump_printf(" ...... dso: %s\n", dso->name);
1576 1170
1577 } else if (cpumode == PERF_EVENT_MISC_USER) { 1171 } else if (cpumode == PERF_EVENT_MISC_USER) {
1578 1172
@@ -1585,7 +1179,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1585 1179
1586 dso = hypervisor_dso; 1180 dso = hypervisor_dso;
1587 1181
1588 dprintf(" ...... dso: [hypervisor]\n"); 1182 dump_printf(" ...... dso: [hypervisor]\n");
1589 } 1183 }
1590 1184
1591 if (show & show_mask) { 1185 if (show & show_mask) {
@@ -1611,10 +1205,12 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1611static int 1205static int
1612process_mmap_event(event_t *event, unsigned long offset, unsigned long head) 1206process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
1613{ 1207{
1614 struct thread *thread = threads__findnew(event->mmap.pid); 1208 struct thread *thread;
1615 struct map *map = map__new(&event->mmap); 1209 struct map *map = map__new(&event->mmap, cwd, cwdlen);
1616 1210
1617 dprintf("%p [%p]: PERF_EVENT_MMAP %d/%d: [%p(%p) @ %p]: %s\n", 1211 thread = threads__findnew(event->mmap.pid, &threads, &last_match);
1212
1213 dump_printf("%p [%p]: PERF_EVENT_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
1618 (void *)(offset + head), 1214 (void *)(offset + head),
1619 (void *)(long)(event->header.size), 1215 (void *)(long)(event->header.size),
1620 event->mmap.pid, 1216 event->mmap.pid,
@@ -1625,7 +1221,7 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
1625 event->mmap.filename); 1221 event->mmap.filename);
1626 1222
1627 if (thread == NULL || map == NULL) { 1223 if (thread == NULL || map == NULL) {
1628 dprintf("problem processing PERF_EVENT_MMAP, skipping event.\n"); 1224 dump_printf("problem processing PERF_EVENT_MMAP, skipping event.\n");
1629 return 0; 1225 return 0;
1630 } 1226 }
1631 1227
@@ -1638,16 +1234,18 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
1638static int 1234static int
1639process_comm_event(event_t *event, unsigned long offset, unsigned long head) 1235process_comm_event(event_t *event, unsigned long offset, unsigned long head)
1640{ 1236{
1641 struct thread *thread = threads__findnew(event->comm.pid); 1237 struct thread *thread;
1238
1239 thread = threads__findnew(event->comm.pid, &threads, &last_match);
1642 1240
1643 dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n", 1241 dump_printf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
1644 (void *)(offset + head), 1242 (void *)(offset + head),
1645 (void *)(long)(event->header.size), 1243 (void *)(long)(event->header.size),
1646 event->comm.comm, event->comm.pid); 1244 event->comm.comm, event->comm.pid);
1647 1245
1648 if (thread == NULL || 1246 if (thread == NULL ||
1649 thread__set_comm(thread, event->comm.comm)) { 1247 thread__set_comm_adjust(thread, event->comm.comm)) {
1650 dprintf("problem processing PERF_EVENT_COMM, skipping event.\n"); 1248 dump_printf("problem processing PERF_EVENT_COMM, skipping event.\n");
1651 return -1; 1249 return -1;
1652 } 1250 }
1653 total_comm++; 1251 total_comm++;
@@ -1658,10 +1256,13 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head)
1658static int 1256static int
1659process_task_event(event_t *event, unsigned long offset, unsigned long head) 1257process_task_event(event_t *event, unsigned long offset, unsigned long head)
1660{ 1258{
1661 struct thread *thread = threads__findnew(event->fork.pid); 1259 struct thread *thread;
1662 struct thread *parent = threads__findnew(event->fork.ppid); 1260 struct thread *parent;
1663 1261
1664 dprintf("%p [%p]: PERF_EVENT_%s: (%d:%d):(%d:%d)\n", 1262 thread = threads__findnew(event->fork.pid, &threads, &last_match);
1263 parent = threads__findnew(event->fork.ppid, &threads, &last_match);
1264
1265 dump_printf("%p [%p]: PERF_EVENT_%s: (%d:%d):(%d:%d)\n",
1665 (void *)(offset + head), 1266 (void *)(offset + head),
1666 (void *)(long)(event->header.size), 1267 (void *)(long)(event->header.size),
1667 event->header.type == PERF_EVENT_FORK ? "FORK" : "EXIT", 1268 event->header.type == PERF_EVENT_FORK ? "FORK" : "EXIT",
@@ -1679,7 +1280,7 @@ process_task_event(event_t *event, unsigned long offset, unsigned long head)
1679 return 0; 1280 return 0;
1680 1281
1681 if (!thread || !parent || thread__fork(thread, parent)) { 1282 if (!thread || !parent || thread__fork(thread, parent)) {
1682 dprintf("problem processing PERF_EVENT_FORK, skipping event.\n"); 1283 dump_printf("problem processing PERF_EVENT_FORK, skipping event.\n");
1683 return -1; 1284 return -1;
1684 } 1285 }
1685 total_fork++; 1286 total_fork++;
@@ -1690,7 +1291,7 @@ process_task_event(event_t *event, unsigned long offset, unsigned long head)
1690static int 1291static int
1691process_lost_event(event_t *event, unsigned long offset, unsigned long head) 1292process_lost_event(event_t *event, unsigned long offset, unsigned long head)
1692{ 1293{
1693 dprintf("%p [%p]: PERF_EVENT_LOST: id:%Ld: lost:%Ld\n", 1294 dump_printf("%p [%p]: PERF_EVENT_LOST: id:%Ld: lost:%Ld\n",
1694 (void *)(offset + head), 1295 (void *)(offset + head),
1695 (void *)(long)(event->header.size), 1296 (void *)(long)(event->header.size),
1696 event->lost.id, 1297 event->lost.id,
@@ -1701,67 +1302,24 @@ process_lost_event(event_t *event, unsigned long offset, unsigned long head)
1701 return 0; 1302 return 0;
1702} 1303}
1703 1304
1704static void trace_event(event_t *event) 1305static int
1705{ 1306process_read_event(event_t *event, unsigned long offset, unsigned long head)
1706 unsigned char *raw_event = (void *)event;
1707 char *color = PERF_COLOR_BLUE;
1708 int i, j;
1709
1710 if (!dump_trace)
1711 return;
1712
1713 dprintf(".");
1714 cdprintf("\n. ... raw event: size %d bytes\n", event->header.size);
1715
1716 for (i = 0; i < event->header.size; i++) {
1717 if ((i & 15) == 0) {
1718 dprintf(".");
1719 cdprintf(" %04x: ", i);
1720 }
1721
1722 cdprintf(" %02x", raw_event[i]);
1723
1724 if (((i & 15) == 15) || i == event->header.size-1) {
1725 cdprintf(" ");
1726 for (j = 0; j < 15-(i & 15); j++)
1727 cdprintf(" ");
1728 for (j = 0; j < (i & 15); j++) {
1729 if (isprint(raw_event[i-15+j]))
1730 cdprintf("%c", raw_event[i-15+j]);
1731 else
1732 cdprintf(".");
1733 }
1734 cdprintf("\n");
1735 }
1736 }
1737 dprintf(".\n");
1738}
1739
1740static struct perf_header *header;
1741
1742static struct perf_counter_attr *perf_header__find_attr(u64 id)
1743{ 1307{
1744 int i; 1308 struct perf_counter_attr *attr;
1745 1309
1746 for (i = 0; i < header->attrs; i++) { 1310 attr = perf_header__find_attr(event->read.id, header);
1747 struct perf_header_attr *attr = header->attr[i];
1748 int j;
1749 1311
1750 for (j = 0; j < attr->ids; j++) { 1312 if (show_threads) {
1751 if (attr->id[j] == id) 1313 const char *name = attr ? __event_name(attr->type, attr->config)
1752 return &attr->attr; 1314 : "unknown";
1753 } 1315 perf_read_values_add_value(&show_threads_values,
1316 event->read.pid, event->read.tid,
1317 event->read.id,
1318 name,
1319 event->read.value);
1754 } 1320 }
1755 1321
1756 return NULL; 1322 dump_printf("%p [%p]: PERF_EVENT_READ: %d %d %s %Lu\n",
1757}
1758
1759static int
1760process_read_event(event_t *event, unsigned long offset, unsigned long head)
1761{
1762 struct perf_counter_attr *attr = perf_header__find_attr(event->read.id);
1763
1764 dprintf("%p [%p]: PERF_EVENT_READ: %d %d %s %Lu\n",
1765 (void *)(offset + head), 1323 (void *)(offset + head),
1766 (void *)(long)(event->header.size), 1324 (void *)(long)(event->header.size),
1767 event->read.pid, 1325 event->read.pid,
@@ -1813,34 +1371,22 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
1813 return 0; 1371 return 0;
1814} 1372}
1815 1373
1816static u64 perf_header__sample_type(void)
1817{
1818 u64 sample_type = 0;
1819 int i;
1820
1821 for (i = 0; i < header->attrs; i++) {
1822 struct perf_header_attr *attr = header->attr[i];
1823
1824 if (!sample_type)
1825 sample_type = attr->attr.sample_type;
1826 else if (sample_type != attr->attr.sample_type)
1827 die("non matching sample_type");
1828 }
1829
1830 return sample_type;
1831}
1832
1833static int __cmd_report(void) 1374static int __cmd_report(void)
1834{ 1375{
1835 int ret, rc = EXIT_FAILURE; 1376 int ret, rc = EXIT_FAILURE;
1836 unsigned long offset = 0; 1377 unsigned long offset = 0;
1837 unsigned long head, shift; 1378 unsigned long head, shift;
1838 struct stat stat; 1379 struct stat input_stat;
1380 struct thread *idle;
1839 event_t *event; 1381 event_t *event;
1840 uint32_t size; 1382 uint32_t size;
1841 char *buf; 1383 char *buf;
1842 1384
1843 register_idle_thread(); 1385 idle = register_idle_thread(&threads, &last_match);
1386 thread__comm_adjust(idle);
1387
1388 if (show_threads)
1389 perf_read_values_init(&show_threads_values);
1844 1390
1845 input = open(input_name, O_RDONLY); 1391 input = open(input_name, O_RDONLY);
1846 if (input < 0) { 1392 if (input < 0) {
@@ -1851,18 +1397,18 @@ static int __cmd_report(void)
1851 exit(-1); 1397 exit(-1);
1852 } 1398 }
1853 1399
1854 ret = fstat(input, &stat); 1400 ret = fstat(input, &input_stat);
1855 if (ret < 0) { 1401 if (ret < 0) {
1856 perror("failed to stat file"); 1402 perror("failed to stat file");
1857 exit(-1); 1403 exit(-1);
1858 } 1404 }
1859 1405
1860 if (!force && (stat.st_uid != geteuid())) { 1406 if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
1861 fprintf(stderr, "file: %s not owned by current user\n", input_name); 1407 fprintf(stderr, "file: %s not owned by current user or root\n", input_name);
1862 exit(-1); 1408 exit(-1);
1863 } 1409 }
1864 1410
1865 if (!stat.st_size) { 1411 if (!input_stat.st_size) {
1866 fprintf(stderr, "zero-sized file, nothing to do!\n"); 1412 fprintf(stderr, "zero-sized file, nothing to do!\n");
1867 exit(0); 1413 exit(0);
1868 } 1414 }
@@ -1870,7 +1416,7 @@ static int __cmd_report(void)
1870 header = perf_header__read(input); 1416 header = perf_header__read(input);
1871 head = header->data_offset; 1417 head = header->data_offset;
1872 1418
1873 sample_type = perf_header__sample_type(); 1419 sample_type = perf_header__sample_type(header);
1874 1420
1875 if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) { 1421 if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
1876 if (sort__has_parent) { 1422 if (sort__has_parent) {
@@ -1880,7 +1426,7 @@ static int __cmd_report(void)
1880 exit(-1); 1426 exit(-1);
1881 } 1427 }
1882 if (callchain) { 1428 if (callchain) {
1883 fprintf(stderr, "selected -c but no callchain data." 1429 fprintf(stderr, "selected -g but no callchain data."
1884 " Did you call perf record without" 1430 " Did you call perf record without"
1885 " -g?\n"); 1431 " -g?\n");
1886 exit(-1); 1432 exit(-1);
@@ -1930,12 +1476,12 @@ more:
1930 size = 8; 1476 size = 8;
1931 1477
1932 if (head + event->header.size >= page_size * mmap_window) { 1478 if (head + event->header.size >= page_size * mmap_window) {
1933 int ret; 1479 int munmap_ret;
1934 1480
1935 shift = page_size * (head / page_size); 1481 shift = page_size * (head / page_size);
1936 1482
1937 ret = munmap(buf, page_size * mmap_window); 1483 munmap_ret = munmap(buf, page_size * mmap_window);
1938 assert(ret == 0); 1484 assert(munmap_ret == 0);
1939 1485
1940 offset += shift; 1486 offset += shift;
1941 head -= shift; 1487 head -= shift;
@@ -1944,14 +1490,14 @@ more:
1944 1490
1945 size = event->header.size; 1491 size = event->header.size;
1946 1492
1947 dprintf("\n%p [%p]: event: %d\n", 1493 dump_printf("\n%p [%p]: event: %d\n",
1948 (void *)(offset + head), 1494 (void *)(offset + head),
1949 (void *)(long)event->header.size, 1495 (void *)(long)event->header.size,
1950 event->header.type); 1496 event->header.type);
1951 1497
1952 if (!size || process_event(event, offset, head) < 0) { 1498 if (!size || process_event(event, offset, head) < 0) {
1953 1499
1954 dprintf("%p [%p]: skipping unknown header type: %d\n", 1500 dump_printf("%p [%p]: skipping unknown header type: %d\n",
1955 (void *)(offset + head), 1501 (void *)(offset + head),
1956 (void *)(long)(event->header.size), 1502 (void *)(long)(event->header.size),
1957 event->header.type); 1503 event->header.type);
@@ -1974,25 +1520,25 @@ more:
1974 if (offset + head >= header->data_offset + header->data_size) 1520 if (offset + head >= header->data_offset + header->data_size)
1975 goto done; 1521 goto done;
1976 1522
1977 if (offset + head < (unsigned long)stat.st_size) 1523 if (offset + head < (unsigned long)input_stat.st_size)
1978 goto more; 1524 goto more;
1979 1525
1980done: 1526done:
1981 rc = EXIT_SUCCESS; 1527 rc = EXIT_SUCCESS;
1982 close(input); 1528 close(input);
1983 1529
1984 dprintf(" IP events: %10ld\n", total); 1530 dump_printf(" IP events: %10ld\n", total);
1985 dprintf(" mmap events: %10ld\n", total_mmap); 1531 dump_printf(" mmap events: %10ld\n", total_mmap);
1986 dprintf(" comm events: %10ld\n", total_comm); 1532 dump_printf(" comm events: %10ld\n", total_comm);
1987 dprintf(" fork events: %10ld\n", total_fork); 1533 dump_printf(" fork events: %10ld\n", total_fork);
1988 dprintf(" lost events: %10ld\n", total_lost); 1534 dump_printf(" lost events: %10ld\n", total_lost);
1989 dprintf(" unknown events: %10ld\n", total_unknown); 1535 dump_printf(" unknown events: %10ld\n", total_unknown);
1990 1536
1991 if (dump_trace) 1537 if (dump_trace)
1992 return 0; 1538 return 0;
1993 1539
1994 if (verbose >= 3) 1540 if (verbose >= 3)
1995 threads__fprintf(stdout); 1541 threads__fprintf(stdout, &threads);
1996 1542
1997 if (verbose >= 2) 1543 if (verbose >= 2)
1998 dsos__fprintf(stdout); 1544 dsos__fprintf(stdout);
@@ -2001,6 +1547,9 @@ done:
2001 output__resort(total); 1547 output__resort(total);
2002 output__fprintf(stdout, total); 1548 output__fprintf(stdout, total);
2003 1549
1550 if (show_threads)
1551 perf_read_values_destroy(&show_threads_values);
1552
2004 return rc; 1553 return rc;
2005} 1554}
2006 1555
@@ -2069,12 +1618,16 @@ static const struct option options[] = {
2069 "be more verbose (show symbol address, etc)"), 1618 "be more verbose (show symbol address, etc)"),
2070 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1619 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
2071 "dump raw trace in ASCII"), 1620 "dump raw trace in ASCII"),
2072 OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), 1621 OPT_STRING('k', "vmlinux", &vmlinux_name, "file", "vmlinux pathname"),
2073 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), 1622 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
2074 OPT_BOOLEAN('m', "modules", &modules, 1623 OPT_BOOLEAN('m', "modules", &modules,
2075 "load module symbols - WARNING: use only with -k and LIVE kernel"), 1624 "load module symbols - WARNING: use only with -k and LIVE kernel"),
2076 OPT_BOOLEAN('n', "show-nr-samples", &show_nr_samples, 1625 OPT_BOOLEAN('n', "show-nr-samples", &show_nr_samples,
2077 "Show a column with the number of samples"), 1626 "Show a column with the number of samples"),
1627 OPT_BOOLEAN('T', "threads", &show_threads,
1628 "Show per-thread event counters"),
1629 OPT_STRING(0, "pretty", &pretty_printing_style, "key",
1630 "pretty printing style key: normal raw"),
2078 OPT_STRING('s', "sort", &sort_order, "key[,key2...]", 1631 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
2079 "sort by key(s): pid, comm, dso, symbol, parent"), 1632 "sort by key(s): pid, comm, dso, symbol, parent"),
2080 OPT_BOOLEAN('P', "full-paths", &full_paths, 1633 OPT_BOOLEAN('P', "full-paths", &full_paths,