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/symbol.h" 11 #include "util/thread.h" 12 #include "util/trace-event.h" 13 #include "util/util.h" 14 #include "util/evlist.h" 15 #include "util/evsel.h" 16 #include <linux/bitmap.h> 17 18 static char const *script_name; 19 static char const *generate_script_lang; 20 static bool debug_mode; 21 static u64 last_timestamp; 22 static u64 nr_unordered; 23 extern const struct option record_options[]; 24 static bool no_callchain; 25 static bool show_full_info; 26 static const char *cpu_list; 27 static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 28 29 enum perf_output_field { 30 PERF_OUTPUT_COMM = 1U << 0, 31 PERF_OUTPUT_TID = 1U << 1, 32 PERF_OUTPUT_PID = 1U << 2, 33 PERF_OUTPUT_TIME = 1U << 3, 34 PERF_OUTPUT_CPU = 1U << 4, 35 PERF_OUTPUT_EVNAME = 1U << 5, 36 PERF_OUTPUT_TRACE = 1U << 6, 37 PERF_OUTPUT_IP = 1U << 7, 38 PERF_OUTPUT_SYM = 1U << 8, 39 PERF_OUTPUT_DSO = 1U << 9, 40 PERF_OUTPUT_ADDR = 1U << 10, 41 }; 42 43 struct output_option { 44 const char *str; 45 enum perf_output_field field; 46 } all_output_options[] = { 47 {.str = "comm", .field = PERF_OUTPUT_COMM}, 48 {.str = "tid", .field = PERF_OUTPUT_TID}, 49 {.str = "pid", .field = PERF_OUTPUT_PID}, 50 {.str = "time", .field = PERF_OUTPUT_TIME}, 51 {.str = "cpu", .field = PERF_OUTPUT_CPU}, 52 {.str = "event", .field = PERF_OUTPUT_EVNAME}, 53 {.str = "trace", .field = PERF_OUTPUT_TRACE}, 54 {.str = "ip", .field = PERF_OUTPUT_IP}, 55 {.str = "sym", .field = PERF_OUTPUT_SYM}, 56 {.str = "dso", .field = PERF_OUTPUT_DSO}, 57 {.str = "addr", .field = PERF_OUTPUT_ADDR}, 58 }; 59 60 /* default set to maintain compatibility with current format */ 61 static struct { 62 bool user_set; 63 bool wildcard_set; 64 u64 fields; 65 u64 invalid_fields; 66 } output[PERF_TYPE_MAX] = { 67 68 [PERF_TYPE_HARDWARE] = { 69 .user_set = false, 70 71 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 72 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 73 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 74 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO, 75 76 .invalid_fields = PERF_OUTPUT_TRACE, 77 }, 78 79 [PERF_TYPE_SOFTWARE] = { 80 .user_set = false, 81 82 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 83 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 84 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 85 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO, 86 87 .invalid_fields = PERF_OUTPUT_TRACE, 88 }, 89 90 [PERF_TYPE_TRACEPOINT] = { 91 .user_set = false, 92 93 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 94 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 95 PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE, 96 }, 97 98 [PERF_TYPE_RAW] = { 99 .user_set = false, 100 101 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 102 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 103 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 104 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO, 105 106 .invalid_fields = PERF_OUTPUT_TRACE, 107 }, 108 }; 109 110 static bool output_set_by_user(void) 111 { 112 int j; 113 for (j = 0; j < PERF_TYPE_MAX; ++j) { 114 if (output[j].user_set) 115 return true; 116 } 117 return false; 118 } 119 120 static const char *output_field2str(enum perf_output_field field) 121 { 122 int i, imax = ARRAY_SIZE(all_output_options); 123 const char *str = ""; 124 125 for (i = 0; i < imax; ++i) { 126 if (all_output_options[i].field == field) { 127 str = all_output_options[i].str; 128 break; 129 } 130 } 131 return str; 132 } 133 134 #define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x) 135 136 static int perf_event_attr__check_stype(struct perf_event_attr *attr, 137 u64 sample_type, const char *sample_msg, 138 enum perf_output_field field) 139 { 140 int type = attr->type; 141 const char *evname; 142 143 if (attr->sample_type & sample_type) 144 return 0; 145 146 if (output[type].user_set) { 147 evname = __event_name(attr->type, attr->config); 148 pr_err("Samples for '%s' event do not have %s attribute set. " 149 "Cannot print '%s' field.\n", 150 evname, sample_msg, output_field2str(field)); 151 return -1; 152 } 153 154 /* user did not ask for it explicitly so remove from the default list */ 155 output[type].fields &= ~field; 156 evname = __event_name(attr->type, attr->config); 157 pr_debug("Samples for '%s' event do not have %s attribute set. " 158 "Skipping '%s' field.\n", 159 evname, sample_msg, output_field2str(field)); 160 161 return 0; 162 } 163 164 static int perf_evsel__check_attr(struct perf_evsel *evsel, 165 struct perf_session *session) 166 { 167 struct perf_event_attr *attr = &evsel->attr; 168 169 if (PRINT_FIELD(TRACE) && 170 !perf_session__has_traces(session, "record -R")) 171 return -EINVAL; 172 173 if (PRINT_FIELD(IP)) { 174 if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP", 175 PERF_OUTPUT_IP)) 176 return -EINVAL; 177 178 if (!no_callchain && 179 !(attr->sample_type & PERF_SAMPLE_CALLCHAIN)) 180 symbol_conf.use_callchain = false; 181 } 182 183 if (PRINT_FIELD(ADDR) && 184 perf_event_attr__check_stype(attr, PERF_SAMPLE_ADDR, "ADDR", 185 PERF_OUTPUT_ADDR)) 186 return -EINVAL; 187 188 if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { 189 pr_err("Display of symbols requested but neither sample IP nor " 190 "sample address\nis selected. Hence, no addresses to convert " 191 "to symbols.\n"); 192 return -EINVAL; 193 } 194 if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { 195 pr_err("Display of DSO requested but neither sample IP nor " 196 "sample address\nis selected. Hence, no addresses to convert " 197 "to DSO.\n"); 198 return -EINVAL; 199 } 200 201 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && 202 perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID", 203 PERF_OUTPUT_TID|PERF_OUTPUT_PID)) 204 return -EINVAL; 205 206 if (PRINT_FIELD(TIME) && 207 perf_event_attr__check_stype(attr, PERF_SAMPLE_TIME, "TIME", 208 PERF_OUTPUT_TIME)) 209 return -EINVAL; 210 211 if (PRINT_FIELD(CPU) && 212 perf_event_attr__check_stype(attr, PERF_SAMPLE_CPU, "CPU", 213 PERF_OUTPUT_CPU)) 214 return -EINVAL; 215 216 return 0; 217 } 218 219 /* 220 * verify all user requested events exist and the samples 221 * have the expected data 222 */ 223 static int perf_session__check_output_opt(struct perf_session *session) 224 { 225 int j; 226 struct perf_evsel *evsel; 227 228 for (j = 0; j < PERF_TYPE_MAX; ++j) { 229 evsel = perf_session__find_first_evtype(session, j); 230 231 /* 232 * even if fields is set to 0 (ie., show nothing) event must 233 * exist if user explicitly includes it on the command line 234 */ 235 if (!evsel && output[j].user_set && !output[j].wildcard_set) { 236 pr_err("%s events do not exist. " 237 "Remove corresponding -f option to proceed.\n", 238 event_type(j)); 239 return -1; 240 } 241 242 if (evsel && output[j].fields && 243 perf_evsel__check_attr(evsel, session)) 244 return -1; 245 } 246 247 return 0; 248 } 249 250 static void print_sample_start(struct perf_sample *sample, 251 struct thread *thread, 252 struct perf_event_attr *attr) 253 { 254 int type; 255 struct event *event; 256 const char *evname = NULL; 257 unsigned long secs; 258 unsigned long usecs; 259 unsigned long long nsecs; 260 261 if (PRINT_FIELD(COMM)) { 262 if (latency_format) 263 printf("%8.8s ", thread->comm); 264 else if (PRINT_FIELD(IP) && symbol_conf.use_callchain) 265 printf("%s ", thread->comm); 266 else 267 printf("%16s ", thread->comm); 268 } 269 270 if (PRINT_FIELD(PID) && PRINT_FIELD(TID)) 271 printf("%5d/%-5d ", sample->pid, sample->tid); 272 else if (PRINT_FIELD(PID)) 273 printf("%5d ", sample->pid); 274 else if (PRINT_FIELD(TID)) 275 printf("%5d ", sample->tid); 276 277 if (PRINT_FIELD(CPU)) { 278 if (latency_format) 279 printf("%3d ", sample->cpu); 280 else 281 printf("[%03d] ", sample->cpu); 282 } 283 284 if (PRINT_FIELD(TIME)) { 285 nsecs = sample->time; 286 secs = nsecs / NSECS_PER_SEC; 287 nsecs -= secs * NSECS_PER_SEC; 288 usecs = nsecs / NSECS_PER_USEC; 289 printf("%5lu.%06lu: ", secs, usecs); 290 } 291 292 if (PRINT_FIELD(EVNAME)) { 293 if (attr->type == PERF_TYPE_TRACEPOINT) { 294 type = trace_parse_common_type(sample->raw_data); 295 event = trace_find_event(type); 296 if (event) 297 evname = event->name; 298 } else 299 evname = __event_name(attr->type, attr->config); 300 301 printf("%s: ", evname ? evname : "(unknown)"); 302 } 303 } 304 305 static bool sample_addr_correlates_sym(struct perf_event_attr *attr) 306 { 307 if ((attr->type == PERF_TYPE_SOFTWARE) && 308 ((attr->config == PERF_COUNT_SW_PAGE_FAULTS) || 309 (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MIN) || 310 (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ))) 311 return true; 312 313 return false; 314 } 315 316 static void print_sample_addr(union perf_event *event, 317 struct perf_sample *sample, 318 struct perf_session *session, 319 struct thread *thread, 320 struct perf_event_attr *attr) 321 { 322 struct addr_location al; 323 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 324 const char *symname, *dsoname; 325 326 printf("%16" PRIx64, sample->addr); 327 328 if (!sample_addr_correlates_sym(attr)) 329 return; 330 331 thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, 332 event->ip.pid, sample->addr, &al); 333 if (!al.map) 334 thread__find_addr_map(thread, session, cpumode, MAP__VARIABLE, 335 event->ip.pid, sample->addr, &al); 336 337 al.cpu = sample->cpu; 338 al.sym = NULL; 339 340 if (al.map) 341 al.sym = map__find_symbol(al.map, al.addr, NULL); 342 343 if (PRINT_FIELD(SYM)) { 344 if (al.sym && al.sym->name) 345 symname = al.sym->name; 346 else 347 symname = ""; 348 349 printf(" %16s", symname); 350 } 351 352 if (PRINT_FIELD(DSO)) { 353 if (al.map && al.map->dso && al.map->dso->name) 354 dsoname = al.map->dso->name; 355 else 356 dsoname = ""; 357 358 printf(" (%s)", dsoname); 359 } 360 } 361 362 static void process_event(union perf_event *event __unused, 363 struct perf_sample *sample, 364 struct perf_evsel *evsel, 365 struct perf_session *session, 366 struct thread *thread) 367 { 368 struct perf_event_attr *attr = &evsel->attr; 369 370 if (output[attr->type].fields == 0) 371 return; 372 373 print_sample_start(sample, thread, attr); 374 375 if (PRINT_FIELD(TRACE)) 376 print_trace_event(sample->cpu, sample->raw_data, 377 sample->raw_size); 378 379 if (PRINT_FIELD(ADDR)) 380 print_sample_addr(event, sample, session, thread, attr); 381 382 if (PRINT_FIELD(IP)) { 383 if (!symbol_conf.use_callchain) 384 printf(" "); 385 else 386 printf("\n"); 387 perf_session__print_ip(event, sample, session, 388 PRINT_FIELD(SYM), PRINT_FIELD(DSO)); 389 } 390 391 printf("\n"); 392 } 393 394 static int default_start_script(const char *script __unused, 395 int argc __unused, 396 const char **argv __unused) 397 { 398 return 0; 399 } 400 401 static int default_stop_script(void) 402 { 403 return 0; 404 } 405 406 static int default_generate_script(const char *outfile __unused) 407 { 408 return 0; 409 } 410 411 static struct scripting_ops default_scripting_ops = { 412 .start_script = default_start_script, 413 .stop_script = default_stop_script, 414 .process_event = process_event, 415 .generate_script = default_generate_script, 416 }; 417 418 static struct scripting_ops *scripting_ops; 419 420 static void setup_scripting(void) 421 { 422 setup_perl_scripting(); 423 setup_python_scripting(); 424 425 scripting_ops = &default_scripting_ops; 426 } 427 428 static int cleanup_scripting(void) 429 { 430 pr_debug("\nperf script stopped\n"); 431 432 return scripting_ops->stop_script(); 433 } 434 435 static char const *input_name = "perf.data"; 436 437 static int process_sample_event(union perf_event *event, 438 struct perf_sample *sample, 439 struct perf_evsel *evsel, 440 struct perf_session *session) 441 { 442 struct thread *thread = perf_session__findnew(session, event->ip.pid); 443 444 if (thread == NULL) { 445 pr_debug("problem processing %d event, skipping it.\n", 446 event->header.type); 447 return -1; 448 } 449 450 if (debug_mode) { 451 if (sample->time < last_timestamp) { 452 pr_err("Samples misordered, previous: %" PRIu64 453 " this: %" PRIu64 "\n", last_timestamp, 454 sample->time); 455 nr_unordered++; 456 } 457 last_timestamp = sample->time; 458 return 0; 459 } 460 461 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) 462 return 0; 463 464 scripting_ops->process_event(event, sample, evsel, session, thread); 465 466 session->hists.stats.total_period += sample->period; 467 return 0; 468 } 469 470 static struct perf_event_ops event_ops = { 471 .sample = process_sample_event, 472 .mmap = perf_event__process_mmap, 473 .comm = perf_event__process_comm, 474 .exit = perf_event__process_task, 475 .fork = perf_event__process_task, 476 .attr = perf_event__process_attr, 477 .event_type = perf_event__process_event_type, 478 .tracing_data = perf_event__process_tracing_data, 479 .build_id = perf_event__process_build_id, 480 .ordered_samples = true, 481 .ordering_requires_timestamps = true, 482 }; 483 484 extern volatile int session_done; 485 486 static void sig_handler(int sig __unused) 487 { 488 session_done = 1; 489 } 490 491 static int __cmd_script(struct perf_session *session) 492 { 493 int ret; 494 495 signal(SIGINT, sig_handler); 496 497 ret = perf_session__process_events(session, &event_ops); 498 499 if (debug_mode) 500 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 501 502 return ret; 503 } 504 505 struct script_spec { 506 struct list_head node; 507 struct scripting_ops *ops; 508 char spec[0]; 509 }; 510 511 static LIST_HEAD(script_specs); 512 513 static struct script_spec *script_spec__new(const char *spec, 514 struct scripting_ops *ops) 515 { 516 struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1); 517 518 if (s != NULL) { 519 strcpy(s->spec, spec); 520 s->ops = ops; 521 } 522 523 return s; 524 } 525 526 static void script_spec__delete(struct script_spec *s) 527 { 528 free(s->spec); 529 free(s); 530 } 531 532 static void script_spec__add(struct script_spec *s) 533 { 534 list_add_tail(&s->node, &script_specs); 535 } 536 537 static struct script_spec *script_spec__find(const char *spec) 538 { 539 struct script_spec *s; 540 541 list_for_each_entry(s, &script_specs, node) 542 if (strcasecmp(s->spec, spec) == 0) 543 return s; 544 return NULL; 545 } 546 547 static struct script_spec *script_spec__findnew(const char *spec, 548 struct scripting_ops *ops) 549 { 550 struct script_spec *s = script_spec__find(spec); 551 552 if (s) 553 return s; 554 555 s = script_spec__new(spec, ops); 556 if (!s) 557 goto out_delete_spec; 558 559 script_spec__add(s); 560 561 return s; 562 563 out_delete_spec: 564 script_spec__delete(s); 565 566 return NULL; 567 } 568 569 int script_spec_register(const char *spec, struct scripting_ops *ops) 570 { 571 struct script_spec *s; 572 573 s = script_spec__find(spec); 574 if (s) 575 return -1; 576 577 s = script_spec__findnew(spec, ops); 578 if (!s) 579 return -1; 580 581 return 0; 582 } 583 584 static struct scripting_ops *script_spec__lookup(const char *spec) 585 { 586 struct script_spec *s = script_spec__find(spec); 587 if (!s) 588 return NULL; 589 590 return s->ops; 591 } 592 593 static void list_available_languages(void) 594 { 595 struct script_spec *s; 596 597 fprintf(stderr, "\n"); 598 fprintf(stderr, "Scripting language extensions (used in " 599 "perf script -s [spec:]script.[spec]):\n\n"); 600 601 list_for_each_entry(s, &script_specs, node) 602 fprintf(stderr, " %-42s [%s]\n", s->spec, s->ops->name); 603 604 fprintf(stderr, "\n"); 605 } 606 607 static int parse_scriptname(const struct option *opt __used, 608 const char *str, int unset __used) 609 { 610 char spec[PATH_MAX]; 611 const char *script, *ext; 612 int len; 613 614 if (strcmp(str, "lang") == 0) { 615 list_available_languages(); 616 exit(0); 617 } 618 619 script = strchr(str, ':'); 620 if (script) { 621 len = script - str; 622 if (len >= PATH_MAX) { 623 fprintf(stderr, "invalid language specifier"); 624 return -1; 625 } 626 strncpy(spec, str, len); 627 spec[len] = '\0'; 628 scripting_ops = script_spec__lookup(spec); 629 if (!scripting_ops) { 630 fprintf(stderr, "invalid language specifier"); 631 return -1; 632 } 633 script++; 634 } else { 635 script = str; 636 ext = strrchr(script, '.'); 637 if (!ext) { 638 fprintf(stderr, "invalid script extension"); 639 return -1; 640 } 641 scripting_ops = script_spec__lookup(++ext); 642 if (!scripting_ops) { 643 fprintf(stderr, "invalid script extension"); 644 return -1; 645 } 646 } 647 648 script_name = strdup(script); 649 650 return 0; 651 } 652 653 static int parse_output_fields(const struct option *opt __used, 654 const char *arg, int unset __used) 655 { 656 char *tok; 657 int i, imax = sizeof(all_output_options) / sizeof(struct output_option); 658 int j; 659 int rc = 0; 660 char *str = strdup(arg); 661 int type = -1; 662 663 if (!str) 664 return -ENOMEM; 665 666 /* first word can state for which event type the user is specifying 667 * the fields. If no type exists, the specified fields apply to all 668 * event types found in the file minus the invalid fields for a type. 669 */ 670 tok = strchr(str, ':'); 671 if (tok) { 672 *tok = '\0'; 673 tok++; 674 if (!strcmp(str, "hw")) 675 type = PERF_TYPE_HARDWARE; 676 else if (!strcmp(str, "sw")) 677 type = PERF_TYPE_SOFTWARE; 678 else if (!strcmp(str, "trace")) 679 type = PERF_TYPE_TRACEPOINT; 680 else if (!strcmp(str, "raw")) 681 type = PERF_TYPE_RAW; 682 else { 683 fprintf(stderr, "Invalid event type in field string.\n"); 684 return -EINVAL; 685 } 686 687 if (output[type].user_set) 688 pr_warning("Overriding previous field request for %s events.\n", 689 event_type(type)); 690 691 output[type].fields = 0; 692 output[type].user_set = true; 693 output[type].wildcard_set = false; 694 695 } else { 696 tok = str; 697 if (strlen(str) == 0) { 698 fprintf(stderr, 699 "Cannot set fields to 'none' for all event types.\n"); 700 rc = -EINVAL; 701 goto out; 702 } 703 704 if (output_set_by_user()) 705 pr_warning("Overriding previous field request for all events.\n"); 706 707 for (j = 0; j < PERF_TYPE_MAX; ++j) { 708 output[j].fields = 0; 709 output[j].user_set = true; 710 output[j].wildcard_set = true; 711 } 712 } 713 714 tok = strtok(tok, ","); 715 while (tok) { 716 for (i = 0; i < imax; ++i) { 717 if (strcmp(tok, all_output_options[i].str) == 0) 718 break; 719 } 720 if (i == imax) { 721 fprintf(stderr, "Invalid field requested.\n"); 722 rc = -EINVAL; 723 goto out; 724 } 725 726 if (type == -1) { 727 /* add user option to all events types for 728 * which it is valid 729 */ 730 for (j = 0; j < PERF_TYPE_MAX; ++j) { 731 if (output[j].invalid_fields & all_output_options[i].field) { 732 pr_warning("\'%s\' not valid for %s events. Ignoring.\n", 733 all_output_options[i].str, event_type(j)); 734 } else 735 output[j].fields |= all_output_options[i].field; 736 } 737 } else { 738 if (output[type].invalid_fields & all_output_options[i].field) { 739 fprintf(stderr, "\'%s\' not valid for %s events.\n", 740 all_output_options[i].str, event_type(type)); 741 742 rc = -EINVAL; 743 goto out; 744 } 745 output[type].fields |= all_output_options[i].field; 746 } 747 748 tok = strtok(NULL, ","); 749 } 750 751 if (type >= 0) { 752 if (output[type].fields == 0) { 753 pr_debug("No fields requested for %s type. " 754 "Events will not be displayed.\n", event_type(type)); 755 } 756 } 757 758 out: 759 free(str); 760 return rc; 761 } 762 763 /* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */ 764 static int is_directory(const char *base_path, const struct dirent *dent) 765 { 766 char path[PATH_MAX]; 767 struct stat st; 768 769 sprintf(path, "%s/%s", base_path, dent->d_name); 770 if (stat(path, &st)) 771 return 0; 772 773 return S_ISDIR(st.st_mode); 774 } 775 776 #define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\ 777 while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ 778 lang_next) \ 779 if ((lang_dirent.d_type == DT_DIR || \ 780 (lang_dirent.d_type == DT_UNKNOWN && \ 781 is_directory(scripts_path, &lang_dirent))) && \ 782 (strcmp(lang_dirent.d_name, ".")) && \ 783 (strcmp(lang_dirent.d_name, ".."))) 784 785 #define for_each_script(lang_path, lang_dir, script_dirent, script_next)\ 786 while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ 787 script_next) \ 788 if (script_dirent.d_type != DT_DIR && \ 789 (script_dirent.d_type != DT_UNKNOWN || \ 790 !is_directory(lang_path, &script_dirent))) 791 792 793 #define RECORD_SUFFIX "-record" 794 #define REPORT_SUFFIX "-report" 795 796 struct script_desc { 797 struct list_head node; 798 char *name; 799 char *half_liner; 800 char *args; 801 }; 802 803 static LIST_HEAD(script_descs); 804 805 static struct script_desc *script_desc__new(const char *name) 806 { 807 struct script_desc *s = zalloc(sizeof(*s)); 808 809 if (s != NULL && name) 810 s->name = strdup(name); 811 812 return s; 813 } 814 815 static void script_desc__delete(struct script_desc *s) 816 { 817 free(s->name); 818 free(s->half_liner); 819 free(s->args); 820 free(s); 821 } 822 823 static void script_desc__add(struct script_desc *s) 824 { 825 list_add_tail(&s->node, &script_descs); 826 } 827 828 static struct script_desc *script_desc__find(const char *name) 829 { 830 struct script_desc *s; 831 832 list_for_each_entry(s, &script_descs, node) 833 if (strcasecmp(s->name, name) == 0) 834 return s; 835 return NULL; 836 } 837 838 static struct script_desc *script_desc__findnew(const char *name) 839 { 840 struct script_desc *s = script_desc__find(name); 841 842 if (s) 843 return s; 844 845 s = script_desc__new(name); 846 if (!s) 847 goto out_delete_desc; 848 849 script_desc__add(s); 850 851 return s; 852 853 out_delete_desc: 854 script_desc__delete(s); 855 856 return NULL; 857 } 858 859 static const char *ends_with(const char *str, const char *suffix) 860 { 861 size_t suffix_len = strlen(suffix); 862 const char *p = str; 863 864 if (strlen(str) > suffix_len) { 865 p = str + strlen(str) - suffix_len; 866 if (!strncmp(p, suffix, suffix_len)) 867 return p; 868 } 869 870 return NULL; 871 } 872 873 static char *ltrim(char *str) 874 { 875 int len = strlen(str); 876 877 while (len && isspace(*str)) { 878 len--; 879 str++; 880 } 881 882 return str; 883 } 884 885 static int read_script_info(struct script_desc *desc, const char *filename) 886 { 887 char line[BUFSIZ], *p; 888 FILE *fp; 889 890 fp = fopen(filename, "r"); 891 if (!fp) 892 return -1; 893 894 while (fgets(line, sizeof(line), fp)) { 895 p = ltrim(line); 896 if (strlen(p) == 0) 897 continue; 898 if (*p != '#') 899 continue; 900 p++; 901 if (strlen(p) && *p == '!') 902 continue; 903 904 p = ltrim(p); 905 if (strlen(p) && p[strlen(p) - 1] == '\n') 906 p[strlen(p) - 1] = '\0'; 907 908 if (!strncmp(p, "description:", strlen("description:"))) { 909 p += strlen("description:"); 910 desc->half_liner = strdup(ltrim(p)); 911 continue; 912 } 913 914 if (!strncmp(p, "args:", strlen("args:"))) { 915 p += strlen("args:"); 916 desc->args = strdup(ltrim(p)); 917 continue; 918 } 919 } 920 921 fclose(fp); 922 923 return 0; 924 } 925 926 static int list_available_scripts(const struct option *opt __used, 927 const char *s __used, int unset __used) 928 { 929 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 930 char scripts_path[MAXPATHLEN]; 931 DIR *scripts_dir, *lang_dir; 932 char script_path[MAXPATHLEN]; 933 char lang_path[MAXPATHLEN]; 934 struct script_desc *desc; 935 char first_half[BUFSIZ]; 936 char *script_root; 937 char *str; 938 939 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); 940 941 scripts_dir = opendir(scripts_path); 942 if (!scripts_dir) 943 return -1; 944 945 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { 946 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 947 lang_dirent.d_name); 948 lang_dir = opendir(lang_path); 949 if (!lang_dir) 950 continue; 951 952 for_each_script(lang_path, lang_dir, script_dirent, script_next) { 953 script_root = strdup(script_dirent.d_name); 954 str = (char *)ends_with(script_root, REPORT_SUFFIX); 955 if (str) { 956 *str = '\0'; 957 desc = script_desc__findnew(script_root); 958 snprintf(script_path, MAXPATHLEN, "%s/%s", 959 lang_path, script_dirent.d_name); 960 read_script_info(desc, script_path); 961 } 962 free(script_root); 963 } 964 } 965 966 fprintf(stdout, "List of available trace scripts:\n"); 967 list_for_each_entry(desc, &script_descs, node) { 968 sprintf(first_half, "%s %s", desc->name, 969 desc->args ? desc->args : ""); 970 fprintf(stdout, " %-36s %s\n", first_half, 971 desc->half_liner ? desc->half_liner : ""); 972 } 973 974 exit(0); 975 } 976 977 static char *get_script_path(const char *script_root, const char *suffix) 978 { 979 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 980 char scripts_path[MAXPATHLEN]; 981 char script_path[MAXPATHLEN]; 982 DIR *scripts_dir, *lang_dir; 983 char lang_path[MAXPATHLEN]; 984 char *str, *__script_root; 985 char *path = NULL; 986 987 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); 988 989 scripts_dir = opendir(scripts_path); 990 if (!scripts_dir) 991 return NULL; 992 993 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { 994 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 995 lang_dirent.d_name); 996 lang_dir = opendir(lang_path); 997 if (!lang_dir) 998 continue; 999 1000 for_each_script(lang_path, lang_dir, script_dirent, script_next) { 1001 __script_root = strdup(script_dirent.d_name); 1002 str = (char *)ends_with(__script_root, suffix); 1003 if (str) { 1004 *str = '\0'; 1005 if (strcmp(__script_root, script_root)) 1006 continue; 1007 snprintf(script_path, MAXPATHLEN, "%s/%s", 1008 lang_path, script_dirent.d_name); 1009 path = strdup(script_path); 1010 free(__script_root); 1011 break; 1012 } 1013 free(__script_root); 1014 } 1015 } 1016 1017 return path; 1018 } 1019 1020 static bool is_top_script(const char *script_path) 1021 { 1022 return ends_with(script_path, "top") == NULL ? false : true; 1023 } 1024 1025 static int has_required_arg(char *script_path) 1026 { 1027 struct script_desc *desc; 1028 int n_args = 0; 1029 char *p; 1030 1031 desc = script_desc__new(NULL); 1032 1033 if (read_script_info(desc, script_path)) 1034 goto out; 1035 1036 if (!desc->args) 1037 goto out; 1038 1039 for (p = desc->args; *p; p++) 1040 if (*p == '<') 1041 n_args++; 1042 out: 1043 script_desc__delete(desc); 1044 1045 return n_args; 1046 } 1047 1048 static const char * const script_usage[] = { 1049 "perf script [<options>]", 1050 "perf script [<options>] record <script> [<record-options>] <command>", 1051 "perf script [<options>] report <script> [script-args]", 1052 "perf script [<options>] <script> [<record-options>] <command>", 1053 "perf script [<options>] <top-script> [script-args]", 1054 NULL 1055 }; 1056 1057 static const struct option options[] = { 1058 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1059 "dump raw trace in ASCII"), 1060 OPT_INCR('v', "verbose", &verbose, 1061 "be more verbose (show symbol address, etc)"), 1062 OPT_BOOLEAN('L', "Latency", &latency_format, 1063 "show latency attributes (irqs/preemption disabled, etc)"), 1064 OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts", 1065 list_available_scripts), 1066 OPT_CALLBACK('s', "script", NULL, "name", 1067 "script file name (lang:script name, script name, or *)", 1068 parse_scriptname), 1069 OPT_STRING('g', "gen-script", &generate_script_lang, "lang", 1070 "generate perf-script.xx script in specified language"), 1071 OPT_STRING('i', "input", &input_name, "file", 1072 "input file name"), 1073 OPT_BOOLEAN('d', "debug-mode", &debug_mode, 1074 "do various checks like samples ordering and lost events"), 1075 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 1076 "file", "vmlinux pathname"), 1077 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, 1078 "file", "kallsyms pathname"), 1079 OPT_BOOLEAN('G', "hide-call-graph", &no_callchain, 1080 "When printing symbols do not display call chain"), 1081 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 1082 "Look for files with symbols relative to this directory"), 1083 OPT_CALLBACK('f', "fields", NULL, "str", 1084 "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr", 1085 parse_output_fields), 1086 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 1087 OPT_BOOLEAN('I', "show-info", &show_full_info, 1088 "display extended information from perf.data file"), 1089 OPT_END() 1090 }; 1091 1092 static bool have_cmd(int argc, const char **argv) 1093 { 1094 char **__argv = malloc(sizeof(const char *) * argc); 1095 1096 if (!__argv) 1097 die("malloc"); 1098 memcpy(__argv, argv, sizeof(const char *) * argc); 1099 argc = parse_options(argc, (const char **)__argv, record_options, 1100 NULL, PARSE_OPT_STOP_AT_NON_OPTION); 1101 free(__argv); 1102 1103 return argc != 0; 1104 } 1105 1106 int cmd_script(int argc, const char **argv, const char *prefix __used) 1107 { 1108 char *rec_script_path = NULL; 1109 char *rep_script_path = NULL; 1110 struct perf_session *session; 1111 char *script_path = NULL; 1112 const char **__argv; 1113 bool system_wide; 1114 int i, j, err; 1115 1116 setup_scripting(); 1117 1118 argc = parse_options(argc, argv, options, script_usage, 1119 PARSE_OPT_STOP_AT_NON_OPTION); 1120 1121 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { 1122 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); 1123 if (!rec_script_path) 1124 return cmd_record(argc, argv, NULL); 1125 } 1126 1127 if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) { 1128 rep_script_path = get_script_path(argv[1], REPORT_SUFFIX); 1129 if (!rep_script_path) { 1130 fprintf(stderr, 1131 "Please specify a valid report script" 1132 "(see 'perf script -l' for listing)\n"); 1133 return -1; 1134 } 1135 } 1136 1137 /* make sure PERF_EXEC_PATH is set for scripts */ 1138 perf_set_argv_exec_path(perf_exec_path()); 1139 1140 if (argc && !script_name && !rec_script_path && !rep_script_path) { 1141 int live_pipe[2]; 1142 int rep_args; 1143 pid_t pid; 1144 1145 rec_script_path = get_script_path(argv[0], RECORD_SUFFIX); 1146 rep_script_path = get_script_path(argv[0], REPORT_SUFFIX); 1147 1148 if (!rec_script_path && !rep_script_path) { 1149 fprintf(stderr, " Couldn't find script %s\n\n See perf" 1150 " script -l for available scripts.\n", argv[0]); 1151 usage_with_options(script_usage, options); 1152 } 1153 1154 if (is_top_script(argv[0])) { 1155 rep_args = argc - 1; 1156 } else { 1157 int rec_args; 1158 1159 rep_args = has_required_arg(rep_script_path); 1160 rec_args = (argc - 1) - rep_args; 1161 if (rec_args < 0) { 1162 fprintf(stderr, " %s script requires options." 1163 "\n\n See perf script -l for available " 1164 "scripts and options.\n", argv[0]); 1165 usage_with_options(script_usage, options); 1166 } 1167 } 1168 1169 if (pipe(live_pipe) < 0) { 1170 perror("failed to create pipe"); 1171 exit(-1); 1172 } 1173 1174 pid = fork(); 1175 if (pid < 0) { 1176 perror("failed to fork"); 1177 exit(-1); 1178 } 1179 1180 if (!pid) { 1181 system_wide = true; 1182 j = 0; 1183 1184 dup2(live_pipe[1], 1); 1185 close(live_pipe[0]); 1186 1187 if (!is_top_script(argv[0])) 1188 system_wide = !have_cmd(argc - rep_args, 1189 &argv[rep_args]); 1190 1191 __argv = malloc((argc + 6) * sizeof(const char *)); 1192 if (!__argv) 1193 die("malloc"); 1194 1195 __argv[j++] = "/bin/sh"; 1196 __argv[j++] = rec_script_path; 1197 if (system_wide) 1198 __argv[j++] = "-a"; 1199 __argv[j++] = "-q"; 1200 __argv[j++] = "-o"; 1201 __argv[j++] = "-"; 1202 for (i = rep_args + 1; i < argc; i++) 1203 __argv[j++] = argv[i]; 1204 __argv[j++] = NULL; 1205 1206 execvp("/bin/sh", (char **)__argv); 1207 free(__argv); 1208 exit(-1); 1209 } 1210 1211 dup2(live_pipe[0], 0); 1212 close(live_pipe[1]); 1213 1214 __argv = malloc((argc + 4) * sizeof(const char *)); 1215 if (!__argv) 1216 die("malloc"); 1217 j = 0; 1218 __argv[j++] = "/bin/sh"; 1219 __argv[j++] = rep_script_path; 1220 for (i = 1; i < rep_args + 1; i++) 1221 __argv[j++] = argv[i]; 1222 __argv[j++] = "-i"; 1223 __argv[j++] = "-"; 1224 __argv[j++] = NULL; 1225 1226 execvp("/bin/sh", (char **)__argv); 1227 free(__argv); 1228 exit(-1); 1229 } 1230 1231 if (rec_script_path) 1232 script_path = rec_script_path; 1233 if (rep_script_path) 1234 script_path = rep_script_path; 1235 1236 if (script_path) { 1237 system_wide = false; 1238 j = 0; 1239 1240 if (rec_script_path) 1241 system_wide = !have_cmd(argc - 1, &argv[1]); 1242 1243 __argv = malloc((argc + 2) * sizeof(const char *)); 1244 if (!__argv) 1245 die("malloc"); 1246 __argv[j++] = "/bin/sh"; 1247 __argv[j++] = script_path; 1248 if (system_wide) 1249 __argv[j++] = "-a"; 1250 for (i = 2; i < argc; i++) 1251 __argv[j++] = argv[i]; 1252 __argv[j++] = NULL; 1253 1254 execvp("/bin/sh", (char **)__argv); 1255 free(__argv); 1256 exit(-1); 1257 } 1258 1259 if (symbol__init() < 0) 1260 return -1; 1261 if (!script_name) 1262 setup_pager(); 1263 1264 session = perf_session__new(input_name, O_RDONLY, 0, false, &event_ops); 1265 if (session == NULL) 1266 return -ENOMEM; 1267 1268 if (cpu_list) { 1269 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) 1270 return -1; 1271 } 1272 1273 perf_session__fprintf_info(session, stdout, show_full_info); 1274 1275 if (!no_callchain) 1276 symbol_conf.use_callchain = true; 1277 else 1278 symbol_conf.use_callchain = false; 1279 1280 if (generate_script_lang) { 1281 struct stat perf_stat; 1282 int input; 1283 1284 if (output_set_by_user()) { 1285 fprintf(stderr, 1286 "custom fields not supported for generated scripts"); 1287 return -1; 1288 } 1289 1290 input = open(input_name, O_RDONLY); 1291 if (input < 0) { 1292 perror("failed to open file"); 1293 exit(-1); 1294 } 1295 1296 err = fstat(input, &perf_stat); 1297 if (err < 0) { 1298 perror("failed to stat file"); 1299 exit(-1); 1300 } 1301 1302 if (!perf_stat.st_size) { 1303 fprintf(stderr, "zero-sized file, nothing to do!\n"); 1304 exit(0); 1305 } 1306 1307 scripting_ops = script_spec__lookup(generate_script_lang); 1308 if (!scripting_ops) { 1309 fprintf(stderr, "invalid language specifier"); 1310 return -1; 1311 } 1312 1313 err = scripting_ops->generate_script("perf-script"); 1314 goto out; 1315 } 1316 1317 if (script_name) { 1318 err = scripting_ops->start_script(script_name, argc, argv); 1319 if (err) 1320 goto out; 1321 pr_debug("perf script started with script %s\n\n", script_name); 1322 } 1323 1324 1325 err = perf_session__check_output_opt(session); 1326 if (err < 0) 1327 goto out; 1328 1329 err = __cmd_script(session); 1330 1331 perf_session__delete(session); 1332 cleanup_scripting(); 1333 out: 1334 return err; 1335 } 1336