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