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