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