1 #include "builtin.h" 2 3 #include "perf.h" 4 #include "util/cache.h" 5 #include "util/debug.h" 6 #include <subcmd/exec-cmd.h> 7 #include "util/header.h" 8 #include <subcmd/parse-options.h> 9 #include "util/perf_regs.h" 10 #include "util/session.h" 11 #include "util/tool.h" 12 #include "util/symbol.h" 13 #include "util/thread.h" 14 #include "util/trace-event.h" 15 #include "util/util.h" 16 #include "util/evlist.h" 17 #include "util/evsel.h" 18 #include "util/sort.h" 19 #include "util/data.h" 20 #include "util/auxtrace.h" 21 #include "util/cpumap.h" 22 #include "util/thread_map.h" 23 #include "util/stat.h" 24 #include "util/thread-stack.h" 25 #include <linux/bitmap.h> 26 #include <linux/stringify.h> 27 #include <linux/time64.h> 28 #include "asm/bug.h" 29 #include "util/mem-events.h" 30 31 static char const *script_name; 32 static char const *generate_script_lang; 33 static bool debug_mode; 34 static u64 last_timestamp; 35 static u64 nr_unordered; 36 static bool no_callchain; 37 static bool latency_format; 38 static bool system_wide; 39 static bool print_flags; 40 static bool nanosecs; 41 static const char *cpu_list; 42 static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 43 static struct perf_stat_config stat_config; 44 45 unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH; 46 47 enum perf_output_field { 48 PERF_OUTPUT_COMM = 1U << 0, 49 PERF_OUTPUT_TID = 1U << 1, 50 PERF_OUTPUT_PID = 1U << 2, 51 PERF_OUTPUT_TIME = 1U << 3, 52 PERF_OUTPUT_CPU = 1U << 4, 53 PERF_OUTPUT_EVNAME = 1U << 5, 54 PERF_OUTPUT_TRACE = 1U << 6, 55 PERF_OUTPUT_IP = 1U << 7, 56 PERF_OUTPUT_SYM = 1U << 8, 57 PERF_OUTPUT_DSO = 1U << 9, 58 PERF_OUTPUT_ADDR = 1U << 10, 59 PERF_OUTPUT_SYMOFFSET = 1U << 11, 60 PERF_OUTPUT_SRCLINE = 1U << 12, 61 PERF_OUTPUT_PERIOD = 1U << 13, 62 PERF_OUTPUT_IREGS = 1U << 14, 63 PERF_OUTPUT_BRSTACK = 1U << 15, 64 PERF_OUTPUT_BRSTACKSYM = 1U << 16, 65 PERF_OUTPUT_DATA_SRC = 1U << 17, 66 PERF_OUTPUT_WEIGHT = 1U << 18, 67 PERF_OUTPUT_BPF_OUTPUT = 1U << 19, 68 PERF_OUTPUT_CALLINDENT = 1U << 20, 69 PERF_OUTPUT_INSN = 1U << 21, 70 PERF_OUTPUT_INSNLEN = 1U << 22, 71 }; 72 73 struct output_option { 74 const char *str; 75 enum perf_output_field field; 76 } all_output_options[] = { 77 {.str = "comm", .field = PERF_OUTPUT_COMM}, 78 {.str = "tid", .field = PERF_OUTPUT_TID}, 79 {.str = "pid", .field = PERF_OUTPUT_PID}, 80 {.str = "time", .field = PERF_OUTPUT_TIME}, 81 {.str = "cpu", .field = PERF_OUTPUT_CPU}, 82 {.str = "event", .field = PERF_OUTPUT_EVNAME}, 83 {.str = "trace", .field = PERF_OUTPUT_TRACE}, 84 {.str = "ip", .field = PERF_OUTPUT_IP}, 85 {.str = "sym", .field = PERF_OUTPUT_SYM}, 86 {.str = "dso", .field = PERF_OUTPUT_DSO}, 87 {.str = "addr", .field = PERF_OUTPUT_ADDR}, 88 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET}, 89 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, 90 {.str = "period", .field = PERF_OUTPUT_PERIOD}, 91 {.str = "iregs", .field = PERF_OUTPUT_IREGS}, 92 {.str = "brstack", .field = PERF_OUTPUT_BRSTACK}, 93 {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM}, 94 {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC}, 95 {.str = "weight", .field = PERF_OUTPUT_WEIGHT}, 96 {.str = "bpf-output", .field = PERF_OUTPUT_BPF_OUTPUT}, 97 {.str = "callindent", .field = PERF_OUTPUT_CALLINDENT}, 98 {.str = "insn", .field = PERF_OUTPUT_INSN}, 99 {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN}, 100 }; 101 102 /* default set to maintain compatibility with current format */ 103 static struct { 104 bool user_set; 105 bool wildcard_set; 106 unsigned int print_ip_opts; 107 u64 fields; 108 u64 invalid_fields; 109 } output[PERF_TYPE_MAX] = { 110 111 [PERF_TYPE_HARDWARE] = { 112 .user_set = false, 113 114 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 115 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 116 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 117 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 118 PERF_OUTPUT_PERIOD, 119 120 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 121 }, 122 123 [PERF_TYPE_SOFTWARE] = { 124 .user_set = false, 125 126 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 127 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 128 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 129 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 130 PERF_OUTPUT_PERIOD | PERF_OUTPUT_BPF_OUTPUT, 131 132 .invalid_fields = PERF_OUTPUT_TRACE, 133 }, 134 135 [PERF_TYPE_TRACEPOINT] = { 136 .user_set = false, 137 138 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 139 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 140 PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE 141 }, 142 143 [PERF_TYPE_RAW] = { 144 .user_set = false, 145 146 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 147 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 148 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 149 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 150 PERF_OUTPUT_PERIOD | PERF_OUTPUT_ADDR | 151 PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT, 152 153 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 154 }, 155 156 [PERF_TYPE_BREAKPOINT] = { 157 .user_set = false, 158 159 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 160 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 161 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 162 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 163 PERF_OUTPUT_PERIOD, 164 165 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 166 }, 167 }; 168 169 static bool output_set_by_user(void) 170 { 171 int j; 172 for (j = 0; j < PERF_TYPE_MAX; ++j) { 173 if (output[j].user_set) 174 return true; 175 } 176 return false; 177 } 178 179 static const char *output_field2str(enum perf_output_field field) 180 { 181 int i, imax = ARRAY_SIZE(all_output_options); 182 const char *str = ""; 183 184 for (i = 0; i < imax; ++i) { 185 if (all_output_options[i].field == field) { 186 str = all_output_options[i].str; 187 break; 188 } 189 } 190 return str; 191 } 192 193 #define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x) 194 195 static int perf_evsel__do_check_stype(struct perf_evsel *evsel, 196 u64 sample_type, const char *sample_msg, 197 enum perf_output_field field, 198 bool allow_user_set) 199 { 200 struct perf_event_attr *attr = &evsel->attr; 201 int type = attr->type; 202 const char *evname; 203 204 if (attr->sample_type & sample_type) 205 return 0; 206 207 if (output[type].user_set) { 208 if (allow_user_set) 209 return 0; 210 evname = perf_evsel__name(evsel); 211 pr_err("Samples for '%s' event do not have %s attribute set. " 212 "Cannot print '%s' field.\n", 213 evname, sample_msg, output_field2str(field)); 214 return -1; 215 } 216 217 /* user did not ask for it explicitly so remove from the default list */ 218 output[type].fields &= ~field; 219 evname = perf_evsel__name(evsel); 220 pr_debug("Samples for '%s' event do not have %s attribute set. " 221 "Skipping '%s' field.\n", 222 evname, sample_msg, output_field2str(field)); 223 224 return 0; 225 } 226 227 static int perf_evsel__check_stype(struct perf_evsel *evsel, 228 u64 sample_type, const char *sample_msg, 229 enum perf_output_field field) 230 { 231 return perf_evsel__do_check_stype(evsel, sample_type, sample_msg, field, 232 false); 233 } 234 235 static int perf_evsel__check_attr(struct perf_evsel *evsel, 236 struct perf_session *session) 237 { 238 struct perf_event_attr *attr = &evsel->attr; 239 bool allow_user_set; 240 241 if (perf_header__has_feat(&session->header, HEADER_STAT)) 242 return 0; 243 244 allow_user_set = perf_header__has_feat(&session->header, 245 HEADER_AUXTRACE); 246 247 if (PRINT_FIELD(TRACE) && 248 !perf_session__has_traces(session, "record -R")) 249 return -EINVAL; 250 251 if (PRINT_FIELD(IP)) { 252 if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", 253 PERF_OUTPUT_IP)) 254 return -EINVAL; 255 } 256 257 if (PRINT_FIELD(ADDR) && 258 perf_evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", 259 PERF_OUTPUT_ADDR, allow_user_set)) 260 return -EINVAL; 261 262 if (PRINT_FIELD(DATA_SRC) && 263 perf_evsel__check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC", 264 PERF_OUTPUT_DATA_SRC)) 265 return -EINVAL; 266 267 if (PRINT_FIELD(WEIGHT) && 268 perf_evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT, "WEIGHT", 269 PERF_OUTPUT_WEIGHT)) 270 return -EINVAL; 271 272 if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { 273 pr_err("Display of symbols requested but neither sample IP nor " 274 "sample address\nis selected. Hence, no addresses to convert " 275 "to symbols.\n"); 276 return -EINVAL; 277 } 278 if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) { 279 pr_err("Display of offsets requested but symbol is not" 280 "selected.\n"); 281 return -EINVAL; 282 } 283 if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { 284 pr_err("Display of DSO requested but neither sample IP nor " 285 "sample address\nis selected. Hence, no addresses to convert " 286 "to DSO.\n"); 287 return -EINVAL; 288 } 289 if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) { 290 pr_err("Display of source line number requested but sample IP is not\n" 291 "selected. Hence, no address to lookup the source line number.\n"); 292 return -EINVAL; 293 } 294 295 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && 296 perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", 297 PERF_OUTPUT_TID|PERF_OUTPUT_PID)) 298 return -EINVAL; 299 300 if (PRINT_FIELD(TIME) && 301 perf_evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", 302 PERF_OUTPUT_TIME)) 303 return -EINVAL; 304 305 if (PRINT_FIELD(CPU) && 306 perf_evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU", 307 PERF_OUTPUT_CPU, allow_user_set)) 308 return -EINVAL; 309 310 if (PRINT_FIELD(PERIOD) && 311 perf_evsel__check_stype(evsel, PERF_SAMPLE_PERIOD, "PERIOD", 312 PERF_OUTPUT_PERIOD)) 313 return -EINVAL; 314 315 if (PRINT_FIELD(IREGS) && 316 perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", 317 PERF_OUTPUT_IREGS)) 318 return -EINVAL; 319 320 return 0; 321 } 322 323 static void set_print_ip_opts(struct perf_event_attr *attr) 324 { 325 unsigned int type = attr->type; 326 327 output[type].print_ip_opts = 0; 328 if (PRINT_FIELD(IP)) 329 output[type].print_ip_opts |= EVSEL__PRINT_IP; 330 331 if (PRINT_FIELD(SYM)) 332 output[type].print_ip_opts |= EVSEL__PRINT_SYM; 333 334 if (PRINT_FIELD(DSO)) 335 output[type].print_ip_opts |= EVSEL__PRINT_DSO; 336 337 if (PRINT_FIELD(SYMOFFSET)) 338 output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET; 339 340 if (PRINT_FIELD(SRCLINE)) 341 output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE; 342 } 343 344 /* 345 * verify all user requested events exist and the samples 346 * have the expected data 347 */ 348 static int perf_session__check_output_opt(struct perf_session *session) 349 { 350 unsigned int j; 351 struct perf_evsel *evsel; 352 353 for (j = 0; j < PERF_TYPE_MAX; ++j) { 354 evsel = perf_session__find_first_evtype(session, j); 355 356 /* 357 * even if fields is set to 0 (ie., show nothing) event must 358 * exist if user explicitly includes it on the command line 359 */ 360 if (!evsel && output[j].user_set && !output[j].wildcard_set) { 361 pr_err("%s events do not exist. " 362 "Remove corresponding -f option to proceed.\n", 363 event_type(j)); 364 return -1; 365 } 366 367 if (evsel && output[j].fields && 368 perf_evsel__check_attr(evsel, session)) 369 return -1; 370 371 if (evsel == NULL) 372 continue; 373 374 set_print_ip_opts(&evsel->attr); 375 } 376 377 if (!no_callchain) { 378 bool use_callchain = false; 379 bool not_pipe = false; 380 381 evlist__for_each_entry(session->evlist, evsel) { 382 not_pipe = true; 383 if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) { 384 use_callchain = true; 385 break; 386 } 387 } 388 if (not_pipe && !use_callchain) 389 symbol_conf.use_callchain = false; 390 } 391 392 /* 393 * set default for tracepoints to print symbols only 394 * if callchains are present 395 */ 396 if (symbol_conf.use_callchain && 397 !output[PERF_TYPE_TRACEPOINT].user_set) { 398 struct perf_event_attr *attr; 399 400 j = PERF_TYPE_TRACEPOINT; 401 402 evlist__for_each_entry(session->evlist, evsel) { 403 if (evsel->attr.type != j) 404 continue; 405 406 attr = &evsel->attr; 407 408 if (attr->sample_type & PERF_SAMPLE_CALLCHAIN) { 409 output[j].fields |= PERF_OUTPUT_IP; 410 output[j].fields |= PERF_OUTPUT_SYM; 411 output[j].fields |= PERF_OUTPUT_DSO; 412 set_print_ip_opts(attr); 413 goto out; 414 } 415 } 416 } 417 418 out: 419 return 0; 420 } 421 422 static void print_sample_iregs(struct perf_sample *sample, 423 struct perf_event_attr *attr) 424 { 425 struct regs_dump *regs = &sample->intr_regs; 426 uint64_t mask = attr->sample_regs_intr; 427 unsigned i = 0, r; 428 429 if (!regs) 430 return; 431 432 for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { 433 u64 val = regs->regs[i++]; 434 printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val); 435 } 436 } 437 438 static void print_sample_start(struct perf_sample *sample, 439 struct thread *thread, 440 struct perf_evsel *evsel) 441 { 442 struct perf_event_attr *attr = &evsel->attr; 443 unsigned long secs; 444 unsigned long usecs; 445 unsigned long long nsecs; 446 447 if (PRINT_FIELD(COMM)) { 448 if (latency_format) 449 printf("%8.8s ", thread__comm_str(thread)); 450 else if (PRINT_FIELD(IP) && symbol_conf.use_callchain) 451 printf("%s ", thread__comm_str(thread)); 452 else 453 printf("%16s ", thread__comm_str(thread)); 454 } 455 456 if (PRINT_FIELD(PID) && PRINT_FIELD(TID)) 457 printf("%5d/%-5d ", sample->pid, sample->tid); 458 else if (PRINT_FIELD(PID)) 459 printf("%5d ", sample->pid); 460 else if (PRINT_FIELD(TID)) 461 printf("%5d ", sample->tid); 462 463 if (PRINT_FIELD(CPU)) { 464 if (latency_format) 465 printf("%3d ", sample->cpu); 466 else 467 printf("[%03d] ", sample->cpu); 468 } 469 470 if (PRINT_FIELD(TIME)) { 471 nsecs = sample->time; 472 secs = nsecs / NSEC_PER_SEC; 473 nsecs -= secs * NSEC_PER_SEC; 474 usecs = nsecs / NSEC_PER_USEC; 475 if (nanosecs) 476 printf("%5lu.%09llu: ", secs, nsecs); 477 else 478 printf("%5lu.%06lu: ", secs, usecs); 479 } 480 } 481 482 static inline char 483 mispred_str(struct branch_entry *br) 484 { 485 if (!(br->flags.mispred || br->flags.predicted)) 486 return '-'; 487 488 return br->flags.predicted ? 'P' : 'M'; 489 } 490 491 static void print_sample_brstack(struct perf_sample *sample) 492 { 493 struct branch_stack *br = sample->branch_stack; 494 u64 i; 495 496 if (!(br && br->nr)) 497 return; 498 499 for (i = 0; i < br->nr; i++) { 500 printf(" 0x%"PRIx64"/0x%"PRIx64"/%c/%c/%c/%d ", 501 br->entries[i].from, 502 br->entries[i].to, 503 mispred_str( br->entries + i), 504 br->entries[i].flags.in_tx? 'X' : '-', 505 br->entries[i].flags.abort? 'A' : '-', 506 br->entries[i].flags.cycles); 507 } 508 } 509 510 static void print_sample_brstacksym(struct perf_sample *sample, 511 struct thread *thread) 512 { 513 struct branch_stack *br = sample->branch_stack; 514 struct addr_location alf, alt; 515 u64 i, from, to; 516 517 if (!(br && br->nr)) 518 return; 519 520 for (i = 0; i < br->nr; i++) { 521 522 memset(&alf, 0, sizeof(alf)); 523 memset(&alt, 0, sizeof(alt)); 524 from = br->entries[i].from; 525 to = br->entries[i].to; 526 527 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf); 528 if (alf.map) 529 alf.sym = map__find_symbol(alf.map, alf.addr); 530 531 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt); 532 if (alt.map) 533 alt.sym = map__find_symbol(alt.map, alt.addr); 534 535 symbol__fprintf_symname_offs(alf.sym, &alf, stdout); 536 putchar('/'); 537 symbol__fprintf_symname_offs(alt.sym, &alt, stdout); 538 printf("/%c/%c/%c/%d ", 539 mispred_str( br->entries + i), 540 br->entries[i].flags.in_tx? 'X' : '-', 541 br->entries[i].flags.abort? 'A' : '-', 542 br->entries[i].flags.cycles); 543 } 544 } 545 546 547 static void print_sample_addr(struct perf_sample *sample, 548 struct thread *thread, 549 struct perf_event_attr *attr) 550 { 551 struct addr_location al; 552 553 printf("%16" PRIx64, sample->addr); 554 555 if (!sample_addr_correlates_sym(attr)) 556 return; 557 558 thread__resolve(thread, &al, sample); 559 560 if (PRINT_FIELD(SYM)) { 561 printf(" "); 562 if (PRINT_FIELD(SYMOFFSET)) 563 symbol__fprintf_symname_offs(al.sym, &al, stdout); 564 else 565 symbol__fprintf_symname(al.sym, stdout); 566 } 567 568 if (PRINT_FIELD(DSO)) { 569 printf(" ("); 570 map__fprintf_dsoname(al.map, stdout); 571 printf(")"); 572 } 573 } 574 575 static void print_sample_callindent(struct perf_sample *sample, 576 struct perf_evsel *evsel, 577 struct thread *thread, 578 struct addr_location *al) 579 { 580 struct perf_event_attr *attr = &evsel->attr; 581 size_t depth = thread_stack__depth(thread); 582 struct addr_location addr_al; 583 const char *name = NULL; 584 static int spacing; 585 int len = 0; 586 u64 ip = 0; 587 588 /* 589 * The 'return' has already been popped off the stack so the depth has 590 * to be adjusted to match the 'call'. 591 */ 592 if (thread->ts && sample->flags & PERF_IP_FLAG_RETURN) 593 depth += 1; 594 595 if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) { 596 if (sample_addr_correlates_sym(attr)) { 597 thread__resolve(thread, &addr_al, sample); 598 if (addr_al.sym) 599 name = addr_al.sym->name; 600 else 601 ip = sample->addr; 602 } else { 603 ip = sample->addr; 604 } 605 } else if (sample->flags & (PERF_IP_FLAG_RETURN | PERF_IP_FLAG_TRACE_END)) { 606 if (al->sym) 607 name = al->sym->name; 608 else 609 ip = sample->ip; 610 } 611 612 if (name) 613 len = printf("%*s%s", (int)depth * 4, "", name); 614 else if (ip) 615 len = printf("%*s%16" PRIx64, (int)depth * 4, "", ip); 616 617 if (len < 0) 618 return; 619 620 /* 621 * Try to keep the output length from changing frequently so that the 622 * output lines up more nicely. 623 */ 624 if (len > spacing || (len && len < spacing - 52)) 625 spacing = round_up(len + 4, 32); 626 627 if (len < spacing) 628 printf("%*s", spacing - len, ""); 629 } 630 631 static void print_insn(struct perf_sample *sample, 632 struct perf_event_attr *attr) 633 { 634 if (PRINT_FIELD(INSNLEN)) 635 printf(" ilen: %d", sample->insn_len); 636 if (PRINT_FIELD(INSN)) { 637 int i; 638 639 printf(" insn:"); 640 for (i = 0; i < sample->insn_len; i++) 641 printf(" %02x", (unsigned char)sample->insn[i]); 642 } 643 } 644 645 static void print_sample_bts(struct perf_sample *sample, 646 struct perf_evsel *evsel, 647 struct thread *thread, 648 struct addr_location *al) 649 { 650 struct perf_event_attr *attr = &evsel->attr; 651 bool print_srcline_last = false; 652 653 if (PRINT_FIELD(CALLINDENT)) 654 print_sample_callindent(sample, evsel, thread, al); 655 656 /* print branch_from information */ 657 if (PRINT_FIELD(IP)) { 658 unsigned int print_opts = output[attr->type].print_ip_opts; 659 struct callchain_cursor *cursor = NULL; 660 661 if (symbol_conf.use_callchain && sample->callchain && 662 thread__resolve_callchain(al->thread, &callchain_cursor, evsel, 663 sample, NULL, NULL, scripting_max_stack) == 0) 664 cursor = &callchain_cursor; 665 666 if (cursor == NULL) { 667 putchar(' '); 668 if (print_opts & EVSEL__PRINT_SRCLINE) { 669 print_srcline_last = true; 670 print_opts &= ~EVSEL__PRINT_SRCLINE; 671 } 672 } else 673 putchar('\n'); 674 675 sample__fprintf_sym(sample, al, 0, print_opts, cursor, stdout); 676 } 677 678 /* print branch_to information */ 679 if (PRINT_FIELD(ADDR) || 680 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && 681 !output[attr->type].user_set)) { 682 printf(" => "); 683 print_sample_addr(sample, thread, attr); 684 } 685 686 if (print_srcline_last) 687 map__fprintf_srcline(al->map, al->addr, "\n ", stdout); 688 689 print_insn(sample, attr); 690 691 printf("\n"); 692 } 693 694 static struct { 695 u32 flags; 696 const char *name; 697 } sample_flags[] = { 698 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"}, 699 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"}, 700 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"}, 701 {PERF_IP_FLAG_BRANCH, "jmp"}, 702 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"}, 703 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"}, 704 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"}, 705 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"}, 706 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"}, 707 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT, "hw int"}, 708 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"}, 709 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"}, 710 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"}, 711 {0, NULL} 712 }; 713 714 static void print_sample_flags(u32 flags) 715 { 716 const char *chars = PERF_IP_FLAG_CHARS; 717 const int n = strlen(PERF_IP_FLAG_CHARS); 718 bool in_tx = flags & PERF_IP_FLAG_IN_TX; 719 const char *name = NULL; 720 char str[33]; 721 int i, pos = 0; 722 723 for (i = 0; sample_flags[i].name ; i++) { 724 if (sample_flags[i].flags == (flags & ~PERF_IP_FLAG_IN_TX)) { 725 name = sample_flags[i].name; 726 break; 727 } 728 } 729 730 for (i = 0; i < n; i++, flags >>= 1) { 731 if (flags & 1) 732 str[pos++] = chars[i]; 733 } 734 for (; i < 32; i++, flags >>= 1) { 735 if (flags & 1) 736 str[pos++] = '?'; 737 } 738 str[pos] = 0; 739 740 if (name) 741 printf(" %-7s%4s ", name, in_tx ? "(x)" : ""); 742 else 743 printf(" %-11s ", str); 744 } 745 746 struct printer_data { 747 int line_no; 748 bool hit_nul; 749 bool is_printable; 750 }; 751 752 static void 753 print_sample_bpf_output_printer(enum binary_printer_ops op, 754 unsigned int val, 755 void *extra) 756 { 757 unsigned char ch = (unsigned char)val; 758 struct printer_data *printer_data = extra; 759 760 switch (op) { 761 case BINARY_PRINT_DATA_BEGIN: 762 printf("\n"); 763 break; 764 case BINARY_PRINT_LINE_BEGIN: 765 printf("%17s", !printer_data->line_no ? "BPF output:" : 766 " "); 767 break; 768 case BINARY_PRINT_ADDR: 769 printf(" %04x:", val); 770 break; 771 case BINARY_PRINT_NUM_DATA: 772 printf(" %02x", val); 773 break; 774 case BINARY_PRINT_NUM_PAD: 775 printf(" "); 776 break; 777 case BINARY_PRINT_SEP: 778 printf(" "); 779 break; 780 case BINARY_PRINT_CHAR_DATA: 781 if (printer_data->hit_nul && ch) 782 printer_data->is_printable = false; 783 784 if (!isprint(ch)) { 785 printf("%c", '.'); 786 787 if (!printer_data->is_printable) 788 break; 789 790 if (ch == '\0') 791 printer_data->hit_nul = true; 792 else 793 printer_data->is_printable = false; 794 } else { 795 printf("%c", ch); 796 } 797 break; 798 case BINARY_PRINT_CHAR_PAD: 799 printf(" "); 800 break; 801 case BINARY_PRINT_LINE_END: 802 printf("\n"); 803 printer_data->line_no++; 804 break; 805 case BINARY_PRINT_DATA_END: 806 default: 807 break; 808 } 809 } 810 811 static void print_sample_bpf_output(struct perf_sample *sample) 812 { 813 unsigned int nr_bytes = sample->raw_size; 814 struct printer_data printer_data = {0, false, true}; 815 816 print_binary(sample->raw_data, nr_bytes, 8, 817 print_sample_bpf_output_printer, &printer_data); 818 819 if (printer_data.is_printable && printer_data.hit_nul) 820 printf("%17s \"%s\"\n", "BPF string:", 821 (char *)(sample->raw_data)); 822 } 823 824 struct perf_script { 825 struct perf_tool tool; 826 struct perf_session *session; 827 bool show_task_events; 828 bool show_mmap_events; 829 bool show_switch_events; 830 bool allocated; 831 struct cpu_map *cpus; 832 struct thread_map *threads; 833 int name_width; 834 }; 835 836 static int perf_evlist__max_name_len(struct perf_evlist *evlist) 837 { 838 struct perf_evsel *evsel; 839 int max = 0; 840 841 evlist__for_each_entry(evlist, evsel) { 842 int len = strlen(perf_evsel__name(evsel)); 843 844 max = MAX(len, max); 845 } 846 847 return max; 848 } 849 850 static size_t data_src__printf(u64 data_src) 851 { 852 struct mem_info mi = { .data_src.val = data_src }; 853 char decode[100]; 854 char out[100]; 855 static int maxlen; 856 int len; 857 858 perf_script__meminfo_scnprintf(decode, 100, &mi); 859 860 len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode); 861 if (maxlen < len) 862 maxlen = len; 863 864 return printf("%-*s", maxlen, out); 865 } 866 867 static void process_event(struct perf_script *script, 868 struct perf_sample *sample, struct perf_evsel *evsel, 869 struct addr_location *al) 870 { 871 struct thread *thread = al->thread; 872 struct perf_event_attr *attr = &evsel->attr; 873 874 if (output[attr->type].fields == 0) 875 return; 876 877 print_sample_start(sample, thread, evsel); 878 879 if (PRINT_FIELD(PERIOD)) 880 printf("%10" PRIu64 " ", sample->period); 881 882 if (PRINT_FIELD(EVNAME)) { 883 const char *evname = perf_evsel__name(evsel); 884 885 if (!script->name_width) 886 script->name_width = perf_evlist__max_name_len(script->session->evlist); 887 888 printf("%*s: ", script->name_width, 889 evname ? evname : "[unknown]"); 890 } 891 892 if (print_flags) 893 print_sample_flags(sample->flags); 894 895 if (is_bts_event(attr)) { 896 print_sample_bts(sample, evsel, thread, al); 897 return; 898 } 899 900 if (PRINT_FIELD(TRACE)) 901 event_format__print(evsel->tp_format, sample->cpu, 902 sample->raw_data, sample->raw_size); 903 if (PRINT_FIELD(ADDR)) 904 print_sample_addr(sample, thread, attr); 905 906 if (PRINT_FIELD(DATA_SRC)) 907 data_src__printf(sample->data_src); 908 909 if (PRINT_FIELD(WEIGHT)) 910 printf("%16" PRIu64, sample->weight); 911 912 if (PRINT_FIELD(IP)) { 913 struct callchain_cursor *cursor = NULL; 914 915 if (symbol_conf.use_callchain && sample->callchain && 916 thread__resolve_callchain(al->thread, &callchain_cursor, evsel, 917 sample, NULL, NULL, scripting_max_stack) == 0) 918 cursor = &callchain_cursor; 919 920 putchar(cursor ? '\n' : ' '); 921 sample__fprintf_sym(sample, al, 0, output[attr->type].print_ip_opts, cursor, stdout); 922 } 923 924 if (PRINT_FIELD(IREGS)) 925 print_sample_iregs(sample, attr); 926 927 if (PRINT_FIELD(BRSTACK)) 928 print_sample_brstack(sample); 929 else if (PRINT_FIELD(BRSTACKSYM)) 930 print_sample_brstacksym(sample, thread); 931 932 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) 933 print_sample_bpf_output(sample); 934 print_insn(sample, attr); 935 printf("\n"); 936 } 937 938 static struct scripting_ops *scripting_ops; 939 940 static void __process_stat(struct perf_evsel *counter, u64 tstamp) 941 { 942 int nthreads = thread_map__nr(counter->threads); 943 int ncpus = perf_evsel__nr_cpus(counter); 944 int cpu, thread; 945 static int header_printed; 946 947 if (counter->system_wide) 948 nthreads = 1; 949 950 if (!header_printed) { 951 printf("%3s %8s %15s %15s %15s %15s %s\n", 952 "CPU", "THREAD", "VAL", "ENA", "RUN", "TIME", "EVENT"); 953 header_printed = 1; 954 } 955 956 for (thread = 0; thread < nthreads; thread++) { 957 for (cpu = 0; cpu < ncpus; cpu++) { 958 struct perf_counts_values *counts; 959 960 counts = perf_counts(counter->counts, cpu, thread); 961 962 printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n", 963 counter->cpus->map[cpu], 964 thread_map__pid(counter->threads, thread), 965 counts->val, 966 counts->ena, 967 counts->run, 968 tstamp, 969 perf_evsel__name(counter)); 970 } 971 } 972 } 973 974 static void process_stat(struct perf_evsel *counter, u64 tstamp) 975 { 976 if (scripting_ops && scripting_ops->process_stat) 977 scripting_ops->process_stat(&stat_config, counter, tstamp); 978 else 979 __process_stat(counter, tstamp); 980 } 981 982 static void process_stat_interval(u64 tstamp) 983 { 984 if (scripting_ops && scripting_ops->process_stat_interval) 985 scripting_ops->process_stat_interval(tstamp); 986 } 987 988 static void setup_scripting(void) 989 { 990 setup_perl_scripting(); 991 setup_python_scripting(); 992 } 993 994 static int flush_scripting(void) 995 { 996 return scripting_ops ? scripting_ops->flush_script() : 0; 997 } 998 999 static int cleanup_scripting(void) 1000 { 1001 pr_debug("\nperf script stopped\n"); 1002 1003 return scripting_ops ? scripting_ops->stop_script() : 0; 1004 } 1005 1006 static int process_sample_event(struct perf_tool *tool, 1007 union perf_event *event, 1008 struct perf_sample *sample, 1009 struct perf_evsel *evsel, 1010 struct machine *machine) 1011 { 1012 struct perf_script *scr = container_of(tool, struct perf_script, tool); 1013 struct addr_location al; 1014 1015 if (debug_mode) { 1016 if (sample->time < last_timestamp) { 1017 pr_err("Samples misordered, previous: %" PRIu64 1018 " this: %" PRIu64 "\n", last_timestamp, 1019 sample->time); 1020 nr_unordered++; 1021 } 1022 last_timestamp = sample->time; 1023 return 0; 1024 } 1025 1026 if (machine__resolve(machine, &al, sample) < 0) { 1027 pr_err("problem processing %d event, skipping it.\n", 1028 event->header.type); 1029 return -1; 1030 } 1031 1032 if (al.filtered) 1033 goto out_put; 1034 1035 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) 1036 goto out_put; 1037 1038 if (scripting_ops) 1039 scripting_ops->process_event(event, sample, evsel, &al); 1040 else 1041 process_event(scr, sample, evsel, &al); 1042 1043 out_put: 1044 addr_location__put(&al); 1045 return 0; 1046 } 1047 1048 static int process_attr(struct perf_tool *tool, union perf_event *event, 1049 struct perf_evlist **pevlist) 1050 { 1051 struct perf_script *scr = container_of(tool, struct perf_script, tool); 1052 struct perf_evlist *evlist; 1053 struct perf_evsel *evsel, *pos; 1054 int err; 1055 1056 err = perf_event__process_attr(tool, event, pevlist); 1057 if (err) 1058 return err; 1059 1060 evlist = *pevlist; 1061 evsel = perf_evlist__last(*pevlist); 1062 1063 if (evsel->attr.type >= PERF_TYPE_MAX) 1064 return 0; 1065 1066 evlist__for_each_entry(evlist, pos) { 1067 if (pos->attr.type == evsel->attr.type && pos != evsel) 1068 return 0; 1069 } 1070 1071 set_print_ip_opts(&evsel->attr); 1072 1073 if (evsel->attr.sample_type) 1074 err = perf_evsel__check_attr(evsel, scr->session); 1075 1076 return err; 1077 } 1078 1079 static int process_comm_event(struct perf_tool *tool, 1080 union perf_event *event, 1081 struct perf_sample *sample, 1082 struct machine *machine) 1083 { 1084 struct thread *thread; 1085 struct perf_script *script = container_of(tool, struct perf_script, tool); 1086 struct perf_session *session = script->session; 1087 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1088 int ret = -1; 1089 1090 thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid); 1091 if (thread == NULL) { 1092 pr_debug("problem processing COMM event, skipping it.\n"); 1093 return -1; 1094 } 1095 1096 if (perf_event__process_comm(tool, event, sample, machine) < 0) 1097 goto out; 1098 1099 if (!evsel->attr.sample_id_all) { 1100 sample->cpu = 0; 1101 sample->time = 0; 1102 sample->tid = event->comm.tid; 1103 sample->pid = event->comm.pid; 1104 } 1105 print_sample_start(sample, thread, evsel); 1106 perf_event__fprintf(event, stdout); 1107 ret = 0; 1108 out: 1109 thread__put(thread); 1110 return ret; 1111 } 1112 1113 static int process_fork_event(struct perf_tool *tool, 1114 union perf_event *event, 1115 struct perf_sample *sample, 1116 struct machine *machine) 1117 { 1118 struct thread *thread; 1119 struct perf_script *script = container_of(tool, struct perf_script, tool); 1120 struct perf_session *session = script->session; 1121 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1122 1123 if (perf_event__process_fork(tool, event, sample, machine) < 0) 1124 return -1; 1125 1126 thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); 1127 if (thread == NULL) { 1128 pr_debug("problem processing FORK event, skipping it.\n"); 1129 return -1; 1130 } 1131 1132 if (!evsel->attr.sample_id_all) { 1133 sample->cpu = 0; 1134 sample->time = event->fork.time; 1135 sample->tid = event->fork.tid; 1136 sample->pid = event->fork.pid; 1137 } 1138 print_sample_start(sample, thread, evsel); 1139 perf_event__fprintf(event, stdout); 1140 thread__put(thread); 1141 1142 return 0; 1143 } 1144 static int process_exit_event(struct perf_tool *tool, 1145 union perf_event *event, 1146 struct perf_sample *sample, 1147 struct machine *machine) 1148 { 1149 int err = 0; 1150 struct thread *thread; 1151 struct perf_script *script = container_of(tool, struct perf_script, tool); 1152 struct perf_session *session = script->session; 1153 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1154 1155 thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); 1156 if (thread == NULL) { 1157 pr_debug("problem processing EXIT event, skipping it.\n"); 1158 return -1; 1159 } 1160 1161 if (!evsel->attr.sample_id_all) { 1162 sample->cpu = 0; 1163 sample->time = 0; 1164 sample->tid = event->fork.tid; 1165 sample->pid = event->fork.pid; 1166 } 1167 print_sample_start(sample, thread, evsel); 1168 perf_event__fprintf(event, stdout); 1169 1170 if (perf_event__process_exit(tool, event, sample, machine) < 0) 1171 err = -1; 1172 1173 thread__put(thread); 1174 return err; 1175 } 1176 1177 static int process_mmap_event(struct perf_tool *tool, 1178 union perf_event *event, 1179 struct perf_sample *sample, 1180 struct machine *machine) 1181 { 1182 struct thread *thread; 1183 struct perf_script *script = container_of(tool, struct perf_script, tool); 1184 struct perf_session *session = script->session; 1185 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1186 1187 if (perf_event__process_mmap(tool, event, sample, machine) < 0) 1188 return -1; 1189 1190 thread = machine__findnew_thread(machine, event->mmap.pid, event->mmap.tid); 1191 if (thread == NULL) { 1192 pr_debug("problem processing MMAP event, skipping it.\n"); 1193 return -1; 1194 } 1195 1196 if (!evsel->attr.sample_id_all) { 1197 sample->cpu = 0; 1198 sample->time = 0; 1199 sample->tid = event->mmap.tid; 1200 sample->pid = event->mmap.pid; 1201 } 1202 print_sample_start(sample, thread, evsel); 1203 perf_event__fprintf(event, stdout); 1204 thread__put(thread); 1205 return 0; 1206 } 1207 1208 static int process_mmap2_event(struct perf_tool *tool, 1209 union perf_event *event, 1210 struct perf_sample *sample, 1211 struct machine *machine) 1212 { 1213 struct thread *thread; 1214 struct perf_script *script = container_of(tool, struct perf_script, tool); 1215 struct perf_session *session = script->session; 1216 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1217 1218 if (perf_event__process_mmap2(tool, event, sample, machine) < 0) 1219 return -1; 1220 1221 thread = machine__findnew_thread(machine, event->mmap2.pid, event->mmap2.tid); 1222 if (thread == NULL) { 1223 pr_debug("problem processing MMAP2 event, skipping it.\n"); 1224 return -1; 1225 } 1226 1227 if (!evsel->attr.sample_id_all) { 1228 sample->cpu = 0; 1229 sample->time = 0; 1230 sample->tid = event->mmap2.tid; 1231 sample->pid = event->mmap2.pid; 1232 } 1233 print_sample_start(sample, thread, evsel); 1234 perf_event__fprintf(event, stdout); 1235 thread__put(thread); 1236 return 0; 1237 } 1238 1239 static int process_switch_event(struct perf_tool *tool, 1240 union perf_event *event, 1241 struct perf_sample *sample, 1242 struct machine *machine) 1243 { 1244 struct thread *thread; 1245 struct perf_script *script = container_of(tool, struct perf_script, tool); 1246 struct perf_session *session = script->session; 1247 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1248 1249 if (perf_event__process_switch(tool, event, sample, machine) < 0) 1250 return -1; 1251 1252 thread = machine__findnew_thread(machine, sample->pid, 1253 sample->tid); 1254 if (thread == NULL) { 1255 pr_debug("problem processing SWITCH event, skipping it.\n"); 1256 return -1; 1257 } 1258 1259 print_sample_start(sample, thread, evsel); 1260 perf_event__fprintf(event, stdout); 1261 thread__put(thread); 1262 return 0; 1263 } 1264 1265 static void sig_handler(int sig __maybe_unused) 1266 { 1267 session_done = 1; 1268 } 1269 1270 static int __cmd_script(struct perf_script *script) 1271 { 1272 int ret; 1273 1274 signal(SIGINT, sig_handler); 1275 1276 /* override event processing functions */ 1277 if (script->show_task_events) { 1278 script->tool.comm = process_comm_event; 1279 script->tool.fork = process_fork_event; 1280 script->tool.exit = process_exit_event; 1281 } 1282 if (script->show_mmap_events) { 1283 script->tool.mmap = process_mmap_event; 1284 script->tool.mmap2 = process_mmap2_event; 1285 } 1286 if (script->show_switch_events) 1287 script->tool.context_switch = process_switch_event; 1288 1289 ret = perf_session__process_events(script->session); 1290 1291 if (debug_mode) 1292 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 1293 1294 return ret; 1295 } 1296 1297 struct script_spec { 1298 struct list_head node; 1299 struct scripting_ops *ops; 1300 char spec[0]; 1301 }; 1302 1303 static LIST_HEAD(script_specs); 1304 1305 static struct script_spec *script_spec__new(const char *spec, 1306 struct scripting_ops *ops) 1307 { 1308 struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1); 1309 1310 if (s != NULL) { 1311 strcpy(s->spec, spec); 1312 s->ops = ops; 1313 } 1314 1315 return s; 1316 } 1317 1318 static void script_spec__add(struct script_spec *s) 1319 { 1320 list_add_tail(&s->node, &script_specs); 1321 } 1322 1323 static struct script_spec *script_spec__find(const char *spec) 1324 { 1325 struct script_spec *s; 1326 1327 list_for_each_entry(s, &script_specs, node) 1328 if (strcasecmp(s->spec, spec) == 0) 1329 return s; 1330 return NULL; 1331 } 1332 1333 int script_spec_register(const char *spec, struct scripting_ops *ops) 1334 { 1335 struct script_spec *s; 1336 1337 s = script_spec__find(spec); 1338 if (s) 1339 return -1; 1340 1341 s = script_spec__new(spec, ops); 1342 if (!s) 1343 return -1; 1344 else 1345 script_spec__add(s); 1346 1347 return 0; 1348 } 1349 1350 static struct scripting_ops *script_spec__lookup(const char *spec) 1351 { 1352 struct script_spec *s = script_spec__find(spec); 1353 if (!s) 1354 return NULL; 1355 1356 return s->ops; 1357 } 1358 1359 static void list_available_languages(void) 1360 { 1361 struct script_spec *s; 1362 1363 fprintf(stderr, "\n"); 1364 fprintf(stderr, "Scripting language extensions (used in " 1365 "perf script -s [spec:]script.[spec]):\n\n"); 1366 1367 list_for_each_entry(s, &script_specs, node) 1368 fprintf(stderr, " %-42s [%s]\n", s->spec, s->ops->name); 1369 1370 fprintf(stderr, "\n"); 1371 } 1372 1373 static int parse_scriptname(const struct option *opt __maybe_unused, 1374 const char *str, int unset __maybe_unused) 1375 { 1376 char spec[PATH_MAX]; 1377 const char *script, *ext; 1378 int len; 1379 1380 if (strcmp(str, "lang") == 0) { 1381 list_available_languages(); 1382 exit(0); 1383 } 1384 1385 script = strchr(str, ':'); 1386 if (script) { 1387 len = script - str; 1388 if (len >= PATH_MAX) { 1389 fprintf(stderr, "invalid language specifier"); 1390 return -1; 1391 } 1392 strncpy(spec, str, len); 1393 spec[len] = '\0'; 1394 scripting_ops = script_spec__lookup(spec); 1395 if (!scripting_ops) { 1396 fprintf(stderr, "invalid language specifier"); 1397 return -1; 1398 } 1399 script++; 1400 } else { 1401 script = str; 1402 ext = strrchr(script, '.'); 1403 if (!ext) { 1404 fprintf(stderr, "invalid script extension"); 1405 return -1; 1406 } 1407 scripting_ops = script_spec__lookup(++ext); 1408 if (!scripting_ops) { 1409 fprintf(stderr, "invalid script extension"); 1410 return -1; 1411 } 1412 } 1413 1414 script_name = strdup(script); 1415 1416 return 0; 1417 } 1418 1419 static int parse_output_fields(const struct option *opt __maybe_unused, 1420 const char *arg, int unset __maybe_unused) 1421 { 1422 char *tok; 1423 int i, imax = ARRAY_SIZE(all_output_options); 1424 int j; 1425 int rc = 0; 1426 char *str = strdup(arg); 1427 int type = -1; 1428 1429 if (!str) 1430 return -ENOMEM; 1431 1432 /* first word can state for which event type the user is specifying 1433 * the fields. If no type exists, the specified fields apply to all 1434 * event types found in the file minus the invalid fields for a type. 1435 */ 1436 tok = strchr(str, ':'); 1437 if (tok) { 1438 *tok = '\0'; 1439 tok++; 1440 if (!strcmp(str, "hw")) 1441 type = PERF_TYPE_HARDWARE; 1442 else if (!strcmp(str, "sw")) 1443 type = PERF_TYPE_SOFTWARE; 1444 else if (!strcmp(str, "trace")) 1445 type = PERF_TYPE_TRACEPOINT; 1446 else if (!strcmp(str, "raw")) 1447 type = PERF_TYPE_RAW; 1448 else if (!strcmp(str, "break")) 1449 type = PERF_TYPE_BREAKPOINT; 1450 else { 1451 fprintf(stderr, "Invalid event type in field string.\n"); 1452 rc = -EINVAL; 1453 goto out; 1454 } 1455 1456 if (output[type].user_set) 1457 pr_warning("Overriding previous field request for %s events.\n", 1458 event_type(type)); 1459 1460 output[type].fields = 0; 1461 output[type].user_set = true; 1462 output[type].wildcard_set = false; 1463 1464 } else { 1465 tok = str; 1466 if (strlen(str) == 0) { 1467 fprintf(stderr, 1468 "Cannot set fields to 'none' for all event types.\n"); 1469 rc = -EINVAL; 1470 goto out; 1471 } 1472 1473 if (output_set_by_user()) 1474 pr_warning("Overriding previous field request for all events.\n"); 1475 1476 for (j = 0; j < PERF_TYPE_MAX; ++j) { 1477 output[j].fields = 0; 1478 output[j].user_set = true; 1479 output[j].wildcard_set = true; 1480 } 1481 } 1482 1483 for (tok = strtok(tok, ","); tok; tok = strtok(NULL, ",")) { 1484 for (i = 0; i < imax; ++i) { 1485 if (strcmp(tok, all_output_options[i].str) == 0) 1486 break; 1487 } 1488 if (i == imax && strcmp(tok, "flags") == 0) { 1489 print_flags = true; 1490 continue; 1491 } 1492 if (i == imax) { 1493 fprintf(stderr, "Invalid field requested.\n"); 1494 rc = -EINVAL; 1495 goto out; 1496 } 1497 1498 if (type == -1) { 1499 /* add user option to all events types for 1500 * which it is valid 1501 */ 1502 for (j = 0; j < PERF_TYPE_MAX; ++j) { 1503 if (output[j].invalid_fields & all_output_options[i].field) { 1504 pr_warning("\'%s\' not valid for %s events. Ignoring.\n", 1505 all_output_options[i].str, event_type(j)); 1506 } else 1507 output[j].fields |= all_output_options[i].field; 1508 } 1509 } else { 1510 if (output[type].invalid_fields & all_output_options[i].field) { 1511 fprintf(stderr, "\'%s\' not valid for %s events.\n", 1512 all_output_options[i].str, event_type(type)); 1513 1514 rc = -EINVAL; 1515 goto out; 1516 } 1517 output[type].fields |= all_output_options[i].field; 1518 } 1519 } 1520 1521 if (type >= 0) { 1522 if (output[type].fields == 0) { 1523 pr_debug("No fields requested for %s type. " 1524 "Events will not be displayed.\n", event_type(type)); 1525 } 1526 } 1527 1528 out: 1529 free(str); 1530 return rc; 1531 } 1532 1533 /* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */ 1534 static int is_directory(const char *base_path, const struct dirent *dent) 1535 { 1536 char path[PATH_MAX]; 1537 struct stat st; 1538 1539 sprintf(path, "%s/%s", base_path, dent->d_name); 1540 if (stat(path, &st)) 1541 return 0; 1542 1543 return S_ISDIR(st.st_mode); 1544 } 1545 1546 #define for_each_lang(scripts_path, scripts_dir, lang_dirent) \ 1547 while ((lang_dirent = readdir(scripts_dir)) != NULL) \ 1548 if ((lang_dirent->d_type == DT_DIR || \ 1549 (lang_dirent->d_type == DT_UNKNOWN && \ 1550 is_directory(scripts_path, lang_dirent))) && \ 1551 (strcmp(lang_dirent->d_name, ".")) && \ 1552 (strcmp(lang_dirent->d_name, ".."))) 1553 1554 #define for_each_script(lang_path, lang_dir, script_dirent) \ 1555 while ((script_dirent = readdir(lang_dir)) != NULL) \ 1556 if (script_dirent->d_type != DT_DIR && \ 1557 (script_dirent->d_type != DT_UNKNOWN || \ 1558 !is_directory(lang_path, script_dirent))) 1559 1560 1561 #define RECORD_SUFFIX "-record" 1562 #define REPORT_SUFFIX "-report" 1563 1564 struct script_desc { 1565 struct list_head node; 1566 char *name; 1567 char *half_liner; 1568 char *args; 1569 }; 1570 1571 static LIST_HEAD(script_descs); 1572 1573 static struct script_desc *script_desc__new(const char *name) 1574 { 1575 struct script_desc *s = zalloc(sizeof(*s)); 1576 1577 if (s != NULL && name) 1578 s->name = strdup(name); 1579 1580 return s; 1581 } 1582 1583 static void script_desc__delete(struct script_desc *s) 1584 { 1585 zfree(&s->name); 1586 zfree(&s->half_liner); 1587 zfree(&s->args); 1588 free(s); 1589 } 1590 1591 static void script_desc__add(struct script_desc *s) 1592 { 1593 list_add_tail(&s->node, &script_descs); 1594 } 1595 1596 static struct script_desc *script_desc__find(const char *name) 1597 { 1598 struct script_desc *s; 1599 1600 list_for_each_entry(s, &script_descs, node) 1601 if (strcasecmp(s->name, name) == 0) 1602 return s; 1603 return NULL; 1604 } 1605 1606 static struct script_desc *script_desc__findnew(const char *name) 1607 { 1608 struct script_desc *s = script_desc__find(name); 1609 1610 if (s) 1611 return s; 1612 1613 s = script_desc__new(name); 1614 if (!s) 1615 goto out_delete_desc; 1616 1617 script_desc__add(s); 1618 1619 return s; 1620 1621 out_delete_desc: 1622 script_desc__delete(s); 1623 1624 return NULL; 1625 } 1626 1627 static const char *ends_with(const char *str, const char *suffix) 1628 { 1629 size_t suffix_len = strlen(suffix); 1630 const char *p = str; 1631 1632 if (strlen(str) > suffix_len) { 1633 p = str + strlen(str) - suffix_len; 1634 if (!strncmp(p, suffix, suffix_len)) 1635 return p; 1636 } 1637 1638 return NULL; 1639 } 1640 1641 static int read_script_info(struct script_desc *desc, const char *filename) 1642 { 1643 char line[BUFSIZ], *p; 1644 FILE *fp; 1645 1646 fp = fopen(filename, "r"); 1647 if (!fp) 1648 return -1; 1649 1650 while (fgets(line, sizeof(line), fp)) { 1651 p = ltrim(line); 1652 if (strlen(p) == 0) 1653 continue; 1654 if (*p != '#') 1655 continue; 1656 p++; 1657 if (strlen(p) && *p == '!') 1658 continue; 1659 1660 p = ltrim(p); 1661 if (strlen(p) && p[strlen(p) - 1] == '\n') 1662 p[strlen(p) - 1] = '\0'; 1663 1664 if (!strncmp(p, "description:", strlen("description:"))) { 1665 p += strlen("description:"); 1666 desc->half_liner = strdup(ltrim(p)); 1667 continue; 1668 } 1669 1670 if (!strncmp(p, "args:", strlen("args:"))) { 1671 p += strlen("args:"); 1672 desc->args = strdup(ltrim(p)); 1673 continue; 1674 } 1675 } 1676 1677 fclose(fp); 1678 1679 return 0; 1680 } 1681 1682 static char *get_script_root(struct dirent *script_dirent, const char *suffix) 1683 { 1684 char *script_root, *str; 1685 1686 script_root = strdup(script_dirent->d_name); 1687 if (!script_root) 1688 return NULL; 1689 1690 str = (char *)ends_with(script_root, suffix); 1691 if (!str) { 1692 free(script_root); 1693 return NULL; 1694 } 1695 1696 *str = '\0'; 1697 return script_root; 1698 } 1699 1700 static int list_available_scripts(const struct option *opt __maybe_unused, 1701 const char *s __maybe_unused, 1702 int unset __maybe_unused) 1703 { 1704 struct dirent *script_dirent, *lang_dirent; 1705 char scripts_path[MAXPATHLEN]; 1706 DIR *scripts_dir, *lang_dir; 1707 char script_path[MAXPATHLEN]; 1708 char lang_path[MAXPATHLEN]; 1709 struct script_desc *desc; 1710 char first_half[BUFSIZ]; 1711 char *script_root; 1712 1713 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); 1714 1715 scripts_dir = opendir(scripts_path); 1716 if (!scripts_dir) { 1717 fprintf(stdout, 1718 "open(%s) failed.\n" 1719 "Check \"PERF_EXEC_PATH\" env to set scripts dir.\n", 1720 scripts_path); 1721 exit(-1); 1722 } 1723 1724 for_each_lang(scripts_path, scripts_dir, lang_dirent) { 1725 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 1726 lang_dirent->d_name); 1727 lang_dir = opendir(lang_path); 1728 if (!lang_dir) 1729 continue; 1730 1731 for_each_script(lang_path, lang_dir, script_dirent) { 1732 script_root = get_script_root(script_dirent, REPORT_SUFFIX); 1733 if (script_root) { 1734 desc = script_desc__findnew(script_root); 1735 snprintf(script_path, MAXPATHLEN, "%s/%s", 1736 lang_path, script_dirent->d_name); 1737 read_script_info(desc, script_path); 1738 free(script_root); 1739 } 1740 } 1741 } 1742 1743 fprintf(stdout, "List of available trace scripts:\n"); 1744 list_for_each_entry(desc, &script_descs, node) { 1745 sprintf(first_half, "%s %s", desc->name, 1746 desc->args ? desc->args : ""); 1747 fprintf(stdout, " %-36s %s\n", first_half, 1748 desc->half_liner ? desc->half_liner : ""); 1749 } 1750 1751 exit(0); 1752 } 1753 1754 /* 1755 * Some scripts specify the required events in their "xxx-record" file, 1756 * this function will check if the events in perf.data match those 1757 * mentioned in the "xxx-record". 1758 * 1759 * Fixme: All existing "xxx-record" are all in good formats "-e event ", 1760 * which is covered well now. And new parsing code should be added to 1761 * cover the future complexing formats like event groups etc. 1762 */ 1763 static int check_ev_match(char *dir_name, char *scriptname, 1764 struct perf_session *session) 1765 { 1766 char filename[MAXPATHLEN], evname[128]; 1767 char line[BUFSIZ], *p; 1768 struct perf_evsel *pos; 1769 int match, len; 1770 FILE *fp; 1771 1772 sprintf(filename, "%s/bin/%s-record", dir_name, scriptname); 1773 1774 fp = fopen(filename, "r"); 1775 if (!fp) 1776 return -1; 1777 1778 while (fgets(line, sizeof(line), fp)) { 1779 p = ltrim(line); 1780 if (*p == '#') 1781 continue; 1782 1783 while (strlen(p)) { 1784 p = strstr(p, "-e"); 1785 if (!p) 1786 break; 1787 1788 p += 2; 1789 p = ltrim(p); 1790 len = strcspn(p, " \t"); 1791 if (!len) 1792 break; 1793 1794 snprintf(evname, len + 1, "%s", p); 1795 1796 match = 0; 1797 evlist__for_each_entry(session->evlist, pos) { 1798 if (!strcmp(perf_evsel__name(pos), evname)) { 1799 match = 1; 1800 break; 1801 } 1802 } 1803 1804 if (!match) { 1805 fclose(fp); 1806 return -1; 1807 } 1808 } 1809 } 1810 1811 fclose(fp); 1812 return 0; 1813 } 1814 1815 /* 1816 * Return -1 if none is found, otherwise the actual scripts number. 1817 * 1818 * Currently the only user of this function is the script browser, which 1819 * will list all statically runnable scripts, select one, execute it and 1820 * show the output in a perf browser. 1821 */ 1822 int find_scripts(char **scripts_array, char **scripts_path_array) 1823 { 1824 struct dirent *script_dirent, *lang_dirent; 1825 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; 1826 DIR *scripts_dir, *lang_dir; 1827 struct perf_session *session; 1828 struct perf_data_file file = { 1829 .path = input_name, 1830 .mode = PERF_DATA_MODE_READ, 1831 }; 1832 char *temp; 1833 int i = 0; 1834 1835 session = perf_session__new(&file, false, NULL); 1836 if (!session) 1837 return -1; 1838 1839 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); 1840 1841 scripts_dir = opendir(scripts_path); 1842 if (!scripts_dir) { 1843 perf_session__delete(session); 1844 return -1; 1845 } 1846 1847 for_each_lang(scripts_path, scripts_dir, lang_dirent) { 1848 snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, 1849 lang_dirent->d_name); 1850 #ifdef NO_LIBPERL 1851 if (strstr(lang_path, "perl")) 1852 continue; 1853 #endif 1854 #ifdef NO_LIBPYTHON 1855 if (strstr(lang_path, "python")) 1856 continue; 1857 #endif 1858 1859 lang_dir = opendir(lang_path); 1860 if (!lang_dir) 1861 continue; 1862 1863 for_each_script(lang_path, lang_dir, script_dirent) { 1864 /* Skip those real time scripts: xxxtop.p[yl] */ 1865 if (strstr(script_dirent->d_name, "top.")) 1866 continue; 1867 sprintf(scripts_path_array[i], "%s/%s", lang_path, 1868 script_dirent->d_name); 1869 temp = strchr(script_dirent->d_name, '.'); 1870 snprintf(scripts_array[i], 1871 (temp - script_dirent->d_name) + 1, 1872 "%s", script_dirent->d_name); 1873 1874 if (check_ev_match(lang_path, 1875 scripts_array[i], session)) 1876 continue; 1877 1878 i++; 1879 } 1880 closedir(lang_dir); 1881 } 1882 1883 closedir(scripts_dir); 1884 perf_session__delete(session); 1885 return i; 1886 } 1887 1888 static char *get_script_path(const char *script_root, const char *suffix) 1889 { 1890 struct dirent *script_dirent, *lang_dirent; 1891 char scripts_path[MAXPATHLEN]; 1892 char script_path[MAXPATHLEN]; 1893 DIR *scripts_dir, *lang_dir; 1894 char lang_path[MAXPATHLEN]; 1895 char *__script_root; 1896 1897 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); 1898 1899 scripts_dir = opendir(scripts_path); 1900 if (!scripts_dir) 1901 return NULL; 1902 1903 for_each_lang(scripts_path, scripts_dir, lang_dirent) { 1904 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 1905 lang_dirent->d_name); 1906 lang_dir = opendir(lang_path); 1907 if (!lang_dir) 1908 continue; 1909 1910 for_each_script(lang_path, lang_dir, script_dirent) { 1911 __script_root = get_script_root(script_dirent, suffix); 1912 if (__script_root && !strcmp(script_root, __script_root)) { 1913 free(__script_root); 1914 closedir(lang_dir); 1915 closedir(scripts_dir); 1916 snprintf(script_path, MAXPATHLEN, "%s/%s", 1917 lang_path, script_dirent->d_name); 1918 return strdup(script_path); 1919 } 1920 free(__script_root); 1921 } 1922 closedir(lang_dir); 1923 } 1924 closedir(scripts_dir); 1925 1926 return NULL; 1927 } 1928 1929 static bool is_top_script(const char *script_path) 1930 { 1931 return ends_with(script_path, "top") == NULL ? false : true; 1932 } 1933 1934 static int has_required_arg(char *script_path) 1935 { 1936 struct script_desc *desc; 1937 int n_args = 0; 1938 char *p; 1939 1940 desc = script_desc__new(NULL); 1941 1942 if (read_script_info(desc, script_path)) 1943 goto out; 1944 1945 if (!desc->args) 1946 goto out; 1947 1948 for (p = desc->args; *p; p++) 1949 if (*p == '<') 1950 n_args++; 1951 out: 1952 script_desc__delete(desc); 1953 1954 return n_args; 1955 } 1956 1957 static int have_cmd(int argc, const char **argv) 1958 { 1959 char **__argv = malloc(sizeof(const char *) * argc); 1960 1961 if (!__argv) { 1962 pr_err("malloc failed\n"); 1963 return -1; 1964 } 1965 1966 memcpy(__argv, argv, sizeof(const char *) * argc); 1967 argc = parse_options(argc, (const char **)__argv, record_options, 1968 NULL, PARSE_OPT_STOP_AT_NON_OPTION); 1969 free(__argv); 1970 1971 system_wide = (argc == 0); 1972 1973 return 0; 1974 } 1975 1976 static void script__setup_sample_type(struct perf_script *script) 1977 { 1978 struct perf_session *session = script->session; 1979 u64 sample_type = perf_evlist__combined_sample_type(session->evlist); 1980 1981 if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) { 1982 if ((sample_type & PERF_SAMPLE_REGS_USER) && 1983 (sample_type & PERF_SAMPLE_STACK_USER)) 1984 callchain_param.record_mode = CALLCHAIN_DWARF; 1985 else if (sample_type & PERF_SAMPLE_BRANCH_STACK) 1986 callchain_param.record_mode = CALLCHAIN_LBR; 1987 else 1988 callchain_param.record_mode = CALLCHAIN_FP; 1989 } 1990 } 1991 1992 static int process_stat_round_event(struct perf_tool *tool __maybe_unused, 1993 union perf_event *event, 1994 struct perf_session *session) 1995 { 1996 struct stat_round_event *round = &event->stat_round; 1997 struct perf_evsel *counter; 1998 1999 evlist__for_each_entry(session->evlist, counter) { 2000 perf_stat_process_counter(&stat_config, counter); 2001 process_stat(counter, round->time); 2002 } 2003 2004 process_stat_interval(round->time); 2005 return 0; 2006 } 2007 2008 static int process_stat_config_event(struct perf_tool *tool __maybe_unused, 2009 union perf_event *event, 2010 struct perf_session *session __maybe_unused) 2011 { 2012 perf_event__read_stat_config(&stat_config, &event->stat_config); 2013 return 0; 2014 } 2015 2016 static int set_maps(struct perf_script *script) 2017 { 2018 struct perf_evlist *evlist = script->session->evlist; 2019 2020 if (!script->cpus || !script->threads) 2021 return 0; 2022 2023 if (WARN_ONCE(script->allocated, "stats double allocation\n")) 2024 return -EINVAL; 2025 2026 perf_evlist__set_maps(evlist, script->cpus, script->threads); 2027 2028 if (perf_evlist__alloc_stats(evlist, true)) 2029 return -ENOMEM; 2030 2031 script->allocated = true; 2032 return 0; 2033 } 2034 2035 static 2036 int process_thread_map_event(struct perf_tool *tool, 2037 union perf_event *event, 2038 struct perf_session *session __maybe_unused) 2039 { 2040 struct perf_script *script = container_of(tool, struct perf_script, tool); 2041 2042 if (script->threads) { 2043 pr_warning("Extra thread map event, ignoring.\n"); 2044 return 0; 2045 } 2046 2047 script->threads = thread_map__new_event(&event->thread_map); 2048 if (!script->threads) 2049 return -ENOMEM; 2050 2051 return set_maps(script); 2052 } 2053 2054 static 2055 int process_cpu_map_event(struct perf_tool *tool __maybe_unused, 2056 union perf_event *event, 2057 struct perf_session *session __maybe_unused) 2058 { 2059 struct perf_script *script = container_of(tool, struct perf_script, tool); 2060 2061 if (script->cpus) { 2062 pr_warning("Extra cpu map event, ignoring.\n"); 2063 return 0; 2064 } 2065 2066 script->cpus = cpu_map__new_data(&event->cpu_map.data); 2067 if (!script->cpus) 2068 return -ENOMEM; 2069 2070 return set_maps(script); 2071 } 2072 2073 int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) 2074 { 2075 bool show_full_info = false; 2076 bool header = false; 2077 bool header_only = false; 2078 bool script_started = false; 2079 char *rec_script_path = NULL; 2080 char *rep_script_path = NULL; 2081 struct perf_session *session; 2082 struct itrace_synth_opts itrace_synth_opts = { .set = false, }; 2083 char *script_path = NULL; 2084 const char **__argv; 2085 int i, j, err = 0; 2086 struct perf_script script = { 2087 .tool = { 2088 .sample = process_sample_event, 2089 .mmap = perf_event__process_mmap, 2090 .mmap2 = perf_event__process_mmap2, 2091 .comm = perf_event__process_comm, 2092 .exit = perf_event__process_exit, 2093 .fork = perf_event__process_fork, 2094 .attr = process_attr, 2095 .event_update = perf_event__process_event_update, 2096 .tracing_data = perf_event__process_tracing_data, 2097 .build_id = perf_event__process_build_id, 2098 .id_index = perf_event__process_id_index, 2099 .auxtrace_info = perf_event__process_auxtrace_info, 2100 .auxtrace = perf_event__process_auxtrace, 2101 .auxtrace_error = perf_event__process_auxtrace_error, 2102 .stat = perf_event__process_stat_event, 2103 .stat_round = process_stat_round_event, 2104 .stat_config = process_stat_config_event, 2105 .thread_map = process_thread_map_event, 2106 .cpu_map = process_cpu_map_event, 2107 .ordered_events = true, 2108 .ordering_requires_timestamps = true, 2109 }, 2110 }; 2111 struct perf_data_file file = { 2112 .mode = PERF_DATA_MODE_READ, 2113 }; 2114 const struct option options[] = { 2115 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 2116 "dump raw trace in ASCII"), 2117 OPT_INCR('v', "verbose", &verbose, 2118 "be more verbose (show symbol address, etc)"), 2119 OPT_BOOLEAN('L', "Latency", &latency_format, 2120 "show latency attributes (irqs/preemption disabled, etc)"), 2121 OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts", 2122 list_available_scripts), 2123 OPT_CALLBACK('s', "script", NULL, "name", 2124 "script file name (lang:script name, script name, or *)", 2125 parse_scriptname), 2126 OPT_STRING('g', "gen-script", &generate_script_lang, "lang", 2127 "generate perf-script.xx script in specified language"), 2128 OPT_STRING('i', "input", &input_name, "file", "input file name"), 2129 OPT_BOOLEAN('d', "debug-mode", &debug_mode, 2130 "do various checks like samples ordering and lost events"), 2131 OPT_BOOLEAN(0, "header", &header, "Show data header."), 2132 OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."), 2133 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 2134 "file", "vmlinux pathname"), 2135 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, 2136 "file", "kallsyms pathname"), 2137 OPT_BOOLEAN('G', "hide-call-graph", &no_callchain, 2138 "When printing symbols do not display call chain"), 2139 OPT_CALLBACK(0, "symfs", NULL, "directory", 2140 "Look for files with symbols relative to this directory", 2141 symbol__config_symfs), 2142 OPT_CALLBACK('F', "fields", NULL, "str", 2143 "comma separated output fields prepend with 'type:'. " 2144 "Valid types: hw,sw,trace,raw. " 2145 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 2146 "addr,symoff,period,iregs,brstack,brstacksym,flags," 2147 "bpf-output,callindent,insn,insnlen", parse_output_fields), 2148 OPT_BOOLEAN('a', "all-cpus", &system_wide, 2149 "system-wide collection from all CPUs"), 2150 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", 2151 "only consider these symbols"), 2152 OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 2153 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", 2154 "only display events for these comms"), 2155 OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]", 2156 "only consider symbols in these pids"), 2157 OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]", 2158 "only consider symbols in these tids"), 2159 OPT_UINTEGER(0, "max-stack", &scripting_max_stack, 2160 "Set the maximum stack depth when parsing the callchain, " 2161 "anything beyond the specified depth will be ignored. " 2162 "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)), 2163 OPT_BOOLEAN('I', "show-info", &show_full_info, 2164 "display extended information from perf.data file"), 2165 OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path, 2166 "Show the path of [kernel.kallsyms]"), 2167 OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events, 2168 "Show the fork/comm/exit events"), 2169 OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events, 2170 "Show the mmap events"), 2171 OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events, 2172 "Show context switch events (if recorded)"), 2173 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), 2174 OPT_BOOLEAN(0, "ns", &nanosecs, 2175 "Use 9 decimal places when displaying time"), 2176 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", 2177 "Instruction Tracing options", 2178 itrace_parse_synth_opts), 2179 OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename, 2180 "Show full source file name path for source lines"), 2181 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, 2182 "Enable symbol demangling"), 2183 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, 2184 "Enable kernel symbol demangling"), 2185 2186 OPT_END() 2187 }; 2188 const char * const script_subcommands[] = { "record", "report", NULL }; 2189 const char *script_usage[] = { 2190 "perf script [<options>]", 2191 "perf script [<options>] record <script> [<record-options>] <command>", 2192 "perf script [<options>] report <script> [script-args]", 2193 "perf script [<options>] <script> [<record-options>] <command>", 2194 "perf script [<options>] <top-script> [script-args]", 2195 NULL 2196 }; 2197 2198 setup_scripting(); 2199 2200 argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage, 2201 PARSE_OPT_STOP_AT_NON_OPTION); 2202 2203 file.path = input_name; 2204 2205 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { 2206 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); 2207 if (!rec_script_path) 2208 return cmd_record(argc, argv, NULL); 2209 } 2210 2211 if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) { 2212 rep_script_path = get_script_path(argv[1], REPORT_SUFFIX); 2213 if (!rep_script_path) { 2214 fprintf(stderr, 2215 "Please specify a valid report script" 2216 "(see 'perf script -l' for listing)\n"); 2217 return -1; 2218 } 2219 } 2220 2221 if (itrace_synth_opts.callchain && 2222 itrace_synth_opts.callchain_sz > scripting_max_stack) 2223 scripting_max_stack = itrace_synth_opts.callchain_sz; 2224 2225 /* make sure PERF_EXEC_PATH is set for scripts */ 2226 set_argv_exec_path(get_argv_exec_path()); 2227 2228 if (argc && !script_name && !rec_script_path && !rep_script_path) { 2229 int live_pipe[2]; 2230 int rep_args; 2231 pid_t pid; 2232 2233 rec_script_path = get_script_path(argv[0], RECORD_SUFFIX); 2234 rep_script_path = get_script_path(argv[0], REPORT_SUFFIX); 2235 2236 if (!rec_script_path && !rep_script_path) { 2237 usage_with_options_msg(script_usage, options, 2238 "Couldn't find script `%s'\n\n See perf" 2239 " script -l for available scripts.\n", argv[0]); 2240 } 2241 2242 if (is_top_script(argv[0])) { 2243 rep_args = argc - 1; 2244 } else { 2245 int rec_args; 2246 2247 rep_args = has_required_arg(rep_script_path); 2248 rec_args = (argc - 1) - rep_args; 2249 if (rec_args < 0) { 2250 usage_with_options_msg(script_usage, options, 2251 "`%s' script requires options." 2252 "\n\n See perf script -l for available " 2253 "scripts and options.\n", argv[0]); 2254 } 2255 } 2256 2257 if (pipe(live_pipe) < 0) { 2258 perror("failed to create pipe"); 2259 return -1; 2260 } 2261 2262 pid = fork(); 2263 if (pid < 0) { 2264 perror("failed to fork"); 2265 return -1; 2266 } 2267 2268 if (!pid) { 2269 j = 0; 2270 2271 dup2(live_pipe[1], 1); 2272 close(live_pipe[0]); 2273 2274 if (is_top_script(argv[0])) { 2275 system_wide = true; 2276 } else if (!system_wide) { 2277 if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) { 2278 err = -1; 2279 goto out; 2280 } 2281 } 2282 2283 __argv = malloc((argc + 6) * sizeof(const char *)); 2284 if (!__argv) { 2285 pr_err("malloc failed\n"); 2286 err = -ENOMEM; 2287 goto out; 2288 } 2289 2290 __argv[j++] = "/bin/sh"; 2291 __argv[j++] = rec_script_path; 2292 if (system_wide) 2293 __argv[j++] = "-a"; 2294 __argv[j++] = "-q"; 2295 __argv[j++] = "-o"; 2296 __argv[j++] = "-"; 2297 for (i = rep_args + 1; i < argc; i++) 2298 __argv[j++] = argv[i]; 2299 __argv[j++] = NULL; 2300 2301 execvp("/bin/sh", (char **)__argv); 2302 free(__argv); 2303 exit(-1); 2304 } 2305 2306 dup2(live_pipe[0], 0); 2307 close(live_pipe[1]); 2308 2309 __argv = malloc((argc + 4) * sizeof(const char *)); 2310 if (!__argv) { 2311 pr_err("malloc failed\n"); 2312 err = -ENOMEM; 2313 goto out; 2314 } 2315 2316 j = 0; 2317 __argv[j++] = "/bin/sh"; 2318 __argv[j++] = rep_script_path; 2319 for (i = 1; i < rep_args + 1; i++) 2320 __argv[j++] = argv[i]; 2321 __argv[j++] = "-i"; 2322 __argv[j++] = "-"; 2323 __argv[j++] = NULL; 2324 2325 execvp("/bin/sh", (char **)__argv); 2326 free(__argv); 2327 exit(-1); 2328 } 2329 2330 if (rec_script_path) 2331 script_path = rec_script_path; 2332 if (rep_script_path) 2333 script_path = rep_script_path; 2334 2335 if (script_path) { 2336 j = 0; 2337 2338 if (!rec_script_path) 2339 system_wide = false; 2340 else if (!system_wide) { 2341 if (have_cmd(argc - 1, &argv[1]) != 0) { 2342 err = -1; 2343 goto out; 2344 } 2345 } 2346 2347 __argv = malloc((argc + 2) * sizeof(const char *)); 2348 if (!__argv) { 2349 pr_err("malloc failed\n"); 2350 err = -ENOMEM; 2351 goto out; 2352 } 2353 2354 __argv[j++] = "/bin/sh"; 2355 __argv[j++] = script_path; 2356 if (system_wide) 2357 __argv[j++] = "-a"; 2358 for (i = 2; i < argc; i++) 2359 __argv[j++] = argv[i]; 2360 __argv[j++] = NULL; 2361 2362 execvp("/bin/sh", (char **)__argv); 2363 free(__argv); 2364 exit(-1); 2365 } 2366 2367 if (!script_name) 2368 setup_pager(); 2369 2370 session = perf_session__new(&file, false, &script.tool); 2371 if (session == NULL) 2372 return -1; 2373 2374 if (header || header_only) { 2375 perf_session__fprintf_info(session, stdout, show_full_info); 2376 if (header_only) 2377 goto out_delete; 2378 } 2379 2380 if (symbol__init(&session->header.env) < 0) 2381 goto out_delete; 2382 2383 script.session = session; 2384 script__setup_sample_type(&script); 2385 2386 if (output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT) 2387 itrace_synth_opts.thread_stack = true; 2388 2389 session->itrace_synth_opts = &itrace_synth_opts; 2390 2391 if (cpu_list) { 2392 err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap); 2393 if (err < 0) 2394 goto out_delete; 2395 } 2396 2397 if (!no_callchain) 2398 symbol_conf.use_callchain = true; 2399 else 2400 symbol_conf.use_callchain = false; 2401 2402 if (session->tevent.pevent && 2403 pevent_set_function_resolver(session->tevent.pevent, 2404 machine__resolve_kernel_addr, 2405 &session->machines.host) < 0) { 2406 pr_err("%s: failed to set libtraceevent function resolver\n", __func__); 2407 return -1; 2408 } 2409 2410 if (generate_script_lang) { 2411 struct stat perf_stat; 2412 int input; 2413 2414 if (output_set_by_user()) { 2415 fprintf(stderr, 2416 "custom fields not supported for generated scripts"); 2417 err = -EINVAL; 2418 goto out_delete; 2419 } 2420 2421 input = open(file.path, O_RDONLY); /* input_name */ 2422 if (input < 0) { 2423 err = -errno; 2424 perror("failed to open file"); 2425 goto out_delete; 2426 } 2427 2428 err = fstat(input, &perf_stat); 2429 if (err < 0) { 2430 perror("failed to stat file"); 2431 goto out_delete; 2432 } 2433 2434 if (!perf_stat.st_size) { 2435 fprintf(stderr, "zero-sized file, nothing to do!\n"); 2436 goto out_delete; 2437 } 2438 2439 scripting_ops = script_spec__lookup(generate_script_lang); 2440 if (!scripting_ops) { 2441 fprintf(stderr, "invalid language specifier"); 2442 err = -ENOENT; 2443 goto out_delete; 2444 } 2445 2446 err = scripting_ops->generate_script(session->tevent.pevent, 2447 "perf-script"); 2448 goto out_delete; 2449 } 2450 2451 if (script_name) { 2452 err = scripting_ops->start_script(script_name, argc, argv); 2453 if (err) 2454 goto out_delete; 2455 pr_debug("perf script started with script %s\n\n", script_name); 2456 script_started = true; 2457 } 2458 2459 2460 err = perf_session__check_output_opt(session); 2461 if (err < 0) 2462 goto out_delete; 2463 2464 err = __cmd_script(&script); 2465 2466 flush_scripting(); 2467 2468 out_delete: 2469 perf_evlist__free_stats(session->evlist); 2470 perf_session__delete(session); 2471 2472 if (script_started) 2473 cleanup_scripting(); 2474 out: 2475 return err; 2476 } 2477