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