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 goto out_put; 611 612 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) 613 goto out_put; 614 615 scripting_ops->process_event(event, sample, evsel, &al); 616 out_put: 617 addr_location__put(&al); 618 return 0; 619 } 620 621 struct perf_script { 622 struct perf_tool tool; 623 struct perf_session *session; 624 bool show_task_events; 625 bool show_mmap_events; 626 }; 627 628 static int process_attr(struct perf_tool *tool, union perf_event *event, 629 struct perf_evlist **pevlist) 630 { 631 struct perf_script *scr = container_of(tool, struct perf_script, tool); 632 struct perf_evlist *evlist; 633 struct perf_evsel *evsel, *pos; 634 int err; 635 636 err = perf_event__process_attr(tool, event, pevlist); 637 if (err) 638 return err; 639 640 evlist = *pevlist; 641 evsel = perf_evlist__last(*pevlist); 642 643 if (evsel->attr.type >= PERF_TYPE_MAX) 644 return 0; 645 646 evlist__for_each(evlist, pos) { 647 if (pos->attr.type == evsel->attr.type && pos != evsel) 648 return 0; 649 } 650 651 set_print_ip_opts(&evsel->attr); 652 653 return perf_evsel__check_attr(evsel, scr->session); 654 } 655 656 static int process_comm_event(struct perf_tool *tool, 657 union perf_event *event, 658 struct perf_sample *sample, 659 struct machine *machine) 660 { 661 struct thread *thread; 662 struct perf_script *script = container_of(tool, struct perf_script, tool); 663 struct perf_session *session = script->session; 664 struct perf_evsel *evsel = perf_evlist__first(session->evlist); 665 int ret = -1; 666 667 thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid); 668 if (thread == NULL) { 669 pr_debug("problem processing COMM event, skipping it.\n"); 670 return -1; 671 } 672 673 if (perf_event__process_comm(tool, event, sample, machine) < 0) 674 goto out; 675 676 if (!evsel->attr.sample_id_all) { 677 sample->cpu = 0; 678 sample->time = 0; 679 sample->tid = event->comm.tid; 680 sample->pid = event->comm.pid; 681 } 682 print_sample_start(sample, thread, evsel); 683 perf_event__fprintf(event, stdout); 684 ret = 0; 685 out: 686 thread__put(thread); 687 return ret; 688 } 689 690 static int process_fork_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 if (perf_event__process_fork(tool, event, sample, machine) < 0) 701 return -1; 702 703 thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); 704 if (thread == NULL) { 705 pr_debug("problem processing FORK event, skipping it.\n"); 706 return -1; 707 } 708 709 if (!evsel->attr.sample_id_all) { 710 sample->cpu = 0; 711 sample->time = event->fork.time; 712 sample->tid = event->fork.tid; 713 sample->pid = event->fork.pid; 714 } 715 print_sample_start(sample, thread, evsel); 716 perf_event__fprintf(event, stdout); 717 thread__put(thread); 718 719 return 0; 720 } 721 static int process_exit_event(struct perf_tool *tool, 722 union perf_event *event, 723 struct perf_sample *sample, 724 struct machine *machine) 725 { 726 int err = 0; 727 struct thread *thread; 728 struct perf_script *script = container_of(tool, struct perf_script, tool); 729 struct perf_session *session = script->session; 730 struct perf_evsel *evsel = perf_evlist__first(session->evlist); 731 732 thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); 733 if (thread == NULL) { 734 pr_debug("problem processing EXIT event, skipping it.\n"); 735 return -1; 736 } 737 738 if (!evsel->attr.sample_id_all) { 739 sample->cpu = 0; 740 sample->time = 0; 741 sample->tid = event->comm.tid; 742 sample->pid = event->comm.pid; 743 } 744 print_sample_start(sample, thread, evsel); 745 perf_event__fprintf(event, stdout); 746 747 if (perf_event__process_exit(tool, event, sample, machine) < 0) 748 err = -1; 749 750 thread__put(thread); 751 return err; 752 } 753 754 static int process_mmap_event(struct perf_tool *tool, 755 union perf_event *event, 756 struct perf_sample *sample, 757 struct machine *machine) 758 { 759 struct thread *thread; 760 struct perf_script *script = container_of(tool, struct perf_script, tool); 761 struct perf_session *session = script->session; 762 struct perf_evsel *evsel = perf_evlist__first(session->evlist); 763 764 if (perf_event__process_mmap(tool, event, sample, machine) < 0) 765 return -1; 766 767 thread = machine__findnew_thread(machine, event->mmap.pid, event->mmap.tid); 768 if (thread == NULL) { 769 pr_debug("problem processing MMAP event, skipping it.\n"); 770 return -1; 771 } 772 773 if (!evsel->attr.sample_id_all) { 774 sample->cpu = 0; 775 sample->time = 0; 776 sample->tid = event->mmap.tid; 777 sample->pid = event->mmap.pid; 778 } 779 print_sample_start(sample, thread, evsel); 780 perf_event__fprintf(event, stdout); 781 thread__put(thread); 782 return 0; 783 } 784 785 static int process_mmap2_event(struct perf_tool *tool, 786 union perf_event *event, 787 struct perf_sample *sample, 788 struct machine *machine) 789 { 790 struct thread *thread; 791 struct perf_script *script = container_of(tool, struct perf_script, tool); 792 struct perf_session *session = script->session; 793 struct perf_evsel *evsel = perf_evlist__first(session->evlist); 794 795 if (perf_event__process_mmap2(tool, event, sample, machine) < 0) 796 return -1; 797 798 thread = machine__findnew_thread(machine, event->mmap2.pid, event->mmap2.tid); 799 if (thread == NULL) { 800 pr_debug("problem processing MMAP2 event, skipping it.\n"); 801 return -1; 802 } 803 804 if (!evsel->attr.sample_id_all) { 805 sample->cpu = 0; 806 sample->time = 0; 807 sample->tid = event->mmap2.tid; 808 sample->pid = event->mmap2.pid; 809 } 810 print_sample_start(sample, thread, evsel); 811 perf_event__fprintf(event, stdout); 812 thread__put(thread); 813 return 0; 814 } 815 816 static void sig_handler(int sig __maybe_unused) 817 { 818 session_done = 1; 819 } 820 821 static int __cmd_script(struct perf_script *script) 822 { 823 int ret; 824 825 signal(SIGINT, sig_handler); 826 827 /* override event processing functions */ 828 if (script->show_task_events) { 829 script->tool.comm = process_comm_event; 830 script->tool.fork = process_fork_event; 831 script->tool.exit = process_exit_event; 832 } 833 if (script->show_mmap_events) { 834 script->tool.mmap = process_mmap_event; 835 script->tool.mmap2 = process_mmap2_event; 836 } 837 838 ret = perf_session__process_events(script->session); 839 840 if (debug_mode) 841 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 842 843 return ret; 844 } 845 846 struct script_spec { 847 struct list_head node; 848 struct scripting_ops *ops; 849 char spec[0]; 850 }; 851 852 static LIST_HEAD(script_specs); 853 854 static struct script_spec *script_spec__new(const char *spec, 855 struct scripting_ops *ops) 856 { 857 struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1); 858 859 if (s != NULL) { 860 strcpy(s->spec, spec); 861 s->ops = ops; 862 } 863 864 return s; 865 } 866 867 static void script_spec__add(struct script_spec *s) 868 { 869 list_add_tail(&s->node, &script_specs); 870 } 871 872 static struct script_spec *script_spec__find(const char *spec) 873 { 874 struct script_spec *s; 875 876 list_for_each_entry(s, &script_specs, node) 877 if (strcasecmp(s->spec, spec) == 0) 878 return s; 879 return NULL; 880 } 881 882 static struct script_spec *script_spec__findnew(const char *spec, 883 struct scripting_ops *ops) 884 { 885 struct script_spec *s = script_spec__find(spec); 886 887 if (s) 888 return s; 889 890 s = script_spec__new(spec, ops); 891 if (!s) 892 return NULL; 893 894 script_spec__add(s); 895 896 return s; 897 } 898 899 int script_spec_register(const char *spec, struct scripting_ops *ops) 900 { 901 struct script_spec *s; 902 903 s = script_spec__find(spec); 904 if (s) 905 return -1; 906 907 s = script_spec__findnew(spec, ops); 908 if (!s) 909 return -1; 910 911 return 0; 912 } 913 914 static struct scripting_ops *script_spec__lookup(const char *spec) 915 { 916 struct script_spec *s = script_spec__find(spec); 917 if (!s) 918 return NULL; 919 920 return s->ops; 921 } 922 923 static void list_available_languages(void) 924 { 925 struct script_spec *s; 926 927 fprintf(stderr, "\n"); 928 fprintf(stderr, "Scripting language extensions (used in " 929 "perf script -s [spec:]script.[spec]):\n\n"); 930 931 list_for_each_entry(s, &script_specs, node) 932 fprintf(stderr, " %-42s [%s]\n", s->spec, s->ops->name); 933 934 fprintf(stderr, "\n"); 935 } 936 937 static int parse_scriptname(const struct option *opt __maybe_unused, 938 const char *str, int unset __maybe_unused) 939 { 940 char spec[PATH_MAX]; 941 const char *script, *ext; 942 int len; 943 944 if (strcmp(str, "lang") == 0) { 945 list_available_languages(); 946 exit(0); 947 } 948 949 script = strchr(str, ':'); 950 if (script) { 951 len = script - str; 952 if (len >= PATH_MAX) { 953 fprintf(stderr, "invalid language specifier"); 954 return -1; 955 } 956 strncpy(spec, str, len); 957 spec[len] = '\0'; 958 scripting_ops = script_spec__lookup(spec); 959 if (!scripting_ops) { 960 fprintf(stderr, "invalid language specifier"); 961 return -1; 962 } 963 script++; 964 } else { 965 script = str; 966 ext = strrchr(script, '.'); 967 if (!ext) { 968 fprintf(stderr, "invalid script extension"); 969 return -1; 970 } 971 scripting_ops = script_spec__lookup(++ext); 972 if (!scripting_ops) { 973 fprintf(stderr, "invalid script extension"); 974 return -1; 975 } 976 } 977 978 script_name = strdup(script); 979 980 return 0; 981 } 982 983 static int parse_output_fields(const struct option *opt __maybe_unused, 984 const char *arg, int unset __maybe_unused) 985 { 986 char *tok; 987 int i, imax = ARRAY_SIZE(all_output_options); 988 int j; 989 int rc = 0; 990 char *str = strdup(arg); 991 int type = -1; 992 993 if (!str) 994 return -ENOMEM; 995 996 /* first word can state for which event type the user is specifying 997 * the fields. If no type exists, the specified fields apply to all 998 * event types found in the file minus the invalid fields for a type. 999 */ 1000 tok = strchr(str, ':'); 1001 if (tok) { 1002 *tok = '\0'; 1003 tok++; 1004 if (!strcmp(str, "hw")) 1005 type = PERF_TYPE_HARDWARE; 1006 else if (!strcmp(str, "sw")) 1007 type = PERF_TYPE_SOFTWARE; 1008 else if (!strcmp(str, "trace")) 1009 type = PERF_TYPE_TRACEPOINT; 1010 else if (!strcmp(str, "raw")) 1011 type = PERF_TYPE_RAW; 1012 else { 1013 fprintf(stderr, "Invalid event type in field string.\n"); 1014 rc = -EINVAL; 1015 goto out; 1016 } 1017 1018 if (output[type].user_set) 1019 pr_warning("Overriding previous field request for %s events.\n", 1020 event_type(type)); 1021 1022 output[type].fields = 0; 1023 output[type].user_set = true; 1024 output[type].wildcard_set = false; 1025 1026 } else { 1027 tok = str; 1028 if (strlen(str) == 0) { 1029 fprintf(stderr, 1030 "Cannot set fields to 'none' for all event types.\n"); 1031 rc = -EINVAL; 1032 goto out; 1033 } 1034 1035 if (output_set_by_user()) 1036 pr_warning("Overriding previous field request for all events.\n"); 1037 1038 for (j = 0; j < PERF_TYPE_MAX; ++j) { 1039 output[j].fields = 0; 1040 output[j].user_set = true; 1041 output[j].wildcard_set = true; 1042 } 1043 } 1044 1045 for (tok = strtok(tok, ","); tok; tok = strtok(NULL, ",")) { 1046 for (i = 0; i < imax; ++i) { 1047 if (strcmp(tok, all_output_options[i].str) == 0) 1048 break; 1049 } 1050 if (i == imax && strcmp(tok, "flags") == 0) { 1051 print_flags = true; 1052 continue; 1053 } 1054 if (i == imax) { 1055 fprintf(stderr, "Invalid field requested.\n"); 1056 rc = -EINVAL; 1057 goto out; 1058 } 1059 1060 if (type == -1) { 1061 /* add user option to all events types for 1062 * which it is valid 1063 */ 1064 for (j = 0; j < PERF_TYPE_MAX; ++j) { 1065 if (output[j].invalid_fields & all_output_options[i].field) { 1066 pr_warning("\'%s\' not valid for %s events. Ignoring.\n", 1067 all_output_options[i].str, event_type(j)); 1068 } else 1069 output[j].fields |= all_output_options[i].field; 1070 } 1071 } else { 1072 if (output[type].invalid_fields & all_output_options[i].field) { 1073 fprintf(stderr, "\'%s\' not valid for %s events.\n", 1074 all_output_options[i].str, event_type(type)); 1075 1076 rc = -EINVAL; 1077 goto out; 1078 } 1079 output[type].fields |= all_output_options[i].field; 1080 } 1081 } 1082 1083 if (type >= 0) { 1084 if (output[type].fields == 0) { 1085 pr_debug("No fields requested for %s type. " 1086 "Events will not be displayed.\n", event_type(type)); 1087 } 1088 } 1089 1090 out: 1091 free(str); 1092 return rc; 1093 } 1094 1095 /* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */ 1096 static int is_directory(const char *base_path, const struct dirent *dent) 1097 { 1098 char path[PATH_MAX]; 1099 struct stat st; 1100 1101 sprintf(path, "%s/%s", base_path, dent->d_name); 1102 if (stat(path, &st)) 1103 return 0; 1104 1105 return S_ISDIR(st.st_mode); 1106 } 1107 1108 #define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\ 1109 while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ 1110 lang_next) \ 1111 if ((lang_dirent.d_type == DT_DIR || \ 1112 (lang_dirent.d_type == DT_UNKNOWN && \ 1113 is_directory(scripts_path, &lang_dirent))) && \ 1114 (strcmp(lang_dirent.d_name, ".")) && \ 1115 (strcmp(lang_dirent.d_name, ".."))) 1116 1117 #define for_each_script(lang_path, lang_dir, script_dirent, script_next)\ 1118 while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ 1119 script_next) \ 1120 if (script_dirent.d_type != DT_DIR && \ 1121 (script_dirent.d_type != DT_UNKNOWN || \ 1122 !is_directory(lang_path, &script_dirent))) 1123 1124 1125 #define RECORD_SUFFIX "-record" 1126 #define REPORT_SUFFIX "-report" 1127 1128 struct script_desc { 1129 struct list_head node; 1130 char *name; 1131 char *half_liner; 1132 char *args; 1133 }; 1134 1135 static LIST_HEAD(script_descs); 1136 1137 static struct script_desc *script_desc__new(const char *name) 1138 { 1139 struct script_desc *s = zalloc(sizeof(*s)); 1140 1141 if (s != NULL && name) 1142 s->name = strdup(name); 1143 1144 return s; 1145 } 1146 1147 static void script_desc__delete(struct script_desc *s) 1148 { 1149 zfree(&s->name); 1150 zfree(&s->half_liner); 1151 zfree(&s->args); 1152 free(s); 1153 } 1154 1155 static void script_desc__add(struct script_desc *s) 1156 { 1157 list_add_tail(&s->node, &script_descs); 1158 } 1159 1160 static struct script_desc *script_desc__find(const char *name) 1161 { 1162 struct script_desc *s; 1163 1164 list_for_each_entry(s, &script_descs, node) 1165 if (strcasecmp(s->name, name) == 0) 1166 return s; 1167 return NULL; 1168 } 1169 1170 static struct script_desc *script_desc__findnew(const char *name) 1171 { 1172 struct script_desc *s = script_desc__find(name); 1173 1174 if (s) 1175 return s; 1176 1177 s = script_desc__new(name); 1178 if (!s) 1179 goto out_delete_desc; 1180 1181 script_desc__add(s); 1182 1183 return s; 1184 1185 out_delete_desc: 1186 script_desc__delete(s); 1187 1188 return NULL; 1189 } 1190 1191 static const char *ends_with(const char *str, const char *suffix) 1192 { 1193 size_t suffix_len = strlen(suffix); 1194 const char *p = str; 1195 1196 if (strlen(str) > suffix_len) { 1197 p = str + strlen(str) - suffix_len; 1198 if (!strncmp(p, suffix, suffix_len)) 1199 return p; 1200 } 1201 1202 return NULL; 1203 } 1204 1205 static int read_script_info(struct script_desc *desc, const char *filename) 1206 { 1207 char line[BUFSIZ], *p; 1208 FILE *fp; 1209 1210 fp = fopen(filename, "r"); 1211 if (!fp) 1212 return -1; 1213 1214 while (fgets(line, sizeof(line), fp)) { 1215 p = ltrim(line); 1216 if (strlen(p) == 0) 1217 continue; 1218 if (*p != '#') 1219 continue; 1220 p++; 1221 if (strlen(p) && *p == '!') 1222 continue; 1223 1224 p = ltrim(p); 1225 if (strlen(p) && p[strlen(p) - 1] == '\n') 1226 p[strlen(p) - 1] = '\0'; 1227 1228 if (!strncmp(p, "description:", strlen("description:"))) { 1229 p += strlen("description:"); 1230 desc->half_liner = strdup(ltrim(p)); 1231 continue; 1232 } 1233 1234 if (!strncmp(p, "args:", strlen("args:"))) { 1235 p += strlen("args:"); 1236 desc->args = strdup(ltrim(p)); 1237 continue; 1238 } 1239 } 1240 1241 fclose(fp); 1242 1243 return 0; 1244 } 1245 1246 static char *get_script_root(struct dirent *script_dirent, const char *suffix) 1247 { 1248 char *script_root, *str; 1249 1250 script_root = strdup(script_dirent->d_name); 1251 if (!script_root) 1252 return NULL; 1253 1254 str = (char *)ends_with(script_root, suffix); 1255 if (!str) { 1256 free(script_root); 1257 return NULL; 1258 } 1259 1260 *str = '\0'; 1261 return script_root; 1262 } 1263 1264 static int list_available_scripts(const struct option *opt __maybe_unused, 1265 const char *s __maybe_unused, 1266 int unset __maybe_unused) 1267 { 1268 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 1269 char scripts_path[MAXPATHLEN]; 1270 DIR *scripts_dir, *lang_dir; 1271 char script_path[MAXPATHLEN]; 1272 char lang_path[MAXPATHLEN]; 1273 struct script_desc *desc; 1274 char first_half[BUFSIZ]; 1275 char *script_root; 1276 1277 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); 1278 1279 scripts_dir = opendir(scripts_path); 1280 if (!scripts_dir) 1281 return -1; 1282 1283 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { 1284 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 1285 lang_dirent.d_name); 1286 lang_dir = opendir(lang_path); 1287 if (!lang_dir) 1288 continue; 1289 1290 for_each_script(lang_path, lang_dir, script_dirent, script_next) { 1291 script_root = get_script_root(&script_dirent, REPORT_SUFFIX); 1292 if (script_root) { 1293 desc = script_desc__findnew(script_root); 1294 snprintf(script_path, MAXPATHLEN, "%s/%s", 1295 lang_path, script_dirent.d_name); 1296 read_script_info(desc, script_path); 1297 free(script_root); 1298 } 1299 } 1300 } 1301 1302 fprintf(stdout, "List of available trace scripts:\n"); 1303 list_for_each_entry(desc, &script_descs, node) { 1304 sprintf(first_half, "%s %s", desc->name, 1305 desc->args ? desc->args : ""); 1306 fprintf(stdout, " %-36s %s\n", first_half, 1307 desc->half_liner ? desc->half_liner : ""); 1308 } 1309 1310 exit(0); 1311 } 1312 1313 /* 1314 * Some scripts specify the required events in their "xxx-record" file, 1315 * this function will check if the events in perf.data match those 1316 * mentioned in the "xxx-record". 1317 * 1318 * Fixme: All existing "xxx-record" are all in good formats "-e event ", 1319 * which is covered well now. And new parsing code should be added to 1320 * cover the future complexing formats like event groups etc. 1321 */ 1322 static int check_ev_match(char *dir_name, char *scriptname, 1323 struct perf_session *session) 1324 { 1325 char filename[MAXPATHLEN], evname[128]; 1326 char line[BUFSIZ], *p; 1327 struct perf_evsel *pos; 1328 int match, len; 1329 FILE *fp; 1330 1331 sprintf(filename, "%s/bin/%s-record", dir_name, scriptname); 1332 1333 fp = fopen(filename, "r"); 1334 if (!fp) 1335 return -1; 1336 1337 while (fgets(line, sizeof(line), fp)) { 1338 p = ltrim(line); 1339 if (*p == '#') 1340 continue; 1341 1342 while (strlen(p)) { 1343 p = strstr(p, "-e"); 1344 if (!p) 1345 break; 1346 1347 p += 2; 1348 p = ltrim(p); 1349 len = strcspn(p, " \t"); 1350 if (!len) 1351 break; 1352 1353 snprintf(evname, len + 1, "%s", p); 1354 1355 match = 0; 1356 evlist__for_each(session->evlist, pos) { 1357 if (!strcmp(perf_evsel__name(pos), evname)) { 1358 match = 1; 1359 break; 1360 } 1361 } 1362 1363 if (!match) { 1364 fclose(fp); 1365 return -1; 1366 } 1367 } 1368 } 1369 1370 fclose(fp); 1371 return 0; 1372 } 1373 1374 /* 1375 * Return -1 if none is found, otherwise the actual scripts number. 1376 * 1377 * Currently the only user of this function is the script browser, which 1378 * will list all statically runnable scripts, select one, execute it and 1379 * show the output in a perf browser. 1380 */ 1381 int find_scripts(char **scripts_array, char **scripts_path_array) 1382 { 1383 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 1384 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; 1385 DIR *scripts_dir, *lang_dir; 1386 struct perf_session *session; 1387 struct perf_data_file file = { 1388 .path = input_name, 1389 .mode = PERF_DATA_MODE_READ, 1390 }; 1391 char *temp; 1392 int i = 0; 1393 1394 session = perf_session__new(&file, false, NULL); 1395 if (!session) 1396 return -1; 1397 1398 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); 1399 1400 scripts_dir = opendir(scripts_path); 1401 if (!scripts_dir) { 1402 perf_session__delete(session); 1403 return -1; 1404 } 1405 1406 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { 1407 snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, 1408 lang_dirent.d_name); 1409 #ifdef NO_LIBPERL 1410 if (strstr(lang_path, "perl")) 1411 continue; 1412 #endif 1413 #ifdef NO_LIBPYTHON 1414 if (strstr(lang_path, "python")) 1415 continue; 1416 #endif 1417 1418 lang_dir = opendir(lang_path); 1419 if (!lang_dir) 1420 continue; 1421 1422 for_each_script(lang_path, lang_dir, script_dirent, script_next) { 1423 /* Skip those real time scripts: xxxtop.p[yl] */ 1424 if (strstr(script_dirent.d_name, "top.")) 1425 continue; 1426 sprintf(scripts_path_array[i], "%s/%s", lang_path, 1427 script_dirent.d_name); 1428 temp = strchr(script_dirent.d_name, '.'); 1429 snprintf(scripts_array[i], 1430 (temp - script_dirent.d_name) + 1, 1431 "%s", script_dirent.d_name); 1432 1433 if (check_ev_match(lang_path, 1434 scripts_array[i], session)) 1435 continue; 1436 1437 i++; 1438 } 1439 closedir(lang_dir); 1440 } 1441 1442 closedir(scripts_dir); 1443 perf_session__delete(session); 1444 return i; 1445 } 1446 1447 static char *get_script_path(const char *script_root, const char *suffix) 1448 { 1449 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 1450 char scripts_path[MAXPATHLEN]; 1451 char script_path[MAXPATHLEN]; 1452 DIR *scripts_dir, *lang_dir; 1453 char lang_path[MAXPATHLEN]; 1454 char *__script_root; 1455 1456 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); 1457 1458 scripts_dir = opendir(scripts_path); 1459 if (!scripts_dir) 1460 return NULL; 1461 1462 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { 1463 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 1464 lang_dirent.d_name); 1465 lang_dir = opendir(lang_path); 1466 if (!lang_dir) 1467 continue; 1468 1469 for_each_script(lang_path, lang_dir, script_dirent, script_next) { 1470 __script_root = get_script_root(&script_dirent, suffix); 1471 if (__script_root && !strcmp(script_root, __script_root)) { 1472 free(__script_root); 1473 closedir(lang_dir); 1474 closedir(scripts_dir); 1475 snprintf(script_path, MAXPATHLEN, "%s/%s", 1476 lang_path, script_dirent.d_name); 1477 return strdup(script_path); 1478 } 1479 free(__script_root); 1480 } 1481 closedir(lang_dir); 1482 } 1483 closedir(scripts_dir); 1484 1485 return NULL; 1486 } 1487 1488 static bool is_top_script(const char *script_path) 1489 { 1490 return ends_with(script_path, "top") == NULL ? false : true; 1491 } 1492 1493 static int has_required_arg(char *script_path) 1494 { 1495 struct script_desc *desc; 1496 int n_args = 0; 1497 char *p; 1498 1499 desc = script_desc__new(NULL); 1500 1501 if (read_script_info(desc, script_path)) 1502 goto out; 1503 1504 if (!desc->args) 1505 goto out; 1506 1507 for (p = desc->args; *p; p++) 1508 if (*p == '<') 1509 n_args++; 1510 out: 1511 script_desc__delete(desc); 1512 1513 return n_args; 1514 } 1515 1516 static int have_cmd(int argc, const char **argv) 1517 { 1518 char **__argv = malloc(sizeof(const char *) * argc); 1519 1520 if (!__argv) { 1521 pr_err("malloc failed\n"); 1522 return -1; 1523 } 1524 1525 memcpy(__argv, argv, sizeof(const char *) * argc); 1526 argc = parse_options(argc, (const char **)__argv, record_options, 1527 NULL, PARSE_OPT_STOP_AT_NON_OPTION); 1528 free(__argv); 1529 1530 system_wide = (argc == 0); 1531 1532 return 0; 1533 } 1534 1535 int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) 1536 { 1537 bool show_full_info = false; 1538 bool header = false; 1539 bool header_only = false; 1540 bool script_started = false; 1541 char *rec_script_path = NULL; 1542 char *rep_script_path = NULL; 1543 struct perf_session *session; 1544 struct itrace_synth_opts itrace_synth_opts = { .set = false, }; 1545 char *script_path = NULL; 1546 const char **__argv; 1547 int i, j, err = 0; 1548 struct perf_script script = { 1549 .tool = { 1550 .sample = process_sample_event, 1551 .mmap = perf_event__process_mmap, 1552 .mmap2 = perf_event__process_mmap2, 1553 .comm = perf_event__process_comm, 1554 .exit = perf_event__process_exit, 1555 .fork = perf_event__process_fork, 1556 .attr = process_attr, 1557 .tracing_data = perf_event__process_tracing_data, 1558 .build_id = perf_event__process_build_id, 1559 .id_index = perf_event__process_id_index, 1560 .auxtrace_info = perf_event__process_auxtrace_info, 1561 .auxtrace = perf_event__process_auxtrace, 1562 .auxtrace_error = perf_event__process_auxtrace_error, 1563 .ordered_events = true, 1564 .ordering_requires_timestamps = true, 1565 }, 1566 }; 1567 struct perf_data_file file = { 1568 .mode = PERF_DATA_MODE_READ, 1569 }; 1570 const struct option options[] = { 1571 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1572 "dump raw trace in ASCII"), 1573 OPT_INCR('v', "verbose", &verbose, 1574 "be more verbose (show symbol address, etc)"), 1575 OPT_BOOLEAN('L', "Latency", &latency_format, 1576 "show latency attributes (irqs/preemption disabled, etc)"), 1577 OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts", 1578 list_available_scripts), 1579 OPT_CALLBACK('s', "script", NULL, "name", 1580 "script file name (lang:script name, script name, or *)", 1581 parse_scriptname), 1582 OPT_STRING('g', "gen-script", &generate_script_lang, "lang", 1583 "generate perf-script.xx script in specified language"), 1584 OPT_STRING('i', "input", &input_name, "file", "input file name"), 1585 OPT_BOOLEAN('d', "debug-mode", &debug_mode, 1586 "do various checks like samples ordering and lost events"), 1587 OPT_BOOLEAN(0, "header", &header, "Show data header."), 1588 OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."), 1589 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 1590 "file", "vmlinux pathname"), 1591 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, 1592 "file", "kallsyms pathname"), 1593 OPT_BOOLEAN('G', "hide-call-graph", &no_callchain, 1594 "When printing symbols do not display call chain"), 1595 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 1596 "Look for files with symbols relative to this directory"), 1597 OPT_CALLBACK('F', "fields", NULL, "str", 1598 "comma separated output fields prepend with 'type:'. " 1599 "Valid types: hw,sw,trace,raw. " 1600 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 1601 "addr,symoff,period,flags", parse_output_fields), 1602 OPT_BOOLEAN('a', "all-cpus", &system_wide, 1603 "system-wide collection from all CPUs"), 1604 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", 1605 "only consider these symbols"), 1606 OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 1607 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", 1608 "only display events for these comms"), 1609 OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]", 1610 "only consider symbols in these pids"), 1611 OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]", 1612 "only consider symbols in these tids"), 1613 OPT_BOOLEAN('I', "show-info", &show_full_info, 1614 "display extended information from perf.data file"), 1615 OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path, 1616 "Show the path of [kernel.kallsyms]"), 1617 OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events, 1618 "Show the fork/comm/exit events"), 1619 OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events, 1620 "Show the mmap events"), 1621 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), 1622 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", 1623 "Instruction Tracing options", 1624 itrace_parse_synth_opts), 1625 OPT_END() 1626 }; 1627 const char * const script_subcommands[] = { "record", "report", NULL }; 1628 const char *script_usage[] = { 1629 "perf script [<options>]", 1630 "perf script [<options>] record <script> [<record-options>] <command>", 1631 "perf script [<options>] report <script> [script-args]", 1632 "perf script [<options>] <script> [<record-options>] <command>", 1633 "perf script [<options>] <top-script> [script-args]", 1634 NULL 1635 }; 1636 1637 setup_scripting(); 1638 1639 argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage, 1640 PARSE_OPT_STOP_AT_NON_OPTION); 1641 1642 file.path = input_name; 1643 1644 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { 1645 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); 1646 if (!rec_script_path) 1647 return cmd_record(argc, argv, NULL); 1648 } 1649 1650 if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) { 1651 rep_script_path = get_script_path(argv[1], REPORT_SUFFIX); 1652 if (!rep_script_path) { 1653 fprintf(stderr, 1654 "Please specify a valid report script" 1655 "(see 'perf script -l' for listing)\n"); 1656 return -1; 1657 } 1658 } 1659 1660 /* make sure PERF_EXEC_PATH is set for scripts */ 1661 perf_set_argv_exec_path(perf_exec_path()); 1662 1663 if (argc && !script_name && !rec_script_path && !rep_script_path) { 1664 int live_pipe[2]; 1665 int rep_args; 1666 pid_t pid; 1667 1668 rec_script_path = get_script_path(argv[0], RECORD_SUFFIX); 1669 rep_script_path = get_script_path(argv[0], REPORT_SUFFIX); 1670 1671 if (!rec_script_path && !rep_script_path) { 1672 fprintf(stderr, " Couldn't find script %s\n\n See perf" 1673 " script -l for available scripts.\n", argv[0]); 1674 usage_with_options(script_usage, options); 1675 } 1676 1677 if (is_top_script(argv[0])) { 1678 rep_args = argc - 1; 1679 } else { 1680 int rec_args; 1681 1682 rep_args = has_required_arg(rep_script_path); 1683 rec_args = (argc - 1) - rep_args; 1684 if (rec_args < 0) { 1685 fprintf(stderr, " %s script requires options." 1686 "\n\n See perf script -l for available " 1687 "scripts and options.\n", argv[0]); 1688 usage_with_options(script_usage, options); 1689 } 1690 } 1691 1692 if (pipe(live_pipe) < 0) { 1693 perror("failed to create pipe"); 1694 return -1; 1695 } 1696 1697 pid = fork(); 1698 if (pid < 0) { 1699 perror("failed to fork"); 1700 return -1; 1701 } 1702 1703 if (!pid) { 1704 j = 0; 1705 1706 dup2(live_pipe[1], 1); 1707 close(live_pipe[0]); 1708 1709 if (is_top_script(argv[0])) { 1710 system_wide = true; 1711 } else if (!system_wide) { 1712 if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) { 1713 err = -1; 1714 goto out; 1715 } 1716 } 1717 1718 __argv = malloc((argc + 6) * sizeof(const char *)); 1719 if (!__argv) { 1720 pr_err("malloc failed\n"); 1721 err = -ENOMEM; 1722 goto out; 1723 } 1724 1725 __argv[j++] = "/bin/sh"; 1726 __argv[j++] = rec_script_path; 1727 if (system_wide) 1728 __argv[j++] = "-a"; 1729 __argv[j++] = "-q"; 1730 __argv[j++] = "-o"; 1731 __argv[j++] = "-"; 1732 for (i = rep_args + 1; i < argc; i++) 1733 __argv[j++] = argv[i]; 1734 __argv[j++] = NULL; 1735 1736 execvp("/bin/sh", (char **)__argv); 1737 free(__argv); 1738 exit(-1); 1739 } 1740 1741 dup2(live_pipe[0], 0); 1742 close(live_pipe[1]); 1743 1744 __argv = malloc((argc + 4) * sizeof(const char *)); 1745 if (!__argv) { 1746 pr_err("malloc failed\n"); 1747 err = -ENOMEM; 1748 goto out; 1749 } 1750 1751 j = 0; 1752 __argv[j++] = "/bin/sh"; 1753 __argv[j++] = rep_script_path; 1754 for (i = 1; i < rep_args + 1; i++) 1755 __argv[j++] = argv[i]; 1756 __argv[j++] = "-i"; 1757 __argv[j++] = "-"; 1758 __argv[j++] = NULL; 1759 1760 execvp("/bin/sh", (char **)__argv); 1761 free(__argv); 1762 exit(-1); 1763 } 1764 1765 if (rec_script_path) 1766 script_path = rec_script_path; 1767 if (rep_script_path) 1768 script_path = rep_script_path; 1769 1770 if (script_path) { 1771 j = 0; 1772 1773 if (!rec_script_path) 1774 system_wide = false; 1775 else if (!system_wide) { 1776 if (have_cmd(argc - 1, &argv[1]) != 0) { 1777 err = -1; 1778 goto out; 1779 } 1780 } 1781 1782 __argv = malloc((argc + 2) * sizeof(const char *)); 1783 if (!__argv) { 1784 pr_err("malloc failed\n"); 1785 err = -ENOMEM; 1786 goto out; 1787 } 1788 1789 __argv[j++] = "/bin/sh"; 1790 __argv[j++] = script_path; 1791 if (system_wide) 1792 __argv[j++] = "-a"; 1793 for (i = 2; i < argc; i++) 1794 __argv[j++] = argv[i]; 1795 __argv[j++] = NULL; 1796 1797 execvp("/bin/sh", (char **)__argv); 1798 free(__argv); 1799 exit(-1); 1800 } 1801 1802 if (!script_name) 1803 setup_pager(); 1804 1805 session = perf_session__new(&file, false, &script.tool); 1806 if (session == NULL) 1807 return -1; 1808 1809 if (header || header_only) { 1810 perf_session__fprintf_info(session, stdout, show_full_info); 1811 if (header_only) 1812 goto out_delete; 1813 } 1814 1815 if (symbol__init(&session->header.env) < 0) 1816 goto out_delete; 1817 1818 script.session = session; 1819 1820 session->itrace_synth_opts = &itrace_synth_opts; 1821 1822 if (cpu_list) { 1823 err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap); 1824 if (err < 0) 1825 goto out_delete; 1826 } 1827 1828 if (!no_callchain) 1829 symbol_conf.use_callchain = true; 1830 else 1831 symbol_conf.use_callchain = false; 1832 1833 if (generate_script_lang) { 1834 struct stat perf_stat; 1835 int input; 1836 1837 if (output_set_by_user()) { 1838 fprintf(stderr, 1839 "custom fields not supported for generated scripts"); 1840 err = -EINVAL; 1841 goto out_delete; 1842 } 1843 1844 input = open(file.path, O_RDONLY); /* input_name */ 1845 if (input < 0) { 1846 err = -errno; 1847 perror("failed to open file"); 1848 goto out_delete; 1849 } 1850 1851 err = fstat(input, &perf_stat); 1852 if (err < 0) { 1853 perror("failed to stat file"); 1854 goto out_delete; 1855 } 1856 1857 if (!perf_stat.st_size) { 1858 fprintf(stderr, "zero-sized file, nothing to do!\n"); 1859 goto out_delete; 1860 } 1861 1862 scripting_ops = script_spec__lookup(generate_script_lang); 1863 if (!scripting_ops) { 1864 fprintf(stderr, "invalid language specifier"); 1865 err = -ENOENT; 1866 goto out_delete; 1867 } 1868 1869 err = scripting_ops->generate_script(session->tevent.pevent, 1870 "perf-script"); 1871 goto out_delete; 1872 } 1873 1874 if (script_name) { 1875 err = scripting_ops->start_script(script_name, argc, argv); 1876 if (err) 1877 goto out_delete; 1878 pr_debug("perf script started with script %s\n\n", script_name); 1879 script_started = true; 1880 } 1881 1882 1883 err = perf_session__check_output_opt(session); 1884 if (err < 0) 1885 goto out_delete; 1886 1887 err = __cmd_script(&script); 1888 1889 flush_scripting(); 1890 1891 out_delete: 1892 perf_session__delete(session); 1893 1894 if (script_started) 1895 cleanup_scripting(); 1896 out: 1897 return err; 1898 } 1899