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