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