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