Linux Perf
builtin-script.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 #include "builtin.h"
3 
4 #include "perf.h"
5 #include "util/cache.h"
6 #include "util/debug.h"
7 #include <subcmd/exec-cmd.h>
8 #include "util/header.h"
9 #include <subcmd/parse-options.h>
10 #include "util/perf_regs.h"
11 #include "util/session.h"
12 #include "util/tool.h"
13 #include "util/symbol.h"
14 #include "util/thread.h"
15 #include "util/trace-event.h"
16 #include "util/util.h"
17 #include "util/evlist.h"
18 #include "util/evsel.h"
19 #include "util/sort.h"
20 #include "util/data.h"
21 #include "util/auxtrace.h"
22 #include "util/cpumap.h"
23 #include "util/thread_map.h"
24 #include "util/stat.h"
25 #include "util/color.h"
26 #include "util/string2.h"
27 #include "util/thread-stack.h"
28 #include "util/time-utils.h"
29 #include "util/path.h"
30 #include "print_binary.h"
31 #include <linux/bitmap.h>
32 #include <linux/kernel.h>
33 #include <linux/stringify.h>
34 #include <linux/time64.h>
35 #include "asm/bug.h"
36 #include "util/mem-events.h"
37 #include "util/dump-insn.h"
38 #include <dirent.h>
39 #include <errno.h>
40 #include <inttypes.h>
41 #include <signal.h>
42 #include <sys/param.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <fcntl.h>
46 #include <unistd.h>
47 
48 #include "sane_ctype.h"
49 
50 static char const *script_name;
51 static char const *generate_script_lang;
52 static bool debug_mode;
53 static u64 last_timestamp;
54 static u64 nr_unordered;
55 static bool no_callchain;
56 static bool latency_format;
57 static bool system_wide;
58 static bool print_flags;
59 static bool nanosecs;
60 static const char *cpu_list;
61 static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
63 static int max_blocks;
64 
65 unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
66 
68  PERF_OUTPUT_COMM = 1U << 0,
69  PERF_OUTPUT_TID = 1U << 1,
70  PERF_OUTPUT_PID = 1U << 2,
71  PERF_OUTPUT_TIME = 1U << 3,
72  PERF_OUTPUT_CPU = 1U << 4,
73  PERF_OUTPUT_EVNAME = 1U << 5,
74  PERF_OUTPUT_TRACE = 1U << 6,
75  PERF_OUTPUT_IP = 1U << 7,
76  PERF_OUTPUT_SYM = 1U << 8,
77  PERF_OUTPUT_DSO = 1U << 9,
78  PERF_OUTPUT_ADDR = 1U << 10,
80  PERF_OUTPUT_SRCLINE = 1U << 12,
81  PERF_OUTPUT_PERIOD = 1U << 13,
82  PERF_OUTPUT_IREGS = 1U << 14,
83  PERF_OUTPUT_BRSTACK = 1U << 15,
86  PERF_OUTPUT_WEIGHT = 1U << 18,
89  PERF_OUTPUT_INSN = 1U << 21,
90  PERF_OUTPUT_INSNLEN = 1U << 22,
93  PERF_OUTPUT_SYNTH = 1U << 25,
95  PERF_OUTPUT_UREGS = 1U << 27,
96  PERF_OUTPUT_METRIC = 1U << 28,
97  PERF_OUTPUT_MISC = 1U << 29,
98 };
99 
101  const char *str;
103 } all_output_options[] = {
104  {.str = "comm", .field = PERF_OUTPUT_COMM},
105  {.str = "tid", .field = PERF_OUTPUT_TID},
106  {.str = "pid", .field = PERF_OUTPUT_PID},
107  {.str = "time", .field = PERF_OUTPUT_TIME},
108  {.str = "cpu", .field = PERF_OUTPUT_CPU},
109  {.str = "event", .field = PERF_OUTPUT_EVNAME},
110  {.str = "trace", .field = PERF_OUTPUT_TRACE},
111  {.str = "ip", .field = PERF_OUTPUT_IP},
112  {.str = "sym", .field = PERF_OUTPUT_SYM},
113  {.str = "dso", .field = PERF_OUTPUT_DSO},
114  {.str = "addr", .field = PERF_OUTPUT_ADDR},
115  {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
116  {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
117  {.str = "period", .field = PERF_OUTPUT_PERIOD},
118  {.str = "iregs", .field = PERF_OUTPUT_IREGS},
119  {.str = "uregs", .field = PERF_OUTPUT_UREGS},
120  {.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
121  {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
122  {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},
123  {.str = "weight", .field = PERF_OUTPUT_WEIGHT},
124  {.str = "bpf-output", .field = PERF_OUTPUT_BPF_OUTPUT},
125  {.str = "callindent", .field = PERF_OUTPUT_CALLINDENT},
126  {.str = "insn", .field = PERF_OUTPUT_INSN},
127  {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN},
128  {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
129  {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
130  {.str = "synth", .field = PERF_OUTPUT_SYNTH},
131  {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
132  {.str = "metric", .field = PERF_OUTPUT_METRIC},
133  {.str = "misc", .field = PERF_OUTPUT_MISC},
134 };
135 
136 enum {
137  OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,
139 };
140 
141 /* default set to maintain compatibility with current format */
142 static struct {
143  bool user_set;
145  unsigned int print_ip_opts;
146  u64 fields;
148 } output[OUTPUT_TYPE_MAX] = {
149 
150  [PERF_TYPE_HARDWARE] = {
151  .user_set = false,
152 
153  .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
158 
159  .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
160  },
161 
162  [PERF_TYPE_SOFTWARE] = {
163  .user_set = false,
164 
165  .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
171 
172  .invalid_fields = PERF_OUTPUT_TRACE,
173  },
174 
175  [PERF_TYPE_TRACEPOINT] = {
176  .user_set = false,
177 
178  .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
181  },
182 
183  [PERF_TYPE_RAW] = {
184  .user_set = false,
185 
186  .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
193 
194  .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
195  },
196 
197  [PERF_TYPE_BREAKPOINT] = {
198  .user_set = false,
199 
200  .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
205 
206  .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
207  },
208 
209  [OUTPUT_TYPE_SYNTH] = {
210  .user_set = false,
211 
212  .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
217 
218  .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
219  },
220 };
221 
223  char *filename;
224  FILE *fp;
225  u64 samples;
226  /* For metric output */
227  u64 val;
228  int gnum;
229 };
230 
231 static inline struct perf_evsel_script *evsel_script(struct perf_evsel *evsel)
232 {
233  return (struct perf_evsel_script *)evsel->priv;
234 }
235 
237  struct perf_data *data)
238 {
239  struct perf_evsel_script *es = zalloc(sizeof(*es));
240 
241  if (es != NULL) {
242  if (asprintf(&es->filename, "%s.%s.dump", data->file.path, perf_evsel__name(evsel)) < 0)
243  goto out_free;
244  es->fp = fopen(es->filename, "w");
245  if (es->fp == NULL)
246  goto out_free_filename;
247  }
248 
249  return es;
250 out_free_filename:
251  zfree(&es->filename);
252 out_free:
253  free(es);
254  return NULL;
255 }
256 
258 {
259  zfree(&es->filename);
260  fclose(es->fp);
261  es->fp = NULL;
262  free(es);
263 }
264 
265 static int perf_evsel_script__fprintf(struct perf_evsel_script *es, FILE *fp)
266 {
267  struct stat st;
268 
269  fstat(fileno(es->fp), &st);
270  return fprintf(fp, "[ perf script: Wrote %.3f MB %s (%" PRIu64 " samples) ]\n",
271  st.st_size / 1024.0 / 1024.0, es->filename, es->samples);
272 }
273 
274 static inline int output_type(unsigned int type)
275 {
276  switch (type) {
277  case PERF_TYPE_SYNTH:
278  return OUTPUT_TYPE_SYNTH;
279  default:
280  return type;
281  }
282 }
283 
284 static inline unsigned int attr_type(unsigned int type)
285 {
286  switch (type) {
287  case OUTPUT_TYPE_SYNTH:
288  return PERF_TYPE_SYNTH;
289  default:
290  return type;
291  }
292 }
293 
294 static bool output_set_by_user(void)
295 {
296  int j;
297  for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
298  if (output[j].user_set)
299  return true;
300  }
301  return false;
302 }
303 
304 static const char *output_field2str(enum perf_output_field field)
305 {
306  int i, imax = ARRAY_SIZE(all_output_options);
307  const char *str = "";
308 
309  for (i = 0; i < imax; ++i) {
310  if (all_output_options[i].field == field) {
311  str = all_output_options[i].str;
312  break;
313  }
314  }
315  return str;
316 }
317 
318 #define PRINT_FIELD(x) (output[output_type(attr->type)].fields & PERF_OUTPUT_##x)
319 
320 static int perf_evsel__do_check_stype(struct perf_evsel *evsel,
321  u64 sample_type, const char *sample_msg,
323  bool allow_user_set)
324 {
325  struct perf_event_attr *attr = &evsel->attr;
326  int type = output_type(attr->type);
327  const char *evname;
328 
329  if (attr->sample_type & sample_type)
330  return 0;
331 
332  if (output[type].user_set) {
333  if (allow_user_set)
334  return 0;
335  evname = perf_evsel__name(evsel);
336  pr_err("Samples for '%s' event do not have %s attribute set. "
337  "Cannot print '%s' field.\n",
338  evname, sample_msg, output_field2str(field));
339  return -1;
340  }
341 
342  /* user did not ask for it explicitly so remove from the default list */
343  output[type].fields &= ~field;
344  evname = perf_evsel__name(evsel);
345  pr_debug("Samples for '%s' event do not have %s attribute set. "
346  "Skipping '%s' field.\n",
347  evname, sample_msg, output_field2str(field));
348 
349  return 0;
350 }
351 
352 static int perf_evsel__check_stype(struct perf_evsel *evsel,
353  u64 sample_type, const char *sample_msg,
355 {
356  return perf_evsel__do_check_stype(evsel, sample_type, sample_msg, field,
357  false);
358 }
359 
360 static int perf_evsel__check_attr(struct perf_evsel *evsel,
361  struct perf_session *session)
362 {
363  struct perf_event_attr *attr = &evsel->attr;
364  bool allow_user_set;
365 
366  if (perf_header__has_feat(&session->header, HEADER_STAT))
367  return 0;
368 
369  allow_user_set = perf_header__has_feat(&session->header,
371 
372  if (PRINT_FIELD(TRACE) &&
373  !perf_session__has_traces(session, "record -R"))
374  return -EINVAL;
375 
376  if (PRINT_FIELD(IP)) {
377  if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP",
379  return -EINVAL;
380  }
381 
382  if (PRINT_FIELD(ADDR) &&
383  perf_evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR",
384  PERF_OUTPUT_ADDR, allow_user_set))
385  return -EINVAL;
386 
387  if (PRINT_FIELD(DATA_SRC) &&
388  perf_evsel__check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC",
390  return -EINVAL;
391 
392  if (PRINT_FIELD(WEIGHT) &&
393  perf_evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT, "WEIGHT",
395  return -EINVAL;
396 
397  if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
398  pr_err("Display of symbols requested but neither sample IP nor "
399  "sample address\nis selected. Hence, no addresses to convert "
400  "to symbols.\n");
401  return -EINVAL;
402  }
403  if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
404  pr_err("Display of offsets requested but symbol is not"
405  "selected.\n");
406  return -EINVAL;
407  }
408  if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR) &&
409  !PRINT_FIELD(BRSTACK) && !PRINT_FIELD(BRSTACKSYM) && !PRINT_FIELD(BRSTACKOFF)) {
410  pr_err("Display of DSO requested but no address to convert. Select\n"
411  "sample IP, sample address, brstack, brstacksym, or brstackoff.\n");
412  return -EINVAL;
413  }
414  if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) {
415  pr_err("Display of source line number requested but sample IP is not\n"
416  "selected. Hence, no address to lookup the source line number.\n");
417  return -EINVAL;
418  }
419  if (PRINT_FIELD(BRSTACKINSN) &&
421  PERF_SAMPLE_BRANCH_ANY)) {
422  pr_err("Display of branch stack assembler requested, but non all-branch filter set\n"
423  "Hint: run 'perf record -b ...'\n");
424  return -EINVAL;
425  }
426  if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
427  perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID",
429  return -EINVAL;
430 
431  if (PRINT_FIELD(TIME) &&
432  perf_evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME",
434  return -EINVAL;
435 
436  if (PRINT_FIELD(CPU) &&
437  perf_evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU",
438  PERF_OUTPUT_CPU, allow_user_set))
439  return -EINVAL;
440 
441  if (PRINT_FIELD(IREGS) &&
442  perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS",
444  return -EINVAL;
445 
446  if (PRINT_FIELD(UREGS) &&
447  perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS",
449  return -EINVAL;
450 
451  if (PRINT_FIELD(PHYS_ADDR) &&
452  perf_evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR",
454  return -EINVAL;
455 
456  return 0;
457 }
458 
459 static void set_print_ip_opts(struct perf_event_attr *attr)
460 {
461  unsigned int type = output_type(attr->type);
462 
463  output[type].print_ip_opts = 0;
464  if (PRINT_FIELD(IP))
465  output[type].print_ip_opts |= EVSEL__PRINT_IP;
466 
467  if (PRINT_FIELD(SYM))
468  output[type].print_ip_opts |= EVSEL__PRINT_SYM;
469 
470  if (PRINT_FIELD(DSO))
471  output[type].print_ip_opts |= EVSEL__PRINT_DSO;
472 
473  if (PRINT_FIELD(SYMOFFSET))
474  output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET;
475 
476  if (PRINT_FIELD(SRCLINE))
477  output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE;
478 }
479 
480 /*
481  * verify all user requested events exist and the samples
482  * have the expected data
483  */
485 {
486  unsigned int j;
487  struct perf_evsel *evsel;
488 
489  for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
490  evsel = perf_session__find_first_evtype(session, attr_type(j));
491 
492  /*
493  * even if fields is set to 0 (ie., show nothing) event must
494  * exist if user explicitly includes it on the command line
495  */
496  if (!evsel && output[j].user_set && !output[j].wildcard_set &&
497  j != OUTPUT_TYPE_SYNTH) {
498  pr_err("%s events do not exist. "
499  "Remove corresponding -F option to proceed.\n",
500  event_type(j));
501  return -1;
502  }
503 
504  if (evsel && output[j].fields &&
505  perf_evsel__check_attr(evsel, session))
506  return -1;
507 
508  if (evsel == NULL)
509  continue;
510 
511  set_print_ip_opts(&evsel->attr);
512  }
513 
514  if (!no_callchain) {
515  bool use_callchain = false;
516  bool not_pipe = false;
517 
518  evlist__for_each_entry(session->evlist, evsel) {
519  not_pipe = true;
520  if (evsel__has_callchain(evsel)) {
521  use_callchain = true;
522  break;
523  }
524  }
525  if (not_pipe && !use_callchain)
526  symbol_conf.use_callchain = false;
527  }
528 
529  /*
530  * set default for tracepoints to print symbols only
531  * if callchains are present
532  */
534  !output[PERF_TYPE_TRACEPOINT].user_set) {
535  j = PERF_TYPE_TRACEPOINT;
536 
537  evlist__for_each_entry(session->evlist, evsel) {
538  if (evsel->attr.type != j)
539  continue;
540 
541  if (evsel__has_callchain(evsel)) {
542  output[j].fields |= PERF_OUTPUT_IP;
543  output[j].fields |= PERF_OUTPUT_SYM;
544  output[j].fields |= PERF_OUTPUT_SYMOFFSET;
545  output[j].fields |= PERF_OUTPUT_DSO;
546  set_print_ip_opts(&evsel->attr);
547  goto out;
548  }
549  }
550  }
551 
552 out:
553  return 0;
554 }
555 
557  struct perf_event_attr *attr, FILE *fp)
558 {
559  struct regs_dump *regs = &sample->intr_regs;
560  uint64_t mask = attr->sample_regs_intr;
561  unsigned i = 0, r;
562  int printed = 0;
563 
564  if (!regs)
565  return 0;
566 
567  for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
568  u64 val = regs->regs[i++];
569  printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
570  }
571 
572  return printed;
573 }
574 
576  struct perf_event_attr *attr, FILE *fp)
577 {
578  struct regs_dump *regs = &sample->user_regs;
579  uint64_t mask = attr->sample_regs_user;
580  unsigned i = 0, r;
581  int printed = 0;
582 
583  if (!regs || !regs->regs)
584  return 0;
585 
586  printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi);
587 
588  for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
589  u64 val = regs->regs[i++];
590  printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
591  }
592 
593  return printed;
594 }
595 
597  struct thread *thread,
598  struct perf_evsel *evsel,
599  u32 type, FILE *fp)
600 {
601  struct perf_event_attr *attr = &evsel->attr;
602  unsigned long secs;
603  unsigned long long nsecs;
604  int printed = 0;
605 
606  if (PRINT_FIELD(COMM)) {
607  if (latency_format)
608  printed += fprintf(fp, "%8.8s ", thread__comm_str(thread));
609  else if (PRINT_FIELD(IP) && evsel__has_callchain(evsel) && symbol_conf.use_callchain)
610  printed += fprintf(fp, "%s ", thread__comm_str(thread));
611  else
612  printed += fprintf(fp, "%16s ", thread__comm_str(thread));
613  }
614 
615  if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
616  printed += fprintf(fp, "%5d/%-5d ", sample->pid, sample->tid);
617  else if (PRINT_FIELD(PID))
618  printed += fprintf(fp, "%5d ", sample->pid);
619  else if (PRINT_FIELD(TID))
620  printed += fprintf(fp, "%5d ", sample->tid);
621 
622  if (PRINT_FIELD(CPU)) {
623  if (latency_format)
624  printed += fprintf(fp, "%3d ", sample->cpu);
625  else
626  printed += fprintf(fp, "[%03d] ", sample->cpu);
627  }
628 
629  if (PRINT_FIELD(MISC)) {
630  int ret = 0;
631 
632  #define has(m) \
633  (sample->misc & PERF_RECORD_MISC_##m) == PERF_RECORD_MISC_##m
634 
635  if (has(KERNEL))
636  ret += fprintf(fp, "K");
637  if (has(USER))
638  ret += fprintf(fp, "U");
639  if (has(HYPERVISOR))
640  ret += fprintf(fp, "H");
641  if (has(GUEST_KERNEL))
642  ret += fprintf(fp, "G");
643  if (has(GUEST_USER))
644  ret += fprintf(fp, "g");
645 
646  switch (type) {
647  case PERF_RECORD_MMAP:
648  case PERF_RECORD_MMAP2:
649  if (has(MMAP_DATA))
650  ret += fprintf(fp, "M");
651  break;
652  case PERF_RECORD_COMM:
653  if (has(COMM_EXEC))
654  ret += fprintf(fp, "E");
655  break;
656  case PERF_RECORD_SWITCH:
657  case PERF_RECORD_SWITCH_CPU_WIDE:
658  if (has(SWITCH_OUT)) {
659  ret += fprintf(fp, "S");
660  if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT)
661  ret += fprintf(fp, "p");
662  }
663  default:
664  break;
665  }
666 
667  #undef has
668 
669  ret += fprintf(fp, "%*s", 6 - ret, " ");
670  printed += ret;
671  }
672 
673  if (PRINT_FIELD(TIME)) {
674  nsecs = sample->time;
675  secs = nsecs / NSEC_PER_SEC;
676  nsecs -= secs * NSEC_PER_SEC;
677 
678  if (nanosecs)
679  printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs);
680  else {
681  char sample_time[32];
682  timestamp__scnprintf_usec(sample->time, sample_time, sizeof(sample_time));
683  printed += fprintf(fp, "%12s: ", sample_time);
684  }
685  }
686 
687  return printed;
688 }
689 
690 static inline char
692 {
693  if (!(br->flags.mispred || br->flags.predicted))
694  return '-';
695 
696  return br->flags.predicted ? 'P' : 'M';
697 }
698 
700  struct thread *thread,
701  struct perf_event_attr *attr, FILE *fp)
702 {
703  struct branch_stack *br = sample->branch_stack;
704  struct addr_location alf, alt;
705  u64 i, from, to;
706  int printed = 0;
707 
708  if (!(br && br->nr))
709  return 0;
710 
711  for (i = 0; i < br->nr; i++) {
712  from = br->entries[i].from;
713  to = br->entries[i].to;
714 
715  if (PRINT_FIELD(DSO)) {
716  memset(&alf, 0, sizeof(alf));
717  memset(&alt, 0, sizeof(alt));
718  thread__find_map(thread, sample->cpumode, from, &alf);
719  thread__find_map(thread, sample->cpumode, to, &alt);
720  }
721 
722  printed += fprintf(fp, " 0x%"PRIx64, from);
723  if (PRINT_FIELD(DSO)) {
724  printed += fprintf(fp, "(");
725  printed += map__fprintf_dsoname(alf.map, fp);
726  printed += fprintf(fp, ")");
727  }
728 
729  printed += fprintf(fp, "/0x%"PRIx64, to);
730  if (PRINT_FIELD(DSO)) {
731  printed += fprintf(fp, "(");
732  printed += map__fprintf_dsoname(alt.map, fp);
733  printed += fprintf(fp, ")");
734  }
735 
736  printed += fprintf(fp, "/%c/%c/%c/%d ",
737  mispred_str( br->entries + i),
738  br->entries[i].flags.in_tx? 'X' : '-',
739  br->entries[i].flags.abort? 'A' : '-',
740  br->entries[i].flags.cycles);
741  }
742 
743  return printed;
744 }
745 
747  struct thread *thread,
748  struct perf_event_attr *attr, FILE *fp)
749 {
750  struct branch_stack *br = sample->branch_stack;
751  struct addr_location alf, alt;
752  u64 i, from, to;
753  int printed = 0;
754 
755  if (!(br && br->nr))
756  return 0;
757 
758  for (i = 0; i < br->nr; i++) {
759 
760  memset(&alf, 0, sizeof(alf));
761  memset(&alt, 0, sizeof(alt));
762  from = br->entries[i].from;
763  to = br->entries[i].to;
764 
765  thread__find_symbol(thread, sample->cpumode, from, &alf);
766  thread__find_symbol(thread, sample->cpumode, to, &alt);
767 
768  printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
769  if (PRINT_FIELD(DSO)) {
770  printed += fprintf(fp, "(");
771  printed += map__fprintf_dsoname(alf.map, fp);
772  printed += fprintf(fp, ")");
773  }
774  printed += fprintf(fp, "%c", '/');
775  printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp);
776  if (PRINT_FIELD(DSO)) {
777  printed += fprintf(fp, "(");
778  printed += map__fprintf_dsoname(alt.map, fp);
779  printed += fprintf(fp, ")");
780  }
781  printed += fprintf(fp, "/%c/%c/%c/%d ",
782  mispred_str( br->entries + i),
783  br->entries[i].flags.in_tx? 'X' : '-',
784  br->entries[i].flags.abort? 'A' : '-',
785  br->entries[i].flags.cycles);
786  }
787 
788  return printed;
789 }
790 
792  struct thread *thread,
793  struct perf_event_attr *attr, FILE *fp)
794 {
795  struct branch_stack *br = sample->branch_stack;
796  struct addr_location alf, alt;
797  u64 i, from, to;
798  int printed = 0;
799 
800  if (!(br && br->nr))
801  return 0;
802 
803  for (i = 0; i < br->nr; i++) {
804 
805  memset(&alf, 0, sizeof(alf));
806  memset(&alt, 0, sizeof(alt));
807  from = br->entries[i].from;
808  to = br->entries[i].to;
809 
810  if (thread__find_map(thread, sample->cpumode, from, &alf) &&
811  !alf.map->dso->adjust_symbols)
812  from = map__map_ip(alf.map, from);
813 
814  if (thread__find_map(thread, sample->cpumode, to, &alt) &&
815  !alt.map->dso->adjust_symbols)
816  to = map__map_ip(alt.map, to);
817 
818  printed += fprintf(fp, " 0x%"PRIx64, from);
819  if (PRINT_FIELD(DSO)) {
820  printed += fprintf(fp, "(");
821  printed += map__fprintf_dsoname(alf.map, fp);
822  printed += fprintf(fp, ")");
823  }
824  printed += fprintf(fp, "/0x%"PRIx64, to);
825  if (PRINT_FIELD(DSO)) {
826  printed += fprintf(fp, "(");
827  printed += map__fprintf_dsoname(alt.map, fp);
828  printed += fprintf(fp, ")");
829  }
830  printed += fprintf(fp, "/%c/%c/%c/%d ",
831  mispred_str(br->entries + i),
832  br->entries[i].flags.in_tx ? 'X' : '-',
833  br->entries[i].flags.abort ? 'A' : '-',
834  br->entries[i].flags.cycles);
835  }
836 
837  return printed;
838 }
839 #define MAXBB 16384UL
840 
841 static int grab_bb(u8 *buffer, u64 start, u64 end,
842  struct machine *machine, struct thread *thread,
843  bool *is64bit, u8 *cpumode, bool last)
844 {
845  long offset, len;
846  struct addr_location al;
847  bool kernel;
848 
849  if (!start || !end)
850  return 0;
851 
852  kernel = machine__kernel_ip(machine, start);
853  if (kernel)
854  *cpumode = PERF_RECORD_MISC_KERNEL;
855  else
856  *cpumode = PERF_RECORD_MISC_USER;
857 
858  /*
859  * Block overlaps between kernel and user.
860  * This can happen due to ring filtering
861  * On Intel CPUs the entry into the kernel is filtered,
862  * but the exit is not. Let the caller patch it up.
863  */
864  if (kernel != machine__kernel_ip(machine, end)) {
865  pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end);
866  return -ENXIO;
867  }
868 
869  memset(&al, 0, sizeof(al));
870  if (end - start > MAXBB - MAXINSN) {
871  if (last)
872  pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end);
873  else
874  pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start);
875  return 0;
876  }
877 
878  if (!thread__find_map(thread, *cpumode, start, &al) || !al.map->dso) {
879  pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
880  return 0;
881  }
882  if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) {
883  pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end);
884  return 0;
885  }
886 
887  /* Load maps to ensure dso->is_64_bit has been updated */
888  map__load(al.map);
889 
890  offset = al.map->map_ip(al.map, start);
891  len = dso__data_read_offset(al.map->dso, machine, offset, (u8 *)buffer,
892  end - start + MAXINSN);
893 
894  *is64bit = al.map->dso->is_64_bit;
895  if (len <= 0)
896  pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n",
897  start, end);
898  return len;
899 }
900 
901 static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
902  struct perf_insn *x, u8 *inbuf, int len,
903  int insn, FILE *fp)
904 {
905  int printed = fprintf(fp, "\t%016" PRIx64 "\t%-30s\t#%s%s%s%s", ip,
906  dump_insn(x, ip, inbuf, len, NULL),
907  en->flags.predicted ? " PRED" : "",
908  en->flags.mispred ? " MISPRED" : "",
909  en->flags.in_tx ? " INTX" : "",
910  en->flags.abort ? " ABORT" : "");
911  if (en->flags.cycles) {
912  printed += fprintf(fp, " %d cycles", en->flags.cycles);
913  if (insn)
914  printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
915  }
916  return printed + fprintf(fp, "\n");
917 }
918 
919 static int ip__fprintf_sym(uint64_t addr, struct thread *thread,
920  u8 cpumode, int cpu, struct symbol **lastsym,
921  struct perf_event_attr *attr, FILE *fp)
922 {
923  struct addr_location al;
924  int off, printed = 0;
925 
926  memset(&al, 0, sizeof(al));
927 
928  thread__find_map(thread, cpumode, addr, &al);
929 
930  if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end)
931  return 0;
932 
933  al.cpu = cpu;
934  al.sym = NULL;
935  if (al.map)
936  al.sym = map__find_symbol(al.map, al.addr);
937 
938  if (!al.sym)
939  return 0;
940 
941  if (al.addr < al.sym->end)
942  off = al.addr - al.sym->start;
943  else
944  off = al.addr - al.map->start - al.sym->start;
945  printed += fprintf(fp, "\t%s", al.sym->name);
946  if (off)
947  printed += fprintf(fp, "%+d", off);
948  printed += fprintf(fp, ":");
949  if (PRINT_FIELD(SRCLINE))
950  printed += map__fprintf_srcline(al.map, al.addr, "\t", fp);
951  printed += fprintf(fp, "\n");
952  *lastsym = al.sym;
953 
954  return printed;
955 }
956 
958  struct thread *thread,
959  struct perf_event_attr *attr,
960  struct machine *machine, FILE *fp)
961 {
962  struct branch_stack *br = sample->branch_stack;
963  u64 start, end;
964  int i, insn, len, nr, ilen, printed = 0;
965  struct perf_insn x;
966  u8 buffer[MAXBB];
967  unsigned off;
968  struct symbol *lastsym = NULL;
969 
970  if (!(br && br->nr))
971  return 0;
972  nr = br->nr;
973  if (max_blocks && nr > max_blocks + 1)
974  nr = max_blocks + 1;
975 
976  x.thread = thread;
977  x.cpu = sample->cpu;
978 
979  printed += fprintf(fp, "%c", '\n');
980 
981  /* Handle first from jump, of which we don't know the entry. */
982  len = grab_bb(buffer, br->entries[nr-1].from,
983  br->entries[nr-1].from,
984  machine, thread, &x.is64bit, &x.cpumode, false);
985  if (len > 0) {
986  printed += ip__fprintf_sym(br->entries[nr - 1].from, thread,
987  x.cpumode, x.cpu, &lastsym, attr, fp);
988  printed += ip__fprintf_jump(br->entries[nr - 1].from, &br->entries[nr - 1],
989  &x, buffer, len, 0, fp);
990  }
991 
992  /* Print all blocks */
993  for (i = nr - 2; i >= 0; i--) {
994  if (br->entries[i].from || br->entries[i].to)
995  pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i,
996  br->entries[i].from,
997  br->entries[i].to);
998  start = br->entries[i + 1].to;
999  end = br->entries[i].from;
1000 
1001  len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
1002  /* Patch up missing kernel transfers due to ring filters */
1003  if (len == -ENXIO && i > 0) {
1004  end = br->entries[--i].from;
1005  pr_debug("\tpatching up to %" PRIx64 "-%" PRIx64 "\n", start, end);
1006  len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false);
1007  }
1008  if (len <= 0)
1009  continue;
1010 
1011  insn = 0;
1012  for (off = 0;; off += ilen) {
1013  uint64_t ip = start + off;
1014 
1015  printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
1016  if (ip == end) {
1017  printed += ip__fprintf_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn, fp);
1018  break;
1019  } else {
1020  printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip,
1021  dump_insn(&x, ip, buffer + off, len - off, &ilen));
1022  if (ilen == 0)
1023  break;
1024  insn++;
1025  }
1026  }
1027  }
1028 
1029  /*
1030  * Hit the branch? In this case we are already done, and the target
1031  * has not been executed yet.
1032  */
1033  if (br->entries[0].from == sample->ip)
1034  goto out;
1035  if (br->entries[0].flags.abort)
1036  goto out;
1037 
1038  /*
1039  * Print final block upto sample
1040  */
1041  start = br->entries[0].to;
1042  end = sample->ip;
1043  len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true);
1044  printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
1045  if (len <= 0) {
1046  /* Print at least last IP if basic block did not work */
1047  len = grab_bb(buffer, sample->ip, sample->ip,
1048  machine, thread, &x.is64bit, &x.cpumode, false);
1049  if (len <= 0)
1050  goto out;
1051 
1052  printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip,
1053  dump_insn(&x, sample->ip, buffer, len, NULL));
1054  goto out;
1055  }
1056  for (off = 0; off <= end - start; off += ilen) {
1057  printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", start + off,
1058  dump_insn(&x, start + off, buffer + off, len - off, &ilen));
1059  if (ilen == 0)
1060  break;
1061  }
1062 out:
1063  return printed;
1064 }
1065 
1067  struct thread *thread,
1068  struct perf_event_attr *attr, FILE *fp)
1069 {
1070  struct addr_location al;
1071  int printed = fprintf(fp, "%16" PRIx64, sample->addr);
1072 
1073  if (!sample_addr_correlates_sym(attr))
1074  goto out;
1075 
1076  thread__resolve(thread, &al, sample);
1077 
1078  if (PRINT_FIELD(SYM)) {
1079  printed += fprintf(fp, " ");
1080  if (PRINT_FIELD(SYMOFFSET))
1081  printed += symbol__fprintf_symname_offs(al.sym, &al, fp);
1082  else
1083  printed += symbol__fprintf_symname(al.sym, fp);
1084  }
1085 
1086  if (PRINT_FIELD(DSO)) {
1087  printed += fprintf(fp, " (");
1088  printed += map__fprintf_dsoname(al.map, fp);
1089  printed += fprintf(fp, ")");
1090  }
1091 out:
1092  return printed;
1093 }
1094 
1096  struct perf_evsel *evsel,
1097  struct thread *thread,
1098  struct addr_location *al, FILE *fp)
1099 {
1100  struct perf_event_attr *attr = &evsel->attr;
1101  size_t depth = thread_stack__depth(thread);
1102  struct addr_location addr_al;
1103  const char *name = NULL;
1104  static int spacing;
1105  int len = 0;
1106  u64 ip = 0;
1107 
1108  /*
1109  * The 'return' has already been popped off the stack so the depth has
1110  * to be adjusted to match the 'call'.
1111  */
1112  if (thread->ts && sample->flags & PERF_IP_FLAG_RETURN)
1113  depth += 1;
1114 
1115  if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) {
1116  if (sample_addr_correlates_sym(attr)) {
1117  thread__resolve(thread, &addr_al, sample);
1118  if (addr_al.sym)
1119  name = addr_al.sym->name;
1120  else
1121  ip = sample->addr;
1122  } else {
1123  ip = sample->addr;
1124  }
1125  } else if (sample->flags & (PERF_IP_FLAG_RETURN | PERF_IP_FLAG_TRACE_END)) {
1126  if (al->sym)
1127  name = al->sym->name;
1128  else
1129  ip = sample->ip;
1130  }
1131 
1132  if (name)
1133  len = fprintf(fp, "%*s%s", (int)depth * 4, "", name);
1134  else if (ip)
1135  len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip);
1136 
1137  if (len < 0)
1138  return len;
1139 
1140  /*
1141  * Try to keep the output length from changing frequently so that the
1142  * output lines up more nicely.
1143  */
1144  if (len > spacing || (len && len < spacing - 52))
1145  spacing = round_up(len + 4, 32);
1146 
1147  if (len < spacing)
1148  len += fprintf(fp, "%*s", spacing - len, "");
1149 
1150  return len;
1151 }
1152 
1154  struct perf_event_attr *attr,
1155  struct thread *thread,
1156  struct machine *machine, FILE *fp)
1157 {
1158  int printed = 0;
1159 
1160  if (PRINT_FIELD(INSNLEN))
1161  printed += fprintf(fp, " ilen: %d", sample->insn_len);
1162  if (PRINT_FIELD(INSN)) {
1163  int i;
1164 
1165  printed += fprintf(fp, " insn:");
1166  for (i = 0; i < sample->insn_len; i++)
1167  printed += fprintf(fp, " %02x", (unsigned char)sample->insn[i]);
1168  }
1169  if (PRINT_FIELD(BRSTACKINSN))
1170  printed += perf_sample__fprintf_brstackinsn(sample, thread, attr, machine, fp);
1171 
1172  return printed;
1173 }
1174 
1176  struct perf_evsel *evsel,
1177  struct thread *thread,
1178  struct addr_location *al,
1179  struct machine *machine, FILE *fp)
1180 {
1181  struct perf_event_attr *attr = &evsel->attr;
1182  unsigned int type = output_type(attr->type);
1183  bool print_srcline_last = false;
1184  int printed = 0;
1185 
1186  if (PRINT_FIELD(CALLINDENT))
1187  printed += perf_sample__fprintf_callindent(sample, evsel, thread, al, fp);
1188 
1189  /* print branch_from information */
1190  if (PRINT_FIELD(IP)) {
1191  unsigned int print_opts = output[type].print_ip_opts;
1192  struct callchain_cursor *cursor = NULL;
1193 
1194  if (symbol_conf.use_callchain && sample->callchain &&
1196  sample, NULL, NULL, scripting_max_stack) == 0)
1197  cursor = &callchain_cursor;
1198 
1199  if (cursor == NULL) {
1200  printed += fprintf(fp, " ");
1201  if (print_opts & EVSEL__PRINT_SRCLINE) {
1202  print_srcline_last = true;
1203  print_opts &= ~EVSEL__PRINT_SRCLINE;
1204  }
1205  } else
1206  printed += fprintf(fp, "\n");
1207 
1208  printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor, fp);
1209  }
1210 
1211  /* print branch_to information */
1212  if (PRINT_FIELD(ADDR) ||
1213  ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
1214  !output[type].user_set)) {
1215  printed += fprintf(fp, " => ");
1216  printed += perf_sample__fprintf_addr(sample, thread, attr, fp);
1217  }
1218 
1219  if (print_srcline_last)
1220  printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp);
1221 
1222  printed += perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
1223  return printed + fprintf(fp, "\n");
1224 }
1225 
1226 static struct {
1227  u32 flags;
1228  const char *name;
1229 } sample_flags[] = {
1233  {PERF_IP_FLAG_BRANCH, "jmp"},
1243  {0, NULL}
1244 };
1245 
1246 static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
1247 {
1248  const char *chars = PERF_IP_FLAG_CHARS;
1249  const int n = strlen(PERF_IP_FLAG_CHARS);
1250  bool in_tx = flags & PERF_IP_FLAG_IN_TX;
1251  const char *name = NULL;
1252  char str[33];
1253  int i, pos = 0;
1254 
1255  for (i = 0; sample_flags[i].name ; i++) {
1256  if (sample_flags[i].flags == (flags & ~PERF_IP_FLAG_IN_TX)) {
1257  name = sample_flags[i].name;
1258  break;
1259  }
1260  }
1261 
1262  for (i = 0; i < n; i++, flags >>= 1) {
1263  if (flags & 1)
1264  str[pos++] = chars[i];
1265  }
1266  for (; i < 32; i++, flags >>= 1) {
1267  if (flags & 1)
1268  str[pos++] = '?';
1269  }
1270  str[pos] = 0;
1271 
1272  if (name)
1273  return fprintf(fp, " %-7s%4s ", name, in_tx ? "(x)" : "");
1274 
1275  return fprintf(fp, " %-11s ", str);
1276 }
1277 
1279  int line_no;
1280  bool hit_nul;
1282 };
1283 
1285  unsigned int val,
1286  void *extra, FILE *fp)
1287 {
1288  unsigned char ch = (unsigned char)val;
1289  struct printer_data *printer_data = extra;
1290  int printed = 0;
1291 
1292  switch (op) {
1294  printed += fprintf(fp, "\n");
1295  break;
1297  printed += fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" :
1298  " ");
1299  break;
1300  case BINARY_PRINT_ADDR:
1301  printed += fprintf(fp, " %04x:", val);
1302  break;
1303  case BINARY_PRINT_NUM_DATA:
1304  printed += fprintf(fp, " %02x", val);
1305  break;
1306  case BINARY_PRINT_NUM_PAD:
1307  printed += fprintf(fp, " ");
1308  break;
1309  case BINARY_PRINT_SEP:
1310  printed += fprintf(fp, " ");
1311  break;
1313  if (printer_data->hit_nul && ch)
1314  printer_data->is_printable = false;
1315 
1316  if (!isprint(ch)) {
1317  printed += fprintf(fp, "%c", '.');
1318 
1319  if (!printer_data->is_printable)
1320  break;
1321 
1322  if (ch == '\0')
1323  printer_data->hit_nul = true;
1324  else
1325  printer_data->is_printable = false;
1326  } else {
1327  printed += fprintf(fp, "%c", ch);
1328  }
1329  break;
1330  case BINARY_PRINT_CHAR_PAD:
1331  printed += fprintf(fp, " ");
1332  break;
1333  case BINARY_PRINT_LINE_END:
1334  printed += fprintf(fp, "\n");
1335  printer_data->line_no++;
1336  break;
1337  case BINARY_PRINT_DATA_END:
1338  default:
1339  break;
1340  }
1341 
1342  return printed;
1343 }
1344 
1346 {
1347  unsigned int nr_bytes = sample->raw_size;
1348  struct printer_data printer_data = {0, false, true};
1349  int printed = binary__fprintf(sample->raw_data, nr_bytes, 8,
1350  sample__fprintf_bpf_output, &printer_data, fp);
1351 
1352  if (printer_data.is_printable && printer_data.hit_nul)
1353  printed += fprintf(fp, "%17s \"%s\"\n", "BPF string:", (char *)(sample->raw_data));
1354 
1355  return printed;
1356 }
1357 
1358 static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp)
1359 {
1360  if (len > 0 && len < spacing)
1361  return fprintf(fp, "%*s", spacing - len, "");
1362 
1363  return 0;
1364 }
1365 
1366 static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)
1367 {
1368  return perf_sample__fprintf_spacing(len, 34, fp);
1369 }
1370 
1372 {
1374  int len;
1375 
1376  if (perf_sample__bad_synth_size(sample, *data))
1377  return 0;
1378 
1379  len = fprintf(fp, " IP: %u payload: %#" PRIx64 " ",
1380  data->ip, le64_to_cpu(data->payload));
1381  return len + perf_sample__fprintf_pt_spacing(len, fp);
1382 }
1383 
1385 {
1387  int len;
1388 
1389  if (perf_sample__bad_synth_size(sample, *data))
1390  return 0;
1391 
1392  len = fprintf(fp, " hints: %#x extensions: %#x ",
1393  data->hints, data->extensions);
1394  return len + perf_sample__fprintf_pt_spacing(len, fp);
1395 }
1396 
1398 {
1400  int len;
1401 
1402  if (perf_sample__bad_synth_size(sample, *data))
1403  return 0;
1404 
1405  len = fprintf(fp, " hw: %u cstate: %u sub-cstate: %u ",
1406  data->hw, data->cstate, data->subcstate);
1407  return len + perf_sample__fprintf_pt_spacing(len, fp);
1408 }
1409 
1411 {
1413  int len;
1414 
1415  if (perf_sample__bad_synth_size(sample, *data))
1416  return 0;
1417 
1418  len = fprintf(fp, " IP: %u ", data->ip);
1419  return len + perf_sample__fprintf_pt_spacing(len, fp);
1420 }
1421 
1423 {
1425  int len;
1426 
1427  if (perf_sample__bad_synth_size(sample, *data))
1428  return 0;
1429 
1430  len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ",
1431  data->deepest_cstate, data->last_cstate,
1432  data->wake_reason);
1433  return len + perf_sample__fprintf_pt_spacing(len, fp);
1434 }
1435 
1437 {
1439  unsigned int percent, freq;
1440  int len;
1441 
1442  if (perf_sample__bad_synth_size(sample, *data))
1443  return 0;
1444 
1445  freq = (le32_to_cpu(data->freq) + 500) / 1000;
1446  len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq);
1447  if (data->max_nonturbo) {
1448  percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10;
1449  len += fprintf(fp, "(%3u%%) ", percent);
1450  }
1451  return len + perf_sample__fprintf_pt_spacing(len, fp);
1452 }
1453 
1455  struct perf_evsel *evsel, FILE *fp)
1456 {
1457  switch (evsel->attr.config) {
1459  return perf_sample__fprintf_synth_ptwrite(sample, fp);
1461  return perf_sample__fprintf_synth_mwait(sample, fp);
1462  case PERF_SYNTH_INTEL_PWRE:
1463  return perf_sample__fprintf_synth_pwre(sample, fp);
1465  return perf_sample__fprintf_synth_exstop(sample, fp);
1466  case PERF_SYNTH_INTEL_PWRX:
1467  return perf_sample__fprintf_synth_pwrx(sample, fp);
1468  case PERF_SYNTH_INTEL_CBR:
1469  return perf_sample__fprintf_synth_cbr(sample, fp);
1470  default:
1471  break;
1472  }
1473 
1474  return 0;
1475 }
1476 
1477 struct perf_script {
1478  struct perf_tool tool;
1488  struct cpu_map *cpus;
1491  const char *time_str;
1495 };
1496 
1497 static int perf_evlist__max_name_len(struct perf_evlist *evlist)
1498 {
1499  struct perf_evsel *evsel;
1500  int max = 0;
1501 
1502  evlist__for_each_entry(evlist, evsel) {
1503  int len = strlen(perf_evsel__name(evsel));
1504 
1505  max = MAX(len, max);
1506  }
1507 
1508  return max;
1509 }
1510 
1511 static int data_src__fprintf(u64 data_src, FILE *fp)
1512 {
1513  struct mem_info mi = { .data_src.val = data_src };
1514  char decode[100];
1515  char out[100];
1516  static int maxlen;
1517  int len;
1518 
1519  perf_script__meminfo_scnprintf(decode, 100, &mi);
1520 
1521  len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode);
1522  if (maxlen < len)
1523  maxlen = len;
1524 
1525  return fprintf(fp, "%-*s", maxlen, out);
1526 }
1527 
1528 struct metric_ctx {
1530  struct thread *thread;
1532  FILE *fp;
1533 };
1534 
1535 static void script_print_metric(void *ctx, const char *color,
1536  const char *fmt,
1537  const char *unit, double val)
1538 {
1539  struct metric_ctx *mctx = ctx;
1540 
1541  if (!fmt)
1542  return;
1543  perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel,
1544  PERF_RECORD_SAMPLE, mctx->fp);
1545  fputs("\tmetric: ", mctx->fp);
1546  if (color)
1547  color_fprintf(mctx->fp, color, fmt, val);
1548  else
1549  printf(fmt, val);
1550  fprintf(mctx->fp, " %s\n", unit);
1551 }
1552 
1553 static void script_new_line(void *ctx)
1554 {
1555  struct metric_ctx *mctx = ctx;
1556 
1557  perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel,
1558  PERF_RECORD_SAMPLE, mctx->fp);
1559  fputs("\tmetric: ", mctx->fp);
1560 }
1561 
1562 static void perf_sample__fprint_metric(struct perf_script *script,
1563  struct thread *thread,
1564  struct perf_evsel *evsel,
1565  struct perf_sample *sample,
1566  FILE *fp)
1567 {
1568  struct perf_stat_output_ctx ctx = {
1570  .new_line = script_new_line,
1571  .ctx = &(struct metric_ctx) {
1572  .sample = sample,
1573  .thread = thread,
1574  .evsel = evsel,
1575  .fp = fp,
1576  },
1577  .force_header = false,
1578  };
1579  struct perf_evsel *ev2;
1580  static bool init;
1581  u64 val;
1582 
1583  if (!init) {
1585  init = true;
1586  }
1587  if (!evsel->stats)
1588  perf_evlist__alloc_stats(script->session->evlist, false);
1589  if (evsel_script(evsel->leader)->gnum++ == 0)
1591  val = sample->period * evsel->scale;
1593  val,
1594  sample->cpu,
1595  &rt_stat);
1596  evsel_script(evsel)->val = val;
1597  if (evsel_script(evsel->leader)->gnum == evsel->leader->nr_members) {
1598  for_each_group_member (ev2, evsel->leader) {
1600  evsel_script(ev2)->val,
1601  sample->cpu,
1602  &ctx,
1603  NULL,
1604  &rt_stat);
1605  }
1606  evsel_script(evsel->leader)->gnum = 0;
1607  }
1608 }
1609 
1610 static void process_event(struct perf_script *script,
1611  struct perf_sample *sample, struct perf_evsel *evsel,
1612  struct addr_location *al,
1613  struct machine *machine)
1614 {
1615  struct thread *thread = al->thread;
1616  struct perf_event_attr *attr = &evsel->attr;
1617  unsigned int type = output_type(attr->type);
1618  struct perf_evsel_script *es = evsel->priv;
1619  FILE *fp = es->fp;
1620 
1621  if (output[type].fields == 0)
1622  return;
1623 
1624  ++es->samples;
1625 
1626  perf_sample__fprintf_start(sample, thread, evsel,
1627  PERF_RECORD_SAMPLE, fp);
1628 
1629  if (PRINT_FIELD(PERIOD))
1630  fprintf(fp, "%10" PRIu64 " ", sample->period);
1631 
1632  if (PRINT_FIELD(EVNAME)) {
1633  const char *evname = perf_evsel__name(evsel);
1634 
1635  if (!script->name_width)
1636  script->name_width = perf_evlist__max_name_len(script->session->evlist);
1637 
1638  fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]");
1639  }
1640 
1641  if (print_flags)
1642  perf_sample__fprintf_flags(sample->flags, fp);
1643 
1644  if (is_bts_event(attr)) {
1645  perf_sample__fprintf_bts(sample, evsel, thread, al, machine, fp);
1646  return;
1647  }
1648 
1649  if (PRINT_FIELD(TRACE)) {
1650  event_format__fprintf(evsel->tp_format, sample->cpu,
1651  sample->raw_data, sample->raw_size, fp);
1652  }
1653 
1654  if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH))
1655  perf_sample__fprintf_synth(sample, evsel, fp);
1656 
1657  if (PRINT_FIELD(ADDR))
1658  perf_sample__fprintf_addr(sample, thread, attr, fp);
1659 
1660  if (PRINT_FIELD(DATA_SRC))
1661  data_src__fprintf(sample->data_src, fp);
1662 
1663  if (PRINT_FIELD(WEIGHT))
1664  fprintf(fp, "%16" PRIu64, sample->weight);
1665 
1666  if (PRINT_FIELD(IP)) {
1667  struct callchain_cursor *cursor = NULL;
1668 
1669  if (symbol_conf.use_callchain && sample->callchain &&
1671  sample, NULL, NULL, scripting_max_stack) == 0)
1672  cursor = &callchain_cursor;
1673 
1674  fputc(cursor ? '\n' : ' ', fp);
1675  sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, fp);
1676  }
1677 
1678  if (PRINT_FIELD(IREGS))
1679  perf_sample__fprintf_iregs(sample, attr, fp);
1680 
1681  if (PRINT_FIELD(UREGS))
1682  perf_sample__fprintf_uregs(sample, attr, fp);
1683 
1684  if (PRINT_FIELD(BRSTACK))
1685  perf_sample__fprintf_brstack(sample, thread, attr, fp);
1686  else if (PRINT_FIELD(BRSTACKSYM))
1687  perf_sample__fprintf_brstacksym(sample, thread, attr, fp);
1688  else if (PRINT_FIELD(BRSTACKOFF))
1689  perf_sample__fprintf_brstackoff(sample, thread, attr, fp);
1690 
1691  if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
1692  perf_sample__fprintf_bpf_output(sample, fp);
1693  perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
1694 
1695  if (PRINT_FIELD(PHYS_ADDR))
1696  fprintf(fp, "%16" PRIx64, sample->phys_addr);
1697  fprintf(fp, "\n");
1698 
1699  if (PRINT_FIELD(METRIC))
1700  perf_sample__fprint_metric(script, thread, evsel, sample, fp);
1701 }
1702 
1704 
1705 static void __process_stat(struct perf_evsel *counter, u64 tstamp)
1706 {
1707  int nthreads = thread_map__nr(counter->threads);
1708  int ncpus = perf_evsel__nr_cpus(counter);
1709  int cpu, thread;
1710  static int header_printed;
1711 
1712  if (counter->system_wide)
1713  nthreads = 1;
1714 
1715  if (!header_printed) {
1716  printf("%3s %8s %15s %15s %15s %15s %s\n",
1717  "CPU", "THREAD", "VAL", "ENA", "RUN", "TIME", "EVENT");
1718  header_printed = 1;
1719  }
1720 
1721  for (thread = 0; thread < nthreads; thread++) {
1722  for (cpu = 0; cpu < ncpus; cpu++) {
1723  struct perf_counts_values *counts;
1724 
1725  counts = perf_counts(counter->counts, cpu, thread);
1726 
1727  printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n",
1728  counter->cpus->map[cpu],
1729  thread_map__pid(counter->threads, thread),
1730  counts->val,
1731  counts->ena,
1732  counts->run,
1733  tstamp,
1734  perf_evsel__name(counter));
1735  }
1736  }
1737 }
1738 
1739 static void process_stat(struct perf_evsel *counter, u64 tstamp)
1740 {
1741  if (scripting_ops && scripting_ops->process_stat)
1742  scripting_ops->process_stat(&stat_config, counter, tstamp);
1743  else
1744  __process_stat(counter, tstamp);
1745 }
1746 
1747 static void process_stat_interval(u64 tstamp)
1748 {
1749  if (scripting_ops && scripting_ops->process_stat_interval)
1750  scripting_ops->process_stat_interval(tstamp);
1751 }
1752 
1753 static void setup_scripting(void)
1754 {
1757 }
1758 
1759 static int flush_scripting(void)
1760 {
1761  return scripting_ops ? scripting_ops->flush_script() : 0;
1762 }
1763 
1764 static int cleanup_scripting(void)
1765 {
1766  pr_debug("\nperf script stopped\n");
1767 
1768  return scripting_ops ? scripting_ops->stop_script() : 0;
1769 }
1770 
1772  union perf_event *event,
1773  struct perf_sample *sample,
1774  struct perf_evsel *evsel,
1775  struct machine *machine)
1776 {
1777  struct perf_script *scr = container_of(tool, struct perf_script, tool);
1778  struct addr_location al;
1779 
1781  sample->time)) {
1782  return 0;
1783  }
1784 
1785  if (debug_mode) {
1786  if (sample->time < last_timestamp) {
1787  pr_err("Samples misordered, previous: %" PRIu64
1788  " this: %" PRIu64 "\n", last_timestamp,
1789  sample->time);
1790  nr_unordered++;
1791  }
1792  last_timestamp = sample->time;
1793  return 0;
1794  }
1795 
1796  if (machine__resolve(machine, &al, sample) < 0) {
1797  pr_err("problem processing %d event, skipping it.\n",
1798  event->header.type);
1799  return -1;
1800  }
1801 
1802  if (al.filtered)
1803  goto out_put;
1804 
1805  if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
1806  goto out_put;
1807 
1808  if (scripting_ops)
1809  scripting_ops->process_event(event, sample, evsel, &al);
1810  else
1811  process_event(scr, sample, evsel, &al, machine);
1812 
1813 out_put:
1814  addr_location__put(&al);
1815  return 0;
1816 }
1817 
1818 static int process_attr(struct perf_tool *tool, union perf_event *event,
1819  struct perf_evlist **pevlist)
1820 {
1821  struct perf_script *scr = container_of(tool, struct perf_script, tool);
1822  struct perf_evlist *evlist;
1823  struct perf_evsel *evsel, *pos;
1824  int err;
1825 
1826  err = perf_event__process_attr(tool, event, pevlist);
1827  if (err)
1828  return err;
1829 
1830  evlist = *pevlist;
1831  evsel = perf_evlist__last(*pevlist);
1832 
1833  if (evsel->attr.type >= PERF_TYPE_MAX &&
1834  evsel->attr.type != PERF_TYPE_SYNTH)
1835  return 0;
1836 
1837  evlist__for_each_entry(evlist, pos) {
1838  if (pos->attr.type == evsel->attr.type && pos != evsel)
1839  return 0;
1840  }
1841 
1842  set_print_ip_opts(&evsel->attr);
1843 
1844  if (evsel->attr.sample_type)
1845  err = perf_evsel__check_attr(evsel, scr->session);
1846 
1847  return err;
1848 }
1849 
1850 static int process_comm_event(struct perf_tool *tool,
1851  union perf_event *event,
1852  struct perf_sample *sample,
1853  struct machine *machine)
1854 {
1855  struct thread *thread;
1856  struct perf_script *script = container_of(tool, struct perf_script, tool);
1857  struct perf_session *session = script->session;
1858  struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1859  int ret = -1;
1860 
1861  thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid);
1862  if (thread == NULL) {
1863  pr_debug("problem processing COMM event, skipping it.\n");
1864  return -1;
1865  }
1866 
1867  if (perf_event__process_comm(tool, event, sample, machine) < 0)
1868  goto out;
1869 
1870  if (!evsel->attr.sample_id_all) {
1871  sample->cpu = 0;
1872  sample->time = 0;
1873  sample->tid = event->comm.tid;
1874  sample->pid = event->comm.pid;
1875  }
1876  perf_sample__fprintf_start(sample, thread, evsel,
1877  PERF_RECORD_COMM, stdout);
1878  perf_event__fprintf(event, stdout);
1879  ret = 0;
1880 out:
1881  thread__put(thread);
1882  return ret;
1883 }
1884 
1886  union perf_event *event,
1887  struct perf_sample *sample,
1888  struct machine *machine)
1889 {
1890  struct thread *thread;
1891  struct perf_script *script = container_of(tool, struct perf_script, tool);
1892  struct perf_session *session = script->session;
1893  struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1894  int ret = -1;
1895 
1896  thread = machine__findnew_thread(machine, event->namespaces.pid,
1897  event->namespaces.tid);
1898  if (thread == NULL) {
1899  pr_debug("problem processing NAMESPACES event, skipping it.\n");
1900  return -1;
1901  }
1902 
1903  if (perf_event__process_namespaces(tool, event, sample, machine) < 0)
1904  goto out;
1905 
1906  if (!evsel->attr.sample_id_all) {
1907  sample->cpu = 0;
1908  sample->time = 0;
1909  sample->tid = event->namespaces.tid;
1910  sample->pid = event->namespaces.pid;
1911  }
1912  perf_sample__fprintf_start(sample, thread, evsel,
1913  PERF_RECORD_NAMESPACES, stdout);
1914  perf_event__fprintf(event, stdout);
1915  ret = 0;
1916 out:
1917  thread__put(thread);
1918  return ret;
1919 }
1920 
1921 static int process_fork_event(struct perf_tool *tool,
1922  union perf_event *event,
1923  struct perf_sample *sample,
1924  struct machine *machine)
1925 {
1926  struct thread *thread;
1927  struct perf_script *script = container_of(tool, struct perf_script, tool);
1928  struct perf_session *session = script->session;
1929  struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1930 
1931  if (perf_event__process_fork(tool, event, sample, machine) < 0)
1932  return -1;
1933 
1934  thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid);
1935  if (thread == NULL) {
1936  pr_debug("problem processing FORK event, skipping it.\n");
1937  return -1;
1938  }
1939 
1940  if (!evsel->attr.sample_id_all) {
1941  sample->cpu = 0;
1942  sample->time = event->fork.time;
1943  sample->tid = event->fork.tid;
1944  sample->pid = event->fork.pid;
1945  }
1946  perf_sample__fprintf_start(sample, thread, evsel,
1947  PERF_RECORD_FORK, stdout);
1948  perf_event__fprintf(event, stdout);
1949  thread__put(thread);
1950 
1951  return 0;
1952 }
1953 static int process_exit_event(struct perf_tool *tool,
1954  union perf_event *event,
1955  struct perf_sample *sample,
1956  struct machine *machine)
1957 {
1958  int err = 0;
1959  struct thread *thread;
1960  struct perf_script *script = container_of(tool, struct perf_script, tool);
1961  struct perf_session *session = script->session;
1962  struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1963 
1964  thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid);
1965  if (thread == NULL) {
1966  pr_debug("problem processing EXIT event, skipping it.\n");
1967  return -1;
1968  }
1969 
1970  if (!evsel->attr.sample_id_all) {
1971  sample->cpu = 0;
1972  sample->time = 0;
1973  sample->tid = event->fork.tid;
1974  sample->pid = event->fork.pid;
1975  }
1976  perf_sample__fprintf_start(sample, thread, evsel,
1977  PERF_RECORD_EXIT, stdout);
1978  perf_event__fprintf(event, stdout);
1979 
1980  if (perf_event__process_exit(tool, event, sample, machine) < 0)
1981  err = -1;
1982 
1983  thread__put(thread);
1984  return err;
1985 }
1986 
1987 static int process_mmap_event(struct perf_tool *tool,
1988  union perf_event *event,
1989  struct perf_sample *sample,
1990  struct machine *machine)
1991 {
1992  struct thread *thread;
1993  struct perf_script *script = container_of(tool, struct perf_script, tool);
1994  struct perf_session *session = script->session;
1995  struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
1996 
1997  if (perf_event__process_mmap(tool, event, sample, machine) < 0)
1998  return -1;
1999 
2000  thread = machine__findnew_thread(machine, event->mmap.pid, event->mmap.tid);
2001  if (thread == NULL) {
2002  pr_debug("problem processing MMAP event, skipping it.\n");
2003  return -1;
2004  }
2005 
2006  if (!evsel->attr.sample_id_all) {
2007  sample->cpu = 0;
2008  sample->time = 0;
2009  sample->tid = event->mmap.tid;
2010  sample->pid = event->mmap.pid;
2011  }
2012  perf_sample__fprintf_start(sample, thread, evsel,
2013  PERF_RECORD_MMAP, stdout);
2014  perf_event__fprintf(event, stdout);
2015  thread__put(thread);
2016  return 0;
2017 }
2018 
2020  union perf_event *event,
2021  struct perf_sample *sample,
2022  struct machine *machine)
2023 {
2024  struct thread *thread;
2025  struct perf_script *script = container_of(tool, struct perf_script, tool);
2026  struct perf_session *session = script->session;
2027  struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2028 
2029  if (perf_event__process_mmap2(tool, event, sample, machine) < 0)
2030  return -1;
2031 
2032  thread = machine__findnew_thread(machine, event->mmap2.pid, event->mmap2.tid);
2033  if (thread == NULL) {
2034  pr_debug("problem processing MMAP2 event, skipping it.\n");
2035  return -1;
2036  }
2037 
2038  if (!evsel->attr.sample_id_all) {
2039  sample->cpu = 0;
2040  sample->time = 0;
2041  sample->tid = event->mmap2.tid;
2042  sample->pid = event->mmap2.pid;
2043  }
2044  perf_sample__fprintf_start(sample, thread, evsel,
2045  PERF_RECORD_MMAP2, stdout);
2046  perf_event__fprintf(event, stdout);
2047  thread__put(thread);
2048  return 0;
2049 }
2050 
2052  union perf_event *event,
2053  struct perf_sample *sample,
2054  struct machine *machine)
2055 {
2056  struct thread *thread;
2057  struct perf_script *script = container_of(tool, struct perf_script, tool);
2058  struct perf_session *session = script->session;
2059  struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2060 
2061  if (perf_event__process_switch(tool, event, sample, machine) < 0)
2062  return -1;
2063 
2064  thread = machine__findnew_thread(machine, sample->pid,
2065  sample->tid);
2066  if (thread == NULL) {
2067  pr_debug("problem processing SWITCH event, skipping it.\n");
2068  return -1;
2069  }
2070 
2071  perf_sample__fprintf_start(sample, thread, evsel,
2072  PERF_RECORD_SWITCH, stdout);
2073  perf_event__fprintf(event, stdout);
2074  thread__put(thread);
2075  return 0;
2076 }
2077 
2078 static int
2080  union perf_event *event,
2081  struct perf_sample *sample,
2082  struct machine *machine)
2083 {
2084  struct perf_script *script = container_of(tool, struct perf_script, tool);
2085  struct perf_session *session = script->session;
2086  struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
2087  struct thread *thread;
2088 
2089  thread = machine__findnew_thread(machine, sample->pid,
2090  sample->tid);
2091  if (thread == NULL)
2092  return -1;
2093 
2094  perf_sample__fprintf_start(sample, thread, evsel,
2095  PERF_RECORD_LOST, stdout);
2096  perf_event__fprintf(event, stdout);
2097  thread__put(thread);
2098  return 0;
2099 }
2100 
2101 static int
2103  union perf_event *event,
2104  struct ordered_events *oe __maybe_unused)
2105 
2106 {
2107  perf_event__fprintf(event, stdout);
2108  return 0;
2109 }
2110 
2111 static void sig_handler(int sig __maybe_unused)
2112 {
2113  session_done = 1;
2114 }
2115 
2117 {
2118  struct perf_evlist *evlist = script->session->evlist;
2119  struct perf_evsel *evsel;
2120 
2121  evlist__for_each_entry(evlist, evsel) {
2122  if (!evsel->priv)
2123  break;
2125  evsel->priv = NULL;
2126  }
2127 }
2128 
2130 {
2131  struct perf_evsel *evsel;
2132 
2133  evlist__for_each_entry(script->session->evlist, evsel) {
2134  /*
2135  * Already setup? I.e. we may be called twice in cases like
2136  * Intel PT, one for the intel_pt// and dummy events, then
2137  * for the evsels syntheized from the auxtrace info.
2138  *
2139  * Ses perf_script__process_auxtrace_info.
2140  */
2141  if (evsel->priv != NULL)
2142  continue;
2143 
2144  evsel->priv = perf_evsel_script__new(evsel, script->session->data);
2145  if (evsel->priv == NULL)
2146  goto out_err_fclose;
2147  }
2148 
2149  return 0;
2150 
2151 out_err_fclose:
2153  return -1;
2154 }
2155 
2157 {
2158  struct perf_evsel *evsel;
2159  static struct perf_evsel_script es_stdout;
2160 
2161  if (script->per_event_dump)
2162  return perf_script__fopen_per_event_dump(script);
2163 
2164  es_stdout.fp = stdout;
2165 
2166  evlist__for_each_entry(script->session->evlist, evsel)
2167  evsel->priv = &es_stdout;
2168 
2169  return 0;
2170 }
2171 
2173 {
2174  struct perf_evsel *evsel;
2175 
2176  evlist__for_each_entry(script->session->evlist, evsel) {
2177  struct perf_evsel_script *es = evsel->priv;
2178 
2179  perf_evsel_script__fprintf(es, stdout);
2181  evsel->priv = NULL;
2182  }
2183 }
2184 
2185 static int __cmd_script(struct perf_script *script)
2186 {
2187  int ret;
2188 
2189  signal(SIGINT, sig_handler);
2190 
2191  /* override event processing functions */
2192  if (script->show_task_events) {
2193  script->tool.comm = process_comm_event;
2194  script->tool.fork = process_fork_event;
2195  script->tool.exit = process_exit_event;
2196  }
2197  if (script->show_mmap_events) {
2198  script->tool.mmap = process_mmap_event;
2199  script->tool.mmap2 = process_mmap2_event;
2200  }
2201  if (script->show_switch_events)
2203  if (script->show_namespace_events)
2205  if (script->show_lost_events)
2206  script->tool.lost = process_lost_event;
2207  if (script->show_round_events) {
2208  script->tool.ordered_events = false;
2210  }
2211 
2212  if (perf_script__setup_per_event_dump(script)) {
2213  pr_err("Couldn't create the per event dump files\n");
2214  return -1;
2215  }
2216 
2217  ret = perf_session__process_events(script->session);
2218 
2219  if (script->per_event_dump)
2221 
2222  if (debug_mode)
2223  pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
2224 
2225  return ret;
2226 }
2227 
2228 struct script_spec {
2229  struct list_head node;
2230  struct scripting_ops *ops;
2231  char spec[0];
2232 };
2233 
2234 static LIST_HEAD(script_specs);
2235 
2236 static struct script_spec *script_spec__new(const char *spec,
2237  struct scripting_ops *ops)
2238 {
2239  struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
2240 
2241  if (s != NULL) {
2242  strcpy(s->spec, spec);
2243  s->ops = ops;
2244  }
2245 
2246  return s;
2247 }
2248 
2249 static void script_spec__add(struct script_spec *s)
2250 {
2251  list_add_tail(&s->node, &script_specs);
2252 }
2253 
2254 static struct script_spec *script_spec__find(const char *spec)
2255 {
2256  struct script_spec *s;
2257 
2258  list_for_each_entry(s, &script_specs, node)
2259  if (strcasecmp(s->spec, spec) == 0)
2260  return s;
2261  return NULL;
2262 }
2263 
2264 int script_spec_register(const char *spec, struct scripting_ops *ops)
2265 {
2266  struct script_spec *s;
2267 
2268  s = script_spec__find(spec);
2269  if (s)
2270  return -1;
2271 
2272  s = script_spec__new(spec, ops);
2273  if (!s)
2274  return -1;
2275  else
2276  script_spec__add(s);
2277 
2278  return 0;
2279 }
2280 
2281 static struct scripting_ops *script_spec__lookup(const char *spec)
2282 {
2283  struct script_spec *s = script_spec__find(spec);
2284  if (!s)
2285  return NULL;
2286 
2287  return s->ops;
2288 }
2289 
2290 static void list_available_languages(void)
2291 {
2292  struct script_spec *s;
2293 
2294  fprintf(stderr, "\n");
2295  fprintf(stderr, "Scripting language extensions (used in "
2296  "perf script -s [spec:]script.[spec]):\n\n");
2297 
2298  list_for_each_entry(s, &script_specs, node)
2299  fprintf(stderr, " %-42s [%s]\n", s->spec, s->ops->name);
2300 
2301  fprintf(stderr, "\n");
2302 }
2303 
2304 static int parse_scriptname(const struct option *opt __maybe_unused,
2305  const char *str, int unset __maybe_unused)
2306 {
2307  char spec[PATH_MAX];
2308  const char *script, *ext;
2309  int len;
2310 
2311  if (strcmp(str, "lang") == 0) {
2313  exit(0);
2314  }
2315 
2316  script = strchr(str, ':');
2317  if (script) {
2318  len = script - str;
2319  if (len >= PATH_MAX) {
2320  fprintf(stderr, "invalid language specifier");
2321  return -1;
2322  }
2323  strncpy(spec, str, len);
2324  spec[len] = '\0';
2325  scripting_ops = script_spec__lookup(spec);
2326  if (!scripting_ops) {
2327  fprintf(stderr, "invalid language specifier");
2328  return -1;
2329  }
2330  script++;
2331  } else {
2332  script = str;
2333  ext = strrchr(script, '.');
2334  if (!ext) {
2335  fprintf(stderr, "invalid script extension");
2336  return -1;
2337  }
2338  scripting_ops = script_spec__lookup(++ext);
2339  if (!scripting_ops) {
2340  fprintf(stderr, "invalid script extension");
2341  return -1;
2342  }
2343  }
2344 
2345  script_name = strdup(script);
2346 
2347  return 0;
2348 }
2349 
2350 static int parse_output_fields(const struct option *opt __maybe_unused,
2351  const char *arg, int unset __maybe_unused)
2352 {
2353  char *tok, *strtok_saveptr = NULL;
2354  int i, imax = ARRAY_SIZE(all_output_options);
2355  int j;
2356  int rc = 0;
2357  char *str = strdup(arg);
2358  int type = -1;
2359  enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT;
2360 
2361  if (!str)
2362  return -ENOMEM;
2363 
2364  /* first word can state for which event type the user is specifying
2365  * the fields. If no type exists, the specified fields apply to all
2366  * event types found in the file minus the invalid fields for a type.
2367  */
2368  tok = strchr(str, ':');
2369  if (tok) {
2370  *tok = '\0';
2371  tok++;
2372  if (!strcmp(str, "hw"))
2373  type = PERF_TYPE_HARDWARE;
2374  else if (!strcmp(str, "sw"))
2375  type = PERF_TYPE_SOFTWARE;
2376  else if (!strcmp(str, "trace"))
2377  type = PERF_TYPE_TRACEPOINT;
2378  else if (!strcmp(str, "raw"))
2379  type = PERF_TYPE_RAW;
2380  else if (!strcmp(str, "break"))
2381  type = PERF_TYPE_BREAKPOINT;
2382  else if (!strcmp(str, "synth"))
2383  type = OUTPUT_TYPE_SYNTH;
2384  else {
2385  fprintf(stderr, "Invalid event type in field string.\n");
2386  rc = -EINVAL;
2387  goto out;
2388  }
2389 
2390  if (output[type].user_set)
2391  pr_warning("Overriding previous field request for %s events.\n",
2392  event_type(type));
2393 
2394  output[type].fields = 0;
2395  output[type].user_set = true;
2396  output[type].wildcard_set = false;
2397 
2398  } else {
2399  tok = str;
2400  if (strlen(str) == 0) {
2401  fprintf(stderr,
2402  "Cannot set fields to 'none' for all event types.\n");
2403  rc = -EINVAL;
2404  goto out;
2405  }
2406 
2407  /* Don't override defaults for +- */
2408  if (strchr(str, '+') || strchr(str, '-'))
2409  goto parse;
2410 
2411  if (output_set_by_user())
2412  pr_warning("Overriding previous field request for all events.\n");
2413 
2414  for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2415  output[j].fields = 0;
2416  output[j].user_set = true;
2417  output[j].wildcard_set = true;
2418  }
2419  }
2420 
2421 parse:
2422  for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
2423  if (*tok == '+') {
2424  if (change == SET)
2425  goto out_badmix;
2426  change = ADD;
2427  tok++;
2428  } else if (*tok == '-') {
2429  if (change == SET)
2430  goto out_badmix;
2431  change = REMOVE;
2432  tok++;
2433  } else {
2434  if (change != SET && change != DEFAULT)
2435  goto out_badmix;
2436  change = SET;
2437  }
2438 
2439  for (i = 0; i < imax; ++i) {
2440  if (strcmp(tok, all_output_options[i].str) == 0)
2441  break;
2442  }
2443  if (i == imax && strcmp(tok, "flags") == 0) {
2444  print_flags = change == REMOVE ? false : true;
2445  continue;
2446  }
2447  if (i == imax) {
2448  fprintf(stderr, "Invalid field requested.\n");
2449  rc = -EINVAL;
2450  goto out;
2451  }
2452 
2453  if (type == -1) {
2454  /* add user option to all events types for
2455  * which it is valid
2456  */
2457  for (j = 0; j < OUTPUT_TYPE_MAX; ++j) {
2459  pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
2460  all_output_options[i].str, event_type(j));
2461  } else {
2462  if (change == REMOVE)
2463  output[j].fields &= ~all_output_options[i].field;
2464  else
2465  output[j].fields |= all_output_options[i].field;
2466  }
2467  }
2468  } else {
2469  if (output[type].invalid_fields & all_output_options[i].field) {
2470  fprintf(stderr, "\'%s\' not valid for %s events.\n",
2471  all_output_options[i].str, event_type(type));
2472 
2473  rc = -EINVAL;
2474  goto out;
2475  }
2476  output[type].fields |= all_output_options[i].field;
2477  }
2478  }
2479 
2480  if (type >= 0) {
2481  if (output[type].fields == 0) {
2482  pr_debug("No fields requested for %s type. "
2483  "Events will not be displayed.\n", event_type(type));
2484  }
2485  }
2486  goto out;
2487 
2488 out_badmix:
2489  fprintf(stderr, "Cannot mix +-field with overridden fields\n");
2490  rc = -EINVAL;
2491 out:
2492  free(str);
2493  return rc;
2494 }
2495 
2496 #define for_each_lang(scripts_path, scripts_dir, lang_dirent) \
2497  while ((lang_dirent = readdir(scripts_dir)) != NULL) \
2498  if ((lang_dirent->d_type == DT_DIR || \
2499  (lang_dirent->d_type == DT_UNKNOWN && \
2500  is_directory(scripts_path, lang_dirent))) && \
2501  (strcmp(lang_dirent->d_name, ".")) && \
2502  (strcmp(lang_dirent->d_name, "..")))
2503 
2504 #define for_each_script(lang_path, lang_dir, script_dirent) \
2505  while ((script_dirent = readdir(lang_dir)) != NULL) \
2506  if (script_dirent->d_type != DT_DIR && \
2507  (script_dirent->d_type != DT_UNKNOWN || \
2508  !is_directory(lang_path, script_dirent)))
2509 
2510 
2511 #define RECORD_SUFFIX "-record"
2512 #define REPORT_SUFFIX "-report"
2513 
2514 struct script_desc {
2515  struct list_head node;
2516  char *name;
2517  char *half_liner;
2518  char *args;
2519 };
2520 
2521 static LIST_HEAD(script_descs);
2522 
2523 static struct script_desc *script_desc__new(const char *name)
2524 {
2525  struct script_desc *s = zalloc(sizeof(*s));
2526 
2527  if (s != NULL && name)
2528  s->name = strdup(name);
2529 
2530  return s;
2531 }
2532 
2533 static void script_desc__delete(struct script_desc *s)
2534 {
2535  zfree(&s->name);
2536  zfree(&s->half_liner);
2537  zfree(&s->args);
2538  free(s);
2539 }
2540 
2541 static void script_desc__add(struct script_desc *s)
2542 {
2543  list_add_tail(&s->node, &script_descs);
2544 }
2545 
2546 static struct script_desc *script_desc__find(const char *name)
2547 {
2548  struct script_desc *s;
2549 
2550  list_for_each_entry(s, &script_descs, node)
2551  if (strcasecmp(s->name, name) == 0)
2552  return s;
2553  return NULL;
2554 }
2555 
2556 static struct script_desc *script_desc__findnew(const char *name)
2557 {
2558  struct script_desc *s = script_desc__find(name);
2559 
2560  if (s)
2561  return s;
2562 
2563  s = script_desc__new(name);
2564  if (!s)
2565  return NULL;
2566 
2567  script_desc__add(s);
2568 
2569  return s;
2570 }
2571 
2572 static const char *ends_with(const char *str, const char *suffix)
2573 {
2574  size_t suffix_len = strlen(suffix);
2575  const char *p = str;
2576 
2577  if (strlen(str) > suffix_len) {
2578  p = str + strlen(str) - suffix_len;
2579  if (!strncmp(p, suffix, suffix_len))
2580  return p;
2581  }
2582 
2583  return NULL;
2584 }
2585 
2586 static int read_script_info(struct script_desc *desc, const char *filename)
2587 {
2588  char line[BUFSIZ], *p;
2589  FILE *fp;
2590 
2591  fp = fopen(filename, "r");
2592  if (!fp)
2593  return -1;
2594 
2595  while (fgets(line, sizeof(line), fp)) {
2596  p = ltrim(line);
2597  if (strlen(p) == 0)
2598  continue;
2599  if (*p != '#')
2600  continue;
2601  p++;
2602  if (strlen(p) && *p == '!')
2603  continue;
2604 
2605  p = ltrim(p);
2606  if (strlen(p) && p[strlen(p) - 1] == '\n')
2607  p[strlen(p) - 1] = '\0';
2608 
2609  if (!strncmp(p, "description:", strlen("description:"))) {
2610  p += strlen("description:");
2611  desc->half_liner = strdup(ltrim(p));
2612  continue;
2613  }
2614 
2615  if (!strncmp(p, "args:", strlen("args:"))) {
2616  p += strlen("args:");
2617  desc->args = strdup(ltrim(p));
2618  continue;
2619  }
2620  }
2621 
2622  fclose(fp);
2623 
2624  return 0;
2625 }
2626 
2627 static char *get_script_root(struct dirent *script_dirent, const char *suffix)
2628 {
2629  char *script_root, *str;
2630 
2631  script_root = strdup(script_dirent->d_name);
2632  if (!script_root)
2633  return NULL;
2634 
2635  str = (char *)ends_with(script_root, suffix);
2636  if (!str) {
2637  free(script_root);
2638  return NULL;
2639  }
2640 
2641  *str = '\0';
2642  return script_root;
2643 }
2644 
2645 static int list_available_scripts(const struct option *opt __maybe_unused,
2646  const char *s __maybe_unused,
2647  int unset __maybe_unused)
2648 {
2649  struct dirent *script_dirent, *lang_dirent;
2650  char scripts_path[MAXPATHLEN];
2651  DIR *scripts_dir, *lang_dir;
2652  char script_path[MAXPATHLEN];
2653  char lang_path[MAXPATHLEN];
2654  struct script_desc *desc;
2655  char first_half[BUFSIZ];
2656  char *script_root;
2657 
2658  snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
2659 
2660  scripts_dir = opendir(scripts_path);
2661  if (!scripts_dir) {
2662  fprintf(stdout,
2663  "open(%s) failed.\n"
2664  "Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",
2665  scripts_path);
2666  exit(-1);
2667  }
2668 
2669  for_each_lang(scripts_path, scripts_dir, lang_dirent) {
2670  scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
2671  lang_dirent->d_name);
2672  lang_dir = opendir(lang_path);
2673  if (!lang_dir)
2674  continue;
2675 
2676  for_each_script(lang_path, lang_dir, script_dirent) {
2677  script_root = get_script_root(script_dirent, REPORT_SUFFIX);
2678  if (script_root) {
2679  desc = script_desc__findnew(script_root);
2680  scnprintf(script_path, MAXPATHLEN, "%s/%s",
2681  lang_path, script_dirent->d_name);
2682  read_script_info(desc, script_path);
2683  free(script_root);
2684  }
2685  }
2686  }
2687 
2688  fprintf(stdout, "List of available trace scripts:\n");
2689  list_for_each_entry(desc, &script_descs, node) {
2690  sprintf(first_half, "%s %s", desc->name,
2691  desc->args ? desc->args : "");
2692  fprintf(stdout, " %-36s %s\n", first_half,
2693  desc->half_liner ? desc->half_liner : "");
2694  }
2695 
2696  exit(0);
2697 }
2698 
2699 /*
2700  * Some scripts specify the required events in their "xxx-record" file,
2701  * this function will check if the events in perf.data match those
2702  * mentioned in the "xxx-record".
2703  *
2704  * Fixme: All existing "xxx-record" are all in good formats "-e event ",
2705  * which is covered well now. And new parsing code should be added to
2706  * cover the future complexing formats like event groups etc.
2707  */
2708 static int check_ev_match(char *dir_name, char *scriptname,
2709  struct perf_session *session)
2710 {
2711  char filename[MAXPATHLEN], evname[128];
2712  char line[BUFSIZ], *p;
2713  struct perf_evsel *pos;
2714  int match, len;
2715  FILE *fp;
2716 
2717  scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname);
2718 
2719  fp = fopen(filename, "r");
2720  if (!fp)
2721  return -1;
2722 
2723  while (fgets(line, sizeof(line), fp)) {
2724  p = ltrim(line);
2725  if (*p == '#')
2726  continue;
2727 
2728  while (strlen(p)) {
2729  p = strstr(p, "-e");
2730  if (!p)
2731  break;
2732 
2733  p += 2;
2734  p = ltrim(p);
2735  len = strcspn(p, " \t");
2736  if (!len)
2737  break;
2738 
2739  snprintf(evname, len + 1, "%s", p);
2740 
2741  match = 0;
2742  evlist__for_each_entry(session->evlist, pos) {
2743  if (!strcmp(perf_evsel__name(pos), evname)) {
2744  match = 1;
2745  break;
2746  }
2747  }
2748 
2749  if (!match) {
2750  fclose(fp);
2751  return -1;
2752  }
2753  }
2754  }
2755 
2756  fclose(fp);
2757  return 0;
2758 }
2759 
2760 /*
2761  * Return -1 if none is found, otherwise the actual scripts number.
2762  *
2763  * Currently the only user of this function is the script browser, which
2764  * will list all statically runnable scripts, select one, execute it and
2765  * show the output in a perf browser.
2766  */
2767 int find_scripts(char **scripts_array, char **scripts_path_array)
2768 {
2769  struct dirent *script_dirent, *lang_dirent;
2770  char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
2771  DIR *scripts_dir, *lang_dir;
2772  struct perf_session *session;
2773  struct perf_data data = {
2774  .file = {
2775  .path = input_name,
2776  },
2777  .mode = PERF_DATA_MODE_READ,
2778  };
2779  char *temp;
2780  int i = 0;
2781 
2782  session = perf_session__new(&data, false, NULL);
2783  if (!session)
2784  return -1;
2785 
2786  snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
2787 
2788  scripts_dir = opendir(scripts_path);
2789  if (!scripts_dir) {
2790  perf_session__delete(session);
2791  return -1;
2792  }
2793 
2794  for_each_lang(scripts_path, scripts_dir, lang_dirent) {
2795  scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
2796  lang_dirent->d_name);
2797 #ifndef HAVE_LIBPERL_SUPPORT
2798  if (strstr(lang_path, "perl"))
2799  continue;
2800 #endif
2801 #ifndef HAVE_LIBPYTHON_SUPPORT
2802  if (strstr(lang_path, "python"))
2803  continue;
2804 #endif
2805 
2806  lang_dir = opendir(lang_path);
2807  if (!lang_dir)
2808  continue;
2809 
2810  for_each_script(lang_path, lang_dir, script_dirent) {
2811  /* Skip those real time scripts: xxxtop.p[yl] */
2812  if (strstr(script_dirent->d_name, "top."))
2813  continue;
2814  sprintf(scripts_path_array[i], "%s/%s", lang_path,
2815  script_dirent->d_name);
2816  temp = strchr(script_dirent->d_name, '.');
2817  snprintf(scripts_array[i],
2818  (temp - script_dirent->d_name) + 1,
2819  "%s", script_dirent->d_name);
2820 
2821  if (check_ev_match(lang_path,
2822  scripts_array[i], session))
2823  continue;
2824 
2825  i++;
2826  }
2827  closedir(lang_dir);
2828  }
2829 
2830  closedir(scripts_dir);
2831  perf_session__delete(session);
2832  return i;
2833 }
2834 
2835 static char *get_script_path(const char *script_root, const char *suffix)
2836 {
2837  struct dirent *script_dirent, *lang_dirent;
2838  char scripts_path[MAXPATHLEN];
2839  char script_path[MAXPATHLEN];
2840  DIR *scripts_dir, *lang_dir;
2841  char lang_path[MAXPATHLEN];
2842  char *__script_root;
2843 
2844  snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
2845 
2846  scripts_dir = opendir(scripts_path);
2847  if (!scripts_dir)
2848  return NULL;
2849 
2850  for_each_lang(scripts_path, scripts_dir, lang_dirent) {
2851  scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
2852  lang_dirent->d_name);
2853  lang_dir = opendir(lang_path);
2854  if (!lang_dir)
2855  continue;
2856 
2857  for_each_script(lang_path, lang_dir, script_dirent) {
2858  __script_root = get_script_root(script_dirent, suffix);
2859  if (__script_root && !strcmp(script_root, __script_root)) {
2860  free(__script_root);
2861  closedir(lang_dir);
2862  closedir(scripts_dir);
2863  scnprintf(script_path, MAXPATHLEN, "%s/%s",
2864  lang_path, script_dirent->d_name);
2865  return strdup(script_path);
2866  }
2867  free(__script_root);
2868  }
2869  closedir(lang_dir);
2870  }
2871  closedir(scripts_dir);
2872 
2873  return NULL;
2874 }
2875 
2876 static bool is_top_script(const char *script_path)
2877 {
2878  return ends_with(script_path, "top") == NULL ? false : true;
2879 }
2880 
2881 static int has_required_arg(char *script_path)
2882 {
2883  struct script_desc *desc;
2884  int n_args = 0;
2885  char *p;
2886 
2887  desc = script_desc__new(NULL);
2888 
2889  if (read_script_info(desc, script_path))
2890  goto out;
2891 
2892  if (!desc->args)
2893  goto out;
2894 
2895  for (p = desc->args; *p; p++)
2896  if (*p == '<')
2897  n_args++;
2898 out:
2899  script_desc__delete(desc);
2900 
2901  return n_args;
2902 }
2903 
2904 static int have_cmd(int argc, const char **argv)
2905 {
2906  char **__argv = malloc(sizeof(const char *) * argc);
2907 
2908  if (!__argv) {
2909  pr_err("malloc failed\n");
2910  return -1;
2911  }
2912 
2913  memcpy(__argv, argv, sizeof(const char *) * argc);
2914  argc = parse_options(argc, (const char **)__argv, record_options,
2915  NULL, PARSE_OPT_STOP_AT_NON_OPTION);
2916  free(__argv);
2917 
2918  system_wide = (argc == 0);
2919 
2920  return 0;
2921 }
2922 
2923 static void script__setup_sample_type(struct perf_script *script)
2924 {
2925  struct perf_session *session = script->session;
2926  u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
2927 
2929  if ((sample_type & PERF_SAMPLE_REGS_USER) &&
2930  (sample_type & PERF_SAMPLE_STACK_USER)) {
2932  dwarf_callchain_users = true;
2933  } else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
2935  else
2937  }
2938 }
2939 
2940 static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
2941  union perf_event *event,
2942  struct perf_session *session)
2943 {
2944  struct stat_round_event *round = &event->stat_round;
2945  struct perf_evsel *counter;
2946 
2947  evlist__for_each_entry(session->evlist, counter) {
2949  process_stat(counter, round->time);
2950  }
2951 
2952  process_stat_interval(round->time);
2953  return 0;
2954 }
2955 
2956 static int process_stat_config_event(struct perf_tool *tool __maybe_unused,
2957  union perf_event *event,
2958  struct perf_session *session __maybe_unused)
2959 {
2961  return 0;
2962 }
2963 
2964 static int set_maps(struct perf_script *script)
2965 {
2966  struct perf_evlist *evlist = script->session->evlist;
2967 
2968  if (!script->cpus || !script->threads)
2969  return 0;
2970 
2971  if (WARN_ONCE(script->allocated, "stats double allocation\n"))
2972  return -EINVAL;
2973 
2974  perf_evlist__set_maps(evlist, script->cpus, script->threads);
2975 
2976  if (perf_evlist__alloc_stats(evlist, true))
2977  return -ENOMEM;
2978 
2979  script->allocated = true;
2980  return 0;
2981 }
2982 
2983 static
2985  union perf_event *event,
2986  struct perf_session *session __maybe_unused)
2987 {
2988  struct perf_script *script = container_of(tool, struct perf_script, tool);
2989 
2990  if (script->threads) {
2991  pr_warning("Extra thread map event, ignoring.\n");
2992  return 0;
2993  }
2994 
2995  script->threads = thread_map__new_event(&event->thread_map);
2996  if (!script->threads)
2997  return -ENOMEM;
2998 
2999  return set_maps(script);
3000 }
3001 
3002 static
3003 int process_cpu_map_event(struct perf_tool *tool __maybe_unused,
3004  union perf_event *event,
3005  struct perf_session *session __maybe_unused)
3006 {
3007  struct perf_script *script = container_of(tool, struct perf_script, tool);
3008 
3009  if (script->cpus) {
3010  pr_warning("Extra cpu map event, ignoring.\n");
3011  return 0;
3012  }
3013 
3014  script->cpus = cpu_map__new_data(&event->cpu_map.data);
3015  if (!script->cpus)
3016  return -ENOMEM;
3017 
3018  return set_maps(script);
3019 }
3020 
3021 #ifdef HAVE_AUXTRACE_SUPPORT
3023  union perf_event *event,
3024  struct perf_session *session)
3025 {
3026  int ret = perf_event__process_auxtrace_info(tool, event, session);
3027 
3028  if (ret == 0) {
3029  struct perf_script *script = container_of(tool, struct perf_script, tool);
3030 
3031  ret = perf_script__setup_per_event_dump(script);
3032  }
3033 
3034  return ret;
3035 }
3036 #else
3037 #define perf_script__process_auxtrace_info 0
3038 #endif
3039 
3040 int cmd_script(int argc, const char **argv)
3041 {
3042  bool show_full_info = false;
3043  bool header = false;
3044  bool header_only = false;
3045  bool script_started = false;
3046  char *rec_script_path = NULL;
3047  char *rep_script_path = NULL;
3048  struct perf_session *session;
3049  struct itrace_synth_opts itrace_synth_opts = { .set = false, };
3050  char *script_path = NULL;
3051  const char **__argv;
3052  int i, j, err = 0;
3053  struct perf_script script = {
3054  .tool = {
3056  .mmap = perf_event__process_mmap,
3057  .mmap2 = perf_event__process_mmap2,
3058  .comm = perf_event__process_comm,
3059  .namespaces = perf_event__process_namespaces,
3060  .exit = perf_event__process_exit,
3061  .fork = perf_event__process_fork,
3062  .attr = process_attr,
3063  .event_update = perf_event__process_event_update,
3064  .tracing_data = perf_event__process_tracing_data,
3065  .feature = perf_event__process_feature,
3066  .build_id = perf_event__process_build_id,
3067  .id_index = perf_event__process_id_index,
3068  .auxtrace_info = perf_script__process_auxtrace_info,
3069  .auxtrace = perf_event__process_auxtrace,
3070  .auxtrace_error = perf_event__process_auxtrace_error,
3072  .stat_round = process_stat_round_event,
3073  .stat_config = process_stat_config_event,
3074  .thread_map = process_thread_map_event,
3075  .cpu_map = process_cpu_map_event,
3076  .ordered_events = true,
3077  .ordering_requires_timestamps = true,
3078  },
3079  };
3080  struct perf_data data = {
3082  };
3083  const struct option options[] = {
3084  OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
3085  "dump raw trace in ASCII"),
3086  OPT_INCR('v', "verbose", &verbose,
3087  "be more verbose (show symbol address, etc)"),
3088  OPT_BOOLEAN('L', "Latency", &latency_format,
3089  "show latency attributes (irqs/preemption disabled, etc)"),
3090  OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
3092  OPT_CALLBACK('s', "script", NULL, "name",
3093  "script file name (lang:script name, script name, or *)",
3095  OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
3096  "generate perf-script.xx script in specified language"),
3097  OPT_STRING('i', "input", &input_name, "file", "input file name"),
3098  OPT_BOOLEAN('d', "debug-mode", &debug_mode,
3099  "do various checks like samples ordering and lost events"),
3100  OPT_BOOLEAN(0, "header", &header, "Show data header."),
3101  OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."),
3102  OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
3103  "file", "vmlinux pathname"),
3104  OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
3105  "file", "kallsyms pathname"),
3106  OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
3107  "When printing symbols do not display call chain"),
3108  OPT_CALLBACK(0, "symfs", NULL, "directory",
3109  "Look for files with symbols relative to this directory",
3111  OPT_CALLBACK('F', "fields", NULL, "str",
3112  "comma separated output fields prepend with 'type:'. "
3113  "+field to add and -field to remove."
3114  "Valid types: hw,sw,trace,raw,synth. "
3115  "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
3116  "addr,symoff,period,iregs,uregs,brstack,brstacksym,flags,"
3117  "bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr",
3119  OPT_BOOLEAN('a', "all-cpus", &system_wide,
3120  "system-wide collection from all CPUs"),
3121  OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
3122  "only consider these symbols"),
3123  OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]",
3124  "Stop display of callgraph at these symbols"),
3125  OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
3126  OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
3127  "only display events for these comms"),
3128  OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
3129  "only consider symbols in these pids"),
3130  OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
3131  "only consider symbols in these tids"),
3132  OPT_UINTEGER(0, "max-stack", &scripting_max_stack,
3133  "Set the maximum stack depth when parsing the callchain, "
3134  "anything beyond the specified depth will be ignored. "
3135  "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
3136  OPT_BOOLEAN('I', "show-info", &show_full_info,
3137  "display extended information from perf.data file"),
3138  OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
3139  "Show the path of [kernel.kallsyms]"),
3140  OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events,
3141  "Show the fork/comm/exit events"),
3142  OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
3143  "Show the mmap events"),
3144  OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
3145  "Show context switch events (if recorded)"),
3146  OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
3147  "Show namespace events (if recorded)"),
3148  OPT_BOOLEAN('\0', "show-lost-events", &script.show_lost_events,
3149  "Show lost events (if recorded)"),
3150  OPT_BOOLEAN('\0', "show-round-events", &script.show_round_events,
3151  "Show round events (if recorded)"),
3152  OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
3153  "Dump trace output to files named by the monitored events"),
3154  OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
3155  OPT_INTEGER(0, "max-blocks", &max_blocks,
3156  "Maximum number of code blocks to dump with brstackinsn"),
3157  OPT_BOOLEAN(0, "ns", &nanosecs,
3158  "Use 9 decimal places when displaying time"),
3159  OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
3160  "Instruction Tracing options",
3162  OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
3163  "Show full source file name path for source lines"),
3164  OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
3165  "Enable symbol demangling"),
3166  OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
3167  "Enable kernel symbol demangling"),
3168  OPT_STRING(0, "time", &script.time_str, "str",
3169  "Time span of interest (start,stop)"),
3170  OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
3171  "Show inline function"),
3172  OPT_END()
3173  };
3174  const char * const script_subcommands[] = { "record", "report", NULL };
3175  const char *script_usage[] = {
3176  "perf script [<options>]",
3177  "perf script [<options>] record <script> [<record-options>] <command>",
3178  "perf script [<options>] report <script> [script-args]",
3179  "perf script [<options>] <script> [<record-options>] <command>",
3180  "perf script [<options>] <top-script> [script-args]",
3181  NULL
3182  };
3183 
3185 
3186  setup_scripting();
3187 
3188  argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
3189  PARSE_OPT_STOP_AT_NON_OPTION);
3190 
3191  data.file.path = input_name;
3192  data.force = symbol_conf.force;
3193 
3194  if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
3195  rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
3196  if (!rec_script_path)
3197  return cmd_record(argc, argv);
3198  }
3199 
3200  if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
3201  rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
3202  if (!rep_script_path) {
3203  fprintf(stderr,
3204  "Please specify a valid report script"
3205  "(see 'perf script -l' for listing)\n");
3206  return -1;
3207  }
3208  }
3209 
3210  if (itrace_synth_opts.callchain &&
3211  itrace_synth_opts.callchain_sz > scripting_max_stack)
3212  scripting_max_stack = itrace_synth_opts.callchain_sz;
3213 
3214  /* make sure PERF_EXEC_PATH is set for scripts */
3215  set_argv_exec_path(get_argv_exec_path());
3216 
3217  if (argc && !script_name && !rec_script_path && !rep_script_path) {
3218  int live_pipe[2];
3219  int rep_args;
3220  pid_t pid;
3221 
3222  rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);
3223  rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
3224 
3225  if (!rec_script_path && !rep_script_path) {
3226  usage_with_options_msg(script_usage, options,
3227  "Couldn't find script `%s'\n\n See perf"
3228  " script -l for available scripts.\n", argv[0]);
3229  }
3230 
3231  if (is_top_script(argv[0])) {
3232  rep_args = argc - 1;
3233  } else {
3234  int rec_args;
3235 
3236  rep_args = has_required_arg(rep_script_path);
3237  rec_args = (argc - 1) - rep_args;
3238  if (rec_args < 0) {
3239  usage_with_options_msg(script_usage, options,
3240  "`%s' script requires options."
3241  "\n\n See perf script -l for available "
3242  "scripts and options.\n", argv[0]);
3243  }
3244  }
3245 
3246  if (pipe(live_pipe) < 0) {
3247  perror("failed to create pipe");
3248  return -1;
3249  }
3250 
3251  pid = fork();
3252  if (pid < 0) {
3253  perror("failed to fork");
3254  return -1;
3255  }
3256 
3257  if (!pid) {
3258  j = 0;
3259 
3260  dup2(live_pipe[1], 1);
3261  close(live_pipe[0]);
3262 
3263  if (is_top_script(argv[0])) {
3264  system_wide = true;
3265  } else if (!system_wide) {
3266  if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
3267  err = -1;
3268  goto out;
3269  }
3270  }
3271 
3272  __argv = malloc((argc + 6) * sizeof(const char *));
3273  if (!__argv) {
3274  pr_err("malloc failed\n");
3275  err = -ENOMEM;
3276  goto out;
3277  }
3278 
3279  __argv[j++] = "/bin/sh";
3280  __argv[j++] = rec_script_path;
3281  if (system_wide)
3282  __argv[j++] = "-a";
3283  __argv[j++] = "-q";
3284  __argv[j++] = "-o";
3285  __argv[j++] = "-";
3286  for (i = rep_args + 1; i < argc; i++)
3287  __argv[j++] = argv[i];
3288  __argv[j++] = NULL;
3289 
3290  execvp("/bin/sh", (char **)__argv);
3291  free(__argv);
3292  exit(-1);
3293  }
3294 
3295  dup2(live_pipe[0], 0);
3296  close(live_pipe[1]);
3297 
3298  __argv = malloc((argc + 4) * sizeof(const char *));
3299  if (!__argv) {
3300  pr_err("malloc failed\n");
3301  err = -ENOMEM;
3302  goto out;
3303  }
3304 
3305  j = 0;
3306  __argv[j++] = "/bin/sh";
3307  __argv[j++] = rep_script_path;
3308  for (i = 1; i < rep_args + 1; i++)
3309  __argv[j++] = argv[i];
3310  __argv[j++] = "-i";
3311  __argv[j++] = "-";
3312  __argv[j++] = NULL;
3313 
3314  execvp("/bin/sh", (char **)__argv);
3315  free(__argv);
3316  exit(-1);
3317  }
3318 
3319  if (rec_script_path)
3320  script_path = rec_script_path;
3321  if (rep_script_path)
3322  script_path = rep_script_path;
3323 
3324  if (script_path) {
3325  j = 0;
3326 
3327  if (!rec_script_path)
3328  system_wide = false;
3329  else if (!system_wide) {
3330  if (have_cmd(argc - 1, &argv[1]) != 0) {
3331  err = -1;
3332  goto out;
3333  }
3334  }
3335 
3336  __argv = malloc((argc + 2) * sizeof(const char *));
3337  if (!__argv) {
3338  pr_err("malloc failed\n");
3339  err = -ENOMEM;
3340  goto out;
3341  }
3342 
3343  __argv[j++] = "/bin/sh";
3344  __argv[j++] = script_path;
3345  if (system_wide)
3346  __argv[j++] = "-a";
3347  for (i = 2; i < argc; i++)
3348  __argv[j++] = argv[i];
3349  __argv[j++] = NULL;
3350 
3351  execvp("/bin/sh", (char **)__argv);
3352  free(__argv);
3353  exit(-1);
3354  }
3355 
3356  if (!script_name)
3357  setup_pager();
3358 
3359  session = perf_session__new(&data, false, &script.tool);
3360  if (session == NULL)
3361  return -1;
3362 
3363  if (header || header_only) {
3365  perf_session__fprintf_info(session, stdout, show_full_info);
3366  if (header_only)
3367  goto out_delete;
3368  }
3369  if (show_full_info)
3371 
3372  if (symbol__init(&session->header.env) < 0)
3373  goto out_delete;
3374 
3375  script.session = session;
3376  script__setup_sample_type(&script);
3377 
3378  if (output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT)
3379  itrace_synth_opts.thread_stack = true;
3380 
3381  session->itrace_synth_opts = &itrace_synth_opts;
3382 
3383  if (cpu_list) {
3384  err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
3385  if (err < 0)
3386  goto out_delete;
3387  itrace_synth_opts.cpu_bitmap = cpu_bitmap;
3388  }
3389 
3390  if (!no_callchain)
3391  symbol_conf.use_callchain = true;
3392  else
3393  symbol_conf.use_callchain = false;
3394 
3395  if (session->tevent.pevent &&
3396  pevent_set_function_resolver(session->tevent.pevent,
3398  &session->machines.host) < 0) {
3399  pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
3400  err = -1;
3401  goto out_delete;
3402  }
3403 
3404  if (generate_script_lang) {
3405  struct stat perf_stat;
3406  int input;
3407 
3408  if (output_set_by_user()) {
3409  fprintf(stderr,
3410  "custom fields not supported for generated scripts");
3411  err = -EINVAL;
3412  goto out_delete;
3413  }
3414 
3415  input = open(data.file.path, O_RDONLY); /* input_name */
3416  if (input < 0) {
3417  err = -errno;
3418  perror("failed to open file");
3419  goto out_delete;
3420  }
3421 
3422  err = fstat(input, &perf_stat);
3423  if (err < 0) {
3424  perror("failed to stat file");
3425  goto out_delete;
3426  }
3427 
3428  if (!perf_stat.st_size) {
3429  fprintf(stderr, "zero-sized file, nothing to do!\n");
3430  goto out_delete;
3431  }
3432 
3433  scripting_ops = script_spec__lookup(generate_script_lang);
3434  if (!scripting_ops) {
3435  fprintf(stderr, "invalid language specifier");
3436  err = -ENOENT;
3437  goto out_delete;
3438  }
3439 
3440  err = scripting_ops->generate_script(session->tevent.pevent,
3441  "perf-script");
3442  goto out_delete;
3443  }
3444 
3445  if (script_name) {
3446  err = scripting_ops->start_script(script_name, argc, argv);
3447  if (err)
3448  goto out_delete;
3449  pr_debug("perf script started with script %s\n\n", script_name);
3450  script_started = true;
3451  }
3452 
3453 
3454  err = perf_session__check_output_opt(session);
3455  if (err < 0)
3456  goto out_delete;
3457 
3459  &script.range_size);
3460  if (!script.ptime_range) {
3461  err = -ENOMEM;
3462  goto out_delete;
3463  }
3464 
3465  /* needs to be parsed after looking up reference time */
3466  if (perf_time__parse_str(script.ptime_range, script.time_str) != 0) {
3467  if (session->evlist->first_sample_time == 0 &&
3468  session->evlist->last_sample_time == 0) {
3469  pr_err("HINT: no first/last sample time found in perf data.\n"
3470  "Please use latest perf binary to execute 'perf record'\n"
3471  "(if '--buildid-all' is enabled, please set '--timestamp-boundary').\n");
3472  err = -EINVAL;
3473  goto out_delete;
3474  }
3475 
3477  script.ptime_range, script.range_size,
3478  script.time_str,
3479  session->evlist->first_sample_time,
3480  session->evlist->last_sample_time);
3481 
3482  if (script.range_num < 0) {
3483  pr_err("Invalid time string\n");
3484  err = -EINVAL;
3485  goto out_delete;
3486  }
3487  } else {
3488  script.range_num = 1;
3489  }
3490 
3491  err = __cmd_script(&script);
3492 
3493  flush_scripting();
3494 
3495 out_delete:
3496  zfree(&script.ptime_range);
3497 
3498  perf_evlist__free_stats(session->evlist);
3499  perf_session__delete(session);
3500 
3501  if (script_started)
3503 out:
3504  return err;
3505 }
bool show_round_events
static LIST_HEAD(script_specs)
struct list_head node
u8 is_64_bit
Definition: dso.h:166
void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, struct thread_map *threads)
Definition: evlist.c:1115
static int flush_scripting(void)
u8 adjust_symbols
Definition: dso.h:159
void thread__resolve(struct thread *thread, struct addr_location *al, struct perf_sample *sample)
Definition: event.c:1687
static int has_required_arg(char *script_path)
void perf_stat__print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu, struct perf_stat_output_ctx *out, struct rblist *metric_events, struct runtime_stat *st)
Definition: stat-shadow.c:753
int perf_event__process_attr(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_evlist **pevlist)
Definition: header.c:3721
Definition: insn.h:36
event_op mmap2
Definition: tool.h:47
static int process_finished_round_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct ordered_events *oe __maybe_unused)
const char * comm_list_str
Definition: symbol.h:131
static unsigned int attr_type(unsigned int type)
static int perf_sample__fprintf_brstack(struct perf_sample *sample, struct thread *thread, struct perf_event_attr *attr, FILE *fp)
static int cleanup_scripting(void)
int color_fprintf(FILE *fp, const char *color, const char *fmt,...)
Definition: color.c:123
u64(* map_ip)(struct map *, u64)
Definition: map.h:41
event_op lost
Definition: tool.h:47
struct list_head node
Definition: mem2node.c:7
enum perf_data_mode mode
Definition: data.h:22
static int read_script_info(struct script_desc *desc, const char *filename)
static void script_desc__add(struct script_desc *s)
struct perf_evlist * evlist
Definition: session.h:25
static struct script_spec * script_spec__new(const char *spec, struct scripting_ops *ops)
bool is_bts_event(struct perf_event_attr *attr)
Definition: event.c:1666
u64 weight
Definition: event.h:199
static int perf_evlist__max_name_len(struct perf_evlist *evlist)
struct perf_data * data
Definition: session.h:36
static int perf_evsel__check_stype(struct perf_evsel *evsel, u64 sample_type, const char *sample_msg, enum perf_output_field field)
static int perf_sample__fprintf_brstacksym(struct perf_sample *sample, struct thread *thread, struct perf_event_attr *attr, FILE *fp)
void event_format__fprintf(struct event_format *event, int cpu, void *data, int size, FILE *fp)
static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp)
enum show_feature_header show_feat_hdr
Definition: tool.h:80
int machine__resolve(struct machine *machine, struct addr_location *al, struct perf_sample *sample)
Definition: event.c:1601
static struct perf_evsel_script * evsel_script(struct perf_evsel *evsel)
const char * vmlinux_name
Definition: symbol.h:123
u32 tid
Definition: event.h:15
static void set_print_ip_opts(struct perf_event_attr *attr)
#define perf_sample__bad_synth_size(s, d)
Definition: event.h:379
static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)
void perf_evlist__free_stats(struct perf_evlist *evlist)
Definition: stat.c:186
static u64 map__map_ip(struct map *map, u64 ip)
Definition: map.h:86
bool cumulate_callchain
Definition: symbol.h:93
static int process_cpu_map_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session __maybe_unused)
u64 data_src
Definition: event.h:203
static int perf_evsel_script__fprintf(struct perf_evsel_script *es, FILE *fp)
char insn[MAX_INSN]
Definition: event.h:209
u32 tid
Definition: event.h:53
struct dso::@70 data
static int perf_sample__fprintf_addr(struct perf_sample *sample, struct thread *thread, struct perf_event_attr *attr, FILE *fp)
static bool output_set_by_user(void)
static int parse_output_fields(const struct option *opt __maybe_unused, const char *arg, int unset __maybe_unused)
int cmd_record(int argc, const char **argv)
struct perf_evsel * evsel
static int process_attr(struct perf_tool *tool, union perf_event *event, struct perf_evlist **pevlist)
struct machine host
Definition: machine.h:136
int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1385
u32 pid
Definition: event.h:52
static int output_type(unsigned int type)
const char * filename
Definition: hists_common.c:26
static int perf_evsel__do_check_stype(struct perf_evsel *evsel, u64 sample_type, const char *sample_msg, enum perf_output_field field, bool allow_user_set)
u32 tid
Definition: event.h:39
u64 addr
Definition: event.h:195
struct thread * thread
Definition: dump-insn.h:13
__thread struct callchain_cursor callchain_cursor
Definition: callchain.c:53
static void script_new_line(void *ctx)
#define EVSEL__PRINT_SYMOFFSET
Definition: evsel.h:425
u16 insn_len
Definition: event.h:206
static bool perf_evsel__is_bpf_output(struct perf_evsel *evsel)
Definition: evsel.h:403
static void * perf_sample__synth_ptr(struct perf_sample *sample)
Definition: event.h:367
static char const * script_name
unsigned int callchain_sz
Definition: auxtrace.h:96
dictionary data
Definition: stat-cpi.py:4
static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
void perf_set_singlethreaded(void)
Definition: util.c:30
struct ip_callchain * callchain
Definition: event.h:211
u64 last_sample_time
Definition: evlist.h:53
const char * time_str
struct map * thread__find_map(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al)
Definition: event.c:1511
int int err
Definition: 5sec.c:44
const char * bt_stop_list_str
Definition: symbol.h:131
int perf_event__process_feature(struct perf_tool *tool, union perf_event *event, struct perf_session *session __maybe_unused)
Definition: header.c:3446
u64 nr
Definition: event.h:157
static bool print_flags
struct perf_time_interval * perf_time__range_alloc(const char *ostr, int *size)
Definition: time-utils.c:328
static void sig_handler(int sig __maybe_unused)
int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al, int left_alignment, unsigned int print_opts, struct callchain_cursor *cursor, FILE *fp)
bool system_wide
Definition: evsel.h:124
#define MAXBB
bool show_kernel_path
Definition: symbol.h:93
bool show_switch_events
static void perf_script__fclose_per_event_dump(struct perf_script *script)
struct itrace_synth_opts * itrace_synth_opts
Definition: session.h:27
static int input(yyscan_t yyscanner)
struct perf_data_file file
Definition: data.h:18
const char * tid_list_str
Definition: symbol.h:131
static void process_event(struct perf_script *script, struct perf_sample *sample, struct perf_evsel *evsel, struct addr_location *al, struct machine *machine)
int cpu
Definition: dump-insn.h:16
static struct scripting_ops * scripting_ops
enum perf_call_graph_mode record_mode
Definition: callchain.h:96
struct perf_env env
Definition: header.h:82
static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, struct thread *thread, struct perf_event_attr *attr, struct machine *machine, FILE *fp)
u64 from
Definition: event.h:151
struct cpu_map * cpu_map__new_data(struct cpu_map_data *data)
Definition: cpumap.c:234
static void list_available_languages(void)
struct namespaces_event namespaces
Definition: event.h:628
static int perf_session__check_output_opt(struct perf_session *session)
int perf_event__process_comm(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1273
struct thread_stack * ts
Definition: thread.h:39
u64 end
Definition: symbol.h:58
print_metric_t print_metric
Definition: stat.h:146
int perf_event__process_exit(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1416
u64 cycles
Definition: event.h:145
static const char * perf_reg_name(int id)
Definition: perf_regs.h:18
static int max_blocks
struct output_option all_output_options[]
static int process_exit_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine)
u64 mask
Definition: event.h:104
struct cpu_map * cpus
Definition: evsel.h:112
int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_evlist **pevlist)
Definition: header.c:3759
Definition: cpumap.h:12
static int process_mmap_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine)
int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz)
Definition: time-utils.c:399
int perf_event__process_fork(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1408
struct stat_config_event stat_config
Definition: event.h:649
static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp)
u8 cpumode
Definition: dump-insn.h:14
static int process_lost_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine)
struct runtime_stat rt_stat
Definition: stat-shadow.c:21
const char * unit
Definition: evsel.h:104
static char * get_script_path(const char *script_root, const char *suffix)
u64 phys_addr
Definition: event.h:204
bool force
Definition: symbol.h:93
static int sample__fprintf_bpf_output(enum binary_printer_ops op, unsigned int val, void *extra, FILE *fp)
int perf_event__process_build_id(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: header.c:3922
bool srcline_full_filename
Definition: srcline.c:17
#define COMM(he)
char * ltrim(char *s)
Definition: string.c:330
static int process_stat_config_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session __maybe_unused)
__weak const char * dump_insn(struct perf_insn *x __maybe_unused, u64 ip __maybe_unused, u8 *inbuf __maybe_unused, int inlen __maybe_unused, int *lenp)
Definition: dump-insn.c:8
bool perf_session__has_traces(struct perf_session *session, const char *msg)
Definition: session.c:1963
u64 ip
Definition: event.h:192
static const char * ends_with(const char *str, const char *suffix)
x86 movsq based memset() in arch/x86/lib/memset_64.S") MEMSET_FN(memset_erms
#define pr_err(fmt,...)
Definition: json.h:21
int cmd_script(int argc, const char **argv)
bool perf_time__ranges_skip_sample(struct perf_time_interval *ptime_buf, int num, u64 timestamp)
Definition: time-utils.c:371
static struct script_desc * script_desc__findnew(const char *name)
int perf_event__process_auxtrace_error(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: auxtrace.c:1182
void perf_session__delete(struct perf_session *session)
Definition: session.c:187
static void perf_evsel_script__delete(struct perf_evsel_script *es)
struct thread * thread
static bool debug_mode
#define session_done()
Definition: session.h:117
int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, FILE *fp)
Definition: map.c:425
static int __cmd_script(struct perf_script *script)
struct perf_sample * sample
u64 start
Definition: map.h:28
struct branch_entry entries[0]
Definition: event.h:158
perf_output_field
void setup_python_scripting(void)
u64 id
Definition: event.h:196
struct trace_event tevent
Definition: session.h:29
#define EVSEL__PRINT_SRCLINE
Definition: evsel.h:427
void * malloc(YYSIZE_T)
static int have_cmd(int argc, const char **argv)
static int perf_sample__fprintf_brstackoff(struct perf_sample *sample, struct thread *thread, struct perf_event_attr *attr, FILE *fp)
static int grab_bb(u8 *buffer, u64 start, u64 end, struct machine *machine, struct thread *thread, bool *is64bit, u8 *cpumode, bool last)
u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist)
Definition: evlist.c:1260
size_t symbol__fprintf_symname_offs(const struct symbol *sym, const struct addr_location *al, FILE *fp)
static u64 last_timestamp
u32 tid
Definition: event.h:24
static void perf_script__exit_per_event_dump_stats(struct perf_script *script)
unsigned int scripting_max_stack
void addr_location__put(struct addr_location *al)
Definition: event.c:1661
#define REPORT_SUFFIX
struct map * map
Definition: symbol.h:210
static struct script_desc * script_desc__new(const char *name)
Definition: thread.h:18
int symbol__config_symfs(const struct option *opt __maybe_unused, const char *dir, int unset __maybe_unused)
Definition: symbol.c:2205
const char * event_type(int type)
Definition: parse-events.c:275
const char * name
static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en, struct perf_insn *x, u8 *inbuf, int len, int insn, FILE *fp)
bool dwarf_callchain_users
Definition: callchain.c:47
const char * thread__comm_str(const struct thread *thread)
Definition: thread.c:258
#define for_each_script(lang_path, lang_dir, script_dirent)
static int perf_sample__fprintf_start(struct perf_sample *sample, struct thread *thread, struct perf_evsel *evsel, u32 type, FILE *fp)
static bool system_wide
#define pr_debug(fmt,...)
Definition: json.h:27
void setup_perl_scripting(void)
static char * get_script_root(struct dirent *script_dirent, const char *suffix)
Definition: tool.h:44
const char * fmt
Definition: dso.c:193
static struct perf_evsel_script * perf_evsel_script__new(struct perf_evsel *evsel, struct perf_data *data)
static struct perf_session * session
Definition: builtin-lock.c:34
u64 start
Definition: symbol.h:57
const char * name
Definition: trace-event.h:75
#define evlist__for_each_entry(evlist, evsel)
Definition: evlist.h:247
event_oe finished_round
Definition: tool.h:63
bool user_set
u64 invalid_fields
struct cpu_map_data data
Definition: event.h:441
static unsigned int nthreads
Definition: futex-hash.c:31
static int perf_sample__fprintf_callindent(struct perf_sample *sample, struct perf_evsel *evsel, struct thread *thread, struct addr_location *al, FILE *fp)
struct dso * dso
Definition: map.h:45
int(* flush_script)(void)
Definition: trace-event.h:77
#define RECORD_SUFFIX
unsigned int print_ip_opts
#define SET(__n, __v)
static void perf_sample__fprint_metric(struct perf_script *script, struct thread *thread, struct perf_evsel *evsel, struct perf_sample *sample, FILE *fp)
struct regs_dump user_regs
Definition: event.h:213
event_op exit
Definition: tool.h:47
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS)
static struct perf_tool tool
Definition: builtin-diff.c:362
static bool machine__kernel_ip(struct machine *machine, u64 ip)
Definition: machine.h:95
struct event_format * tp_format
Definition: evsel.h:105
static int perf_sample__fprintf_synth(struct perf_sample *sample, struct perf_evsel *evsel, FILE *fp)
struct cpu_map_event cpu_map
Definition: event.h:648
int itrace_parse_synth_opts(const struct option *opt, const char *str, int unset)
Definition: auxtrace.c:981
size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
u64 period
Definition: event.h:198
static char const * generate_script_lang
u64 predicted
Definition: event.h:142
#define PATH_MAX
Definition: jevents.c:1042
u32 pid
Definition: event.h:193
void(* process_stat)(struct perf_stat_config *config, struct perf_evsel *evsel, u64 tstamp)
Definition: trace-event.h:83
u32 tid
Definition: event.h:193
bool show_namespace_events
struct thread_map * thread_map__new_event(struct thread_map_event *event)
Definition: thread_map.c:446
static int perf_sample__fprintf_iregs(struct perf_sample *sample, struct perf_event_attr *attr, FILE *fp)
Definition: jevents.c:169
char name[0]
Definition: symbol.h:66
const char * str
const char * input_name
Definition: perf.c:40
static int perf_script__fopen_per_event_dump(struct perf_script *script)
union perf_mem_data_src data_src
Definition: symbol.h:203
static int perf_sample__fprintf_synth_pwre(struct perf_sample *sample, FILE *fp)
static int process_fork_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine)
static void script_spec__add(struct script_spec *s)
struct perf_evsel * perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
Definition: evlist.c:589
bool ordered_events
Definition: tool.h:76
#define DSO(he)
static int perf_sample__fprintf_bts(struct perf_sample *sample, struct perf_evsel *evsel, struct thread *thread, struct addr_location *al, struct machine *machine, FILE *fp)
struct symbol * sym
Definition: symbol.h:211
static const char * cpu_list
u64 abi
Definition: event.h:103
struct regs_dump intr_regs
Definition: event.h:214
const char * pid_list_str
Definition: symbol.h:131
#define CPU(he)
struct thread_map * threads
#define event
s64 perf_event__process_auxtrace(struct perf_tool *tool, union perf_event *event, struct perf_session *session)
Definition: auxtrace.c:929
struct perf_counts * counts
Definition: evsel.h:98
int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: auxtrace.c:905
struct fork_event fork
Definition: event.h:629
struct branch_stack * branch_stack
Definition: event.h:212
static int process_stat_round_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
u64 in_tx
Definition: event.h:143
u32 raw_size
Definition: event.h:202
u32 cpu
Definition: event.h:201
static int process_namespaces_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine)
static struct script_desc * script_desc__find(const char *name)
static void script__setup_sample_type(struct perf_script *script)
static int process_comm_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: data.h:17
size_t thread_stack__depth(struct thread *thread)
Definition: thread-stack.c:621
#define for_each_lang(scripts_path, scripts_dir, lang_dirent)
x86 movsq based memcpy() in arch/x86/lib/memcpy_64.S") MEMCPY_FN(memcpy_erms
struct thread * thread
Definition: symbol.h:209
struct thread_map * threads
Definition: evsel.h:114
bool inline_name
Definition: symbol.h:93
int perf_event__process_tracing_data(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: header.c:3854
int map[]
Definition: cpumap.h:15
struct symbol * map__find_symbol(struct map *map, u64 addr)
Definition: map.c:351
double scale
Definition: evsel.h:103
int perf_event__process_switch(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused, struct machine *machine)
Definition: event.c:1321
int perf_script__meminfo_scnprintf(char *out, size_t sz, struct mem_info *mem_info)
Definition: mem-events.c:297
#define NSEC_PER_SEC
Definition: jvmti_agent.c:101
#define zfree(ptr)
Definition: util.h:25
u32 pid
Definition: event.h:24
bool wildcard_set
const char * perf_evsel__name(struct perf_evsel *evsel)
Definition: evsel.c:577
int perf_stat_process_counter(struct perf_stat_config *config, struct perf_evsel *counter)
Definition: stat.c:327
u64 fields
void * raw_data
Definition: event.h:210
static int thread_map__nr(struct thread_map *threads)
Definition: thread_map.h:41
void perf_stat__init_shadow_stats(void)
Definition: stat-shadow.c:141
#define has(m)
#define PRINT_FIELD(x)
struct perf_event_header header
Definition: event.h:624
Definition: event.h:150
u32 pid
Definition: hists_common.c:15
#define PERF_TYPE_SYNTH
Definition: event.h:261
static int perf_script__setup_per_event_dump(struct perf_script *script)
static int process_thread_map_event(struct perf_tool *tool, union perf_event *event, struct perf_session *session __maybe_unused)
void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 count, int cpu, struct runtime_stat *st)
Definition: stat-shadow.c:208
const char * desc
Definition: clang.c:10
static int set_maps(struct perf_script *script)
static int perf_sample__fprintf_uregs(struct perf_sample *sample, struct perf_event_attr *attr, FILE *fp)
int(* generate_script)(struct pevent *pevent, const char *outfile)
Definition: trace-event.h:86
static struct @9 output[OUTPUT_TYPE_MAX]
struct option * record_options
u64 start
Definition: hists_common.c:25
#define MAXINSN
Definition: dump-insn.h:5
struct perf_session * perf_session__new(struct perf_data *data, bool repipe, struct perf_tool *tool)
Definition: session.c:116
int script_spec_register(const char *spec, struct scripting_ops *ops)
int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1393
const char * kallsyms_name
Definition: symbol.h:123
#define for_each_group_member(_evsel, _leader)
Definition: evsel.h:452
size_t map__fprintf_dsoname(struct map *map, FILE *fp)
Definition: map.c:404
void thread__put(struct thread *thread)
Definition: thread.c:119
bool perf_header__has_feat(const struct perf_header *header, int feat)
Definition: header.c:86
int perf_time__percent_parse_str(struct perf_time_interval *ptime_buf, int num, const char *ostr, u64 start, u64 end)
Definition: time-utils.c:295
bool use_callchain
Definition: symbol.h:93
unsigned long * cpu_bitmap
Definition: auxtrace.h:101
int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
Definition: stat.c:170
struct cpu_map * cpus
int perf_session__process_events(struct perf_session *session)
Definition: session.c:1945
int status
Definition: dso.h:183
struct perf_tool tool
bool demangle
Definition: symbol.h:93
static struct @10 sample_flags[]
struct perf_evsel * leader
Definition: evsel.h:136
int perf_event__process_stat_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: stat.c:377
event_op namespaces
Definition: tool.h:47
u32 flags
Definition: event.h:205
static void script_desc__delete(struct script_desc *s)
static int list_available_scripts(const struct option *opt __maybe_unused, const char *s __maybe_unused, int unset __maybe_unused)
static void script_print_metric(void *ctx, const char *color, const char *fmt, const char *unit, double val)
static int process_mmap2_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine)
u64 time
Definition: event.h:194
u32 flags
#define PID(he)
static unsigned int ncpus
Definition: futex-wake.c:45
static void __process_stat(struct perf_evsel *counter, u64 tstamp)
void perf_stat__reset_shadow_stats(void)
Definition: stat-shadow.c:181
struct symbol * thread__find_symbol(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al)
Definition: event.c:1588
u64 perf_evlist__combined_branch_type(struct perf_evlist *evlist)
Definition: evlist.c:1266
struct perf_header header
Definition: session.h:23
static void setup_scripting(void)
static double percent(int st, int tot)
Definition: builtin-c2c.c:899
static int data_src__fprintf(u64 data_src, FILE *fp)
event_op comm
Definition: tool.h:47
struct perf_evsel * perf_session__find_first_evtype(struct perf_session *session, unsigned int type)
Definition: session.c:2039
u16 misc
Definition: event.h:208
#define SYM(he)
bool dump_trace
Definition: debug.c:27
size_t perf_event__fprintf(union perf_event *event, FILE *fp)
Definition: event.c:1461
#define le32_to_cpu
u32 pid
Definition: event.h:15
int symbol__init(struct perf_env *env)
Definition: symbol.c:2112
static unsigned int nsecs
Definition: futex-hash.c:32
bool is64bit
Definition: dump-insn.h:15
int(* start_script)(const char *script, int argc, const char **argv)
Definition: trace-event.h:76
void * priv
Definition: evsel.h:108
struct comm_event comm
Definition: event.h:627
static int perf_sample__fprintf_synth_mwait(struct perf_sample *sample, FILE *fp)
static int parse_scriptname(const struct option *opt __maybe_unused, const char *str, int unset __maybe_unused)
#define EVSEL__PRINT_IP
Definition: evsel.h:422
void free(void *)
int perf_event__process_id_index(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: session.c:2136
static int perf_sample__fprintf_synth_pwrx(struct perf_sample *sample, FILE *fp)
struct mmap2_event mmap2
Definition: event.h:626
const char * sym_list_str
Definition: symbol.h:131
struct pevent * pevent
Definition: trace-event.h:16
static int ip__fprintf_sym(uint64_t addr, struct thread *thread, u8 cpumode, int cpu, struct symbol **lastsym, struct perf_event_attr *attr, FILE *fp)
int nr_members
Definition: evsel.h:133
#define EVSEL__PRINT_SYM
Definition: evsel.h:423
static pid_t thread_map__pid(struct thread_map *map, int thread)
Definition: thread_map.h:46
enum perf_output_field field
struct scripting_ops * ops
int(* stop_script)(void)
Definition: trace-event.h:78
static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine)
#define isprint(x)
Definition: sane_ctype.h:39
#define MAX_NR_CPUS
Definition: perf.h:27
bool demangle_kernel
Definition: symbol.h:93
struct thread_map_event thread_map
Definition: event.h:647
static int perf_evsel__nr_cpus(struct perf_evsel *evsel)
Definition: evsel.h:180
static struct perf_counts_values * perf_counts(struct perf_counts *counts, int cpu, int thread)
Definition: counts.h:27
#define EVSEL__PRINT_DSO
Definition: evsel.h:424
Definition: attr.py:1
static bool nanosecs
int verbose
Definition: jevents.c:53
static struct script_spec * script_spec__find(const char *spec)
Definition: symbol.h:55
int find_scripts(char **scripts_array, char **scripts_path_array)
int thread__resolve_callchain(struct thread *thread, struct callchain_cursor *cursor, struct perf_evsel *evsel, struct perf_sample *sample, struct symbol **parent, struct addr_location *root_al, int max_stack)
Definition: machine.c:2308
ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, u64 offset, u8 *data, ssize_t size)
Definition: dso.c:986
u64 first_sample_time
Definition: evlist.h:52
static struct perf_evsel * perf_evlist__last(struct perf_evlist *evlist)
Definition: evlist.h:220
#define PERF_IP_FLAG_CHARS
Definition: event.h:175
static bool is_top_script(const char *script_path)
static bool latency_format
bool sample_addr_correlates_sym(struct perf_event_attr *attr)
Definition: event.c:1673
struct perf_stat_evsel * stats
Definition: evsel.h:107
u64 * regs
Definition: event.h:105
int(* init)(struct perf_evsel *evsel)
Definition: evsel.c:61
static void process_stat_interval(u64 tstamp)
static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp)
char * machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, char **modp)
Definition: machine.c:2501
static void process_stat(struct perf_evsel *counter, u64 tstamp)
#define pr_warning(fmt,...)
Definition: debug.h:25
int perf_session__cpu_bitmap(struct perf_session *session, const char *cpu_list, unsigned long *cpu_bitmap)
Definition: session.c:2051
event_op fork
Definition: tool.h:47
static struct perf_stat_config stat_config
void perf_session__fprintf_info(struct perf_session *session, FILE *fp, bool full)
Definition: session.c:2096
static bool evsel__has_callchain(const struct perf_evsel *evsel)
Definition: evsel.h:462
static int perf_sample__fprintf_insn(struct perf_sample *sample, struct perf_event_attr *attr, struct thread *thread, struct machine *machine, FILE *fp)
bool force
Definition: data.h:20
struct perf_time_interval * ptime_range
event_op mmap
Definition: tool.h:47
int perf_event__process_namespaces(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1281
event_op context_switch
Definition: tool.h:47
#define le64_to_cpu
int map__load(struct map *map)
Definition: map.c:307
static int perf_sample__fprintf_synth_exstop(struct perf_sample *sample, FILE *fp)
struct mmap_event mmap
Definition: event.h:625
void(* process_stat_interval)(u64 tstamp)
Definition: trace-event.h:85
static int perf_evsel__check_attr(struct perf_evsel *evsel, struct perf_session *session)
void(* process_event)(union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct addr_location *al)
Definition: trace-event.h:79
u8 cpumode
Definition: event.h:207
static int process_switch_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine)
static int check_ev_match(char *dir_name, char *scriptname, struct perf_session *session)
static struct scripting_ops * script_spec__lookup(const char *spec)
u32 pid
Definition: event.h:39
const char * path
Definition: data.h:13
struct machines machines
Definition: session.h:24
u64 to
Definition: event.h:152
struct perf_session * session
struct thread * machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid)
Definition: machine.c:492
int perf_time__parse_str(struct perf_time_interval *ptime, const char *ostr)
Definition: time-utils.c:91
struct perf_event_attr attr
Definition: evsel.h:93
#define ADD(__n, __v)
static char mispred_str(struct branch_entry *br)
u64 abort
Definition: event.h:144
struct branch_flags flags
Definition: event.h:153
void perf_event__read_stat_config(struct perf_stat_config *config, struct stat_config_event *event)
Definition: event.c:1210
u64 mispred
Definition: event.h:141
static int perf_sample__fprintf_bpf_output(struct perf_sample *sample, FILE *fp)
event_sample sample
Definition: tool.h:45
#define perf_script__process_auxtrace_info
static bool no_callchain
void static void * zalloc(size_t size)
Definition: util.h:20
static u64 nr_unordered
static const char * output_field2str(enum perf_output_field field)