1 #include "builtin.h" 2 3 #include "perf.h" 4 #include "util/cache.h" 5 #include "util/debug.h" 6 #include <subcmd/exec-cmd.h> 7 #include "util/header.h" 8 #include <subcmd/parse-options.h> 9 #include "util/perf_regs.h" 10 #include "util/session.h" 11 #include "util/tool.h" 12 #include "util/symbol.h" 13 #include "util/thread.h" 14 #include "util/trace-event.h" 15 #include "util/util.h" 16 #include "util/evlist.h" 17 #include "util/evsel.h" 18 #include "util/sort.h" 19 #include "util/data.h" 20 #include "util/auxtrace.h" 21 #include "util/cpumap.h" 22 #include "util/thread_map.h" 23 #include "util/stat.h" 24 #include "util/thread-stack.h" 25 #include "util/time-utils.h" 26 #include <linux/bitmap.h> 27 #include <linux/stringify.h> 28 #include <linux/time64.h> 29 #include "asm/bug.h" 30 #include "util/mem-events.h" 31 32 static char const *script_name; 33 static char const *generate_script_lang; 34 static bool debug_mode; 35 static u64 last_timestamp; 36 static u64 nr_unordered; 37 static bool no_callchain; 38 static bool latency_format; 39 static bool system_wide; 40 static bool print_flags; 41 static bool nanosecs; 42 static const char *cpu_list; 43 static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 44 static struct perf_stat_config stat_config; 45 46 unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH; 47 48 enum perf_output_field { 49 PERF_OUTPUT_COMM = 1U << 0, 50 PERF_OUTPUT_TID = 1U << 1, 51 PERF_OUTPUT_PID = 1U << 2, 52 PERF_OUTPUT_TIME = 1U << 3, 53 PERF_OUTPUT_CPU = 1U << 4, 54 PERF_OUTPUT_EVNAME = 1U << 5, 55 PERF_OUTPUT_TRACE = 1U << 6, 56 PERF_OUTPUT_IP = 1U << 7, 57 PERF_OUTPUT_SYM = 1U << 8, 58 PERF_OUTPUT_DSO = 1U << 9, 59 PERF_OUTPUT_ADDR = 1U << 10, 60 PERF_OUTPUT_SYMOFFSET = 1U << 11, 61 PERF_OUTPUT_SRCLINE = 1U << 12, 62 PERF_OUTPUT_PERIOD = 1U << 13, 63 PERF_OUTPUT_IREGS = 1U << 14, 64 PERF_OUTPUT_BRSTACK = 1U << 15, 65 PERF_OUTPUT_BRSTACKSYM = 1U << 16, 66 PERF_OUTPUT_DATA_SRC = 1U << 17, 67 PERF_OUTPUT_WEIGHT = 1U << 18, 68 PERF_OUTPUT_BPF_OUTPUT = 1U << 19, 69 PERF_OUTPUT_CALLINDENT = 1U << 20, 70 PERF_OUTPUT_INSN = 1U << 21, 71 PERF_OUTPUT_INSNLEN = 1U << 22, 72 }; 73 74 struct output_option { 75 const char *str; 76 enum perf_output_field field; 77 } all_output_options[] = { 78 {.str = "comm", .field = PERF_OUTPUT_COMM}, 79 {.str = "tid", .field = PERF_OUTPUT_TID}, 80 {.str = "pid", .field = PERF_OUTPUT_PID}, 81 {.str = "time", .field = PERF_OUTPUT_TIME}, 82 {.str = "cpu", .field = PERF_OUTPUT_CPU}, 83 {.str = "event", .field = PERF_OUTPUT_EVNAME}, 84 {.str = "trace", .field = PERF_OUTPUT_TRACE}, 85 {.str = "ip", .field = PERF_OUTPUT_IP}, 86 {.str = "sym", .field = PERF_OUTPUT_SYM}, 87 {.str = "dso", .field = PERF_OUTPUT_DSO}, 88 {.str = "addr", .field = PERF_OUTPUT_ADDR}, 89 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET}, 90 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, 91 {.str = "period", .field = PERF_OUTPUT_PERIOD}, 92 {.str = "iregs", .field = PERF_OUTPUT_IREGS}, 93 {.str = "brstack", .field = PERF_OUTPUT_BRSTACK}, 94 {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM}, 95 {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC}, 96 {.str = "weight", .field = PERF_OUTPUT_WEIGHT}, 97 {.str = "bpf-output", .field = PERF_OUTPUT_BPF_OUTPUT}, 98 {.str = "callindent", .field = PERF_OUTPUT_CALLINDENT}, 99 {.str = "insn", .field = PERF_OUTPUT_INSN}, 100 {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN}, 101 }; 102 103 /* default set to maintain compatibility with current format */ 104 static struct { 105 bool user_set; 106 bool wildcard_set; 107 unsigned int print_ip_opts; 108 u64 fields; 109 u64 invalid_fields; 110 } output[PERF_TYPE_MAX] = { 111 112 [PERF_TYPE_HARDWARE] = { 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 | PERF_OUTPUT_BPF_OUTPUT, 122 }, 123 124 [PERF_TYPE_SOFTWARE] = { 125 .user_set = false, 126 127 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 128 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 129 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 130 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 131 PERF_OUTPUT_PERIOD | PERF_OUTPUT_BPF_OUTPUT, 132 133 .invalid_fields = PERF_OUTPUT_TRACE, 134 }, 135 136 [PERF_TYPE_TRACEPOINT] = { 137 .user_set = false, 138 139 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 140 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 141 PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE 142 }, 143 144 [PERF_TYPE_RAW] = { 145 .user_set = false, 146 147 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 148 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 149 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 150 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 151 PERF_OUTPUT_PERIOD | PERF_OUTPUT_ADDR | 152 PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT, 153 154 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 155 }, 156 157 [PERF_TYPE_BREAKPOINT] = { 158 .user_set = false, 159 160 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 161 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 162 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 163 PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | 164 PERF_OUTPUT_PERIOD, 165 166 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 167 }, 168 }; 169 170 static bool output_set_by_user(void) 171 { 172 int j; 173 for (j = 0; j < PERF_TYPE_MAX; ++j) { 174 if (output[j].user_set) 175 return true; 176 } 177 return false; 178 } 179 180 static const char *output_field2str(enum perf_output_field field) 181 { 182 int i, imax = ARRAY_SIZE(all_output_options); 183 const char *str = ""; 184 185 for (i = 0; i < imax; ++i) { 186 if (all_output_options[i].field == field) { 187 str = all_output_options[i].str; 188 break; 189 } 190 } 191 return str; 192 } 193 194 #define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x) 195 196 static int perf_evsel__do_check_stype(struct perf_evsel *evsel, 197 u64 sample_type, const char *sample_msg, 198 enum perf_output_field field, 199 bool allow_user_set) 200 { 201 struct perf_event_attr *attr = &evsel->attr; 202 int type = attr->type; 203 const char *evname; 204 205 if (attr->sample_type & sample_type) 206 return 0; 207 208 if (output[type].user_set) { 209 if (allow_user_set) 210 return 0; 211 evname = perf_evsel__name(evsel); 212 pr_err("Samples for '%s' event do not have %s attribute set. " 213 "Cannot print '%s' field.\n", 214 evname, sample_msg, output_field2str(field)); 215 return -1; 216 } 217 218 /* user did not ask for it explicitly so remove from the default list */ 219 output[type].fields &= ~field; 220 evname = perf_evsel__name(evsel); 221 pr_debug("Samples for '%s' event do not have %s attribute set. " 222 "Skipping '%s' field.\n", 223 evname, sample_msg, output_field2str(field)); 224 225 return 0; 226 } 227 228 static int perf_evsel__check_stype(struct perf_evsel *evsel, 229 u64 sample_type, const char *sample_msg, 230 enum perf_output_field field) 231 { 232 return perf_evsel__do_check_stype(evsel, sample_type, sample_msg, field, 233 false); 234 } 235 236 static int perf_evsel__check_attr(struct perf_evsel *evsel, 237 struct perf_session *session) 238 { 239 struct perf_event_attr *attr = &evsel->attr; 240 bool allow_user_set; 241 242 if (perf_header__has_feat(&session->header, HEADER_STAT)) 243 return 0; 244 245 allow_user_set = perf_header__has_feat(&session->header, 246 HEADER_AUXTRACE); 247 248 if (PRINT_FIELD(TRACE) && 249 !perf_session__has_traces(session, "record -R")) 250 return -EINVAL; 251 252 if (PRINT_FIELD(IP)) { 253 if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", 254 PERF_OUTPUT_IP)) 255 return -EINVAL; 256 } 257 258 if (PRINT_FIELD(ADDR) && 259 perf_evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", 260 PERF_OUTPUT_ADDR, allow_user_set)) 261 return -EINVAL; 262 263 if (PRINT_FIELD(DATA_SRC) && 264 perf_evsel__check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC", 265 PERF_OUTPUT_DATA_SRC)) 266 return -EINVAL; 267 268 if (PRINT_FIELD(WEIGHT) && 269 perf_evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT, "WEIGHT", 270 PERF_OUTPUT_WEIGHT)) 271 return -EINVAL; 272 273 if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { 274 pr_err("Display of symbols requested but neither sample IP nor " 275 "sample address\nis selected. Hence, no addresses to convert " 276 "to symbols.\n"); 277 return -EINVAL; 278 } 279 if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) { 280 pr_err("Display of offsets requested but symbol is not" 281 "selected.\n"); 282 return -EINVAL; 283 } 284 if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { 285 pr_err("Display of DSO requested but neither sample IP nor " 286 "sample address\nis selected. Hence, no addresses to convert " 287 "to DSO.\n"); 288 return -EINVAL; 289 } 290 if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) { 291 pr_err("Display of source line number requested but sample IP is not\n" 292 "selected. Hence, no address to lookup the source line number.\n"); 293 return -EINVAL; 294 } 295 296 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && 297 perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", 298 PERF_OUTPUT_TID|PERF_OUTPUT_PID)) 299 return -EINVAL; 300 301 if (PRINT_FIELD(TIME) && 302 perf_evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", 303 PERF_OUTPUT_TIME)) 304 return -EINVAL; 305 306 if (PRINT_FIELD(CPU) && 307 perf_evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU", 308 PERF_OUTPUT_CPU, allow_user_set)) 309 return -EINVAL; 310 311 if (PRINT_FIELD(PERIOD) && 312 perf_evsel__check_stype(evsel, PERF_SAMPLE_PERIOD, "PERIOD", 313 PERF_OUTPUT_PERIOD)) 314 return -EINVAL; 315 316 if (PRINT_FIELD(IREGS) && 317 perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", 318 PERF_OUTPUT_IREGS)) 319 return -EINVAL; 320 321 return 0; 322 } 323 324 static void set_print_ip_opts(struct perf_event_attr *attr) 325 { 326 unsigned int type = attr->type; 327 328 output[type].print_ip_opts = 0; 329 if (PRINT_FIELD(IP)) 330 output[type].print_ip_opts |= EVSEL__PRINT_IP; 331 332 if (PRINT_FIELD(SYM)) 333 output[type].print_ip_opts |= EVSEL__PRINT_SYM; 334 335 if (PRINT_FIELD(DSO)) 336 output[type].print_ip_opts |= EVSEL__PRINT_DSO; 337 338 if (PRINT_FIELD(SYMOFFSET)) 339 output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET; 340 341 if (PRINT_FIELD(SRCLINE)) 342 output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE; 343 } 344 345 /* 346 * verify all user requested events exist and the samples 347 * have the expected data 348 */ 349 static int perf_session__check_output_opt(struct perf_session *session) 350 { 351 unsigned int j; 352 struct perf_evsel *evsel; 353 354 for (j = 0; j < PERF_TYPE_MAX; ++j) { 355 evsel = perf_session__find_first_evtype(session, j); 356 357 /* 358 * even if fields is set to 0 (ie., show nothing) event must 359 * exist if user explicitly includes it on the command line 360 */ 361 if (!evsel && output[j].user_set && !output[j].wildcard_set) { 362 pr_err("%s events do not exist. " 363 "Remove corresponding -f option to proceed.\n", 364 event_type(j)); 365 return -1; 366 } 367 368 if (evsel && output[j].fields && 369 perf_evsel__check_attr(evsel, session)) 370 return -1; 371 372 if (evsel == NULL) 373 continue; 374 375 set_print_ip_opts(&evsel->attr); 376 } 377 378 if (!no_callchain) { 379 bool use_callchain = false; 380 bool not_pipe = false; 381 382 evlist__for_each_entry(session->evlist, evsel) { 383 not_pipe = true; 384 if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) { 385 use_callchain = true; 386 break; 387 } 388 } 389 if (not_pipe && !use_callchain) 390 symbol_conf.use_callchain = false; 391 } 392 393 /* 394 * set default for tracepoints to print symbols only 395 * if callchains are present 396 */ 397 if (symbol_conf.use_callchain && 398 !output[PERF_TYPE_TRACEPOINT].user_set) { 399 struct perf_event_attr *attr; 400 401 j = PERF_TYPE_TRACEPOINT; 402 403 evlist__for_each_entry(session->evlist, evsel) { 404 if (evsel->attr.type != j) 405 continue; 406 407 attr = &evsel->attr; 408 409 if (attr->sample_type & PERF_SAMPLE_CALLCHAIN) { 410 output[j].fields |= PERF_OUTPUT_IP; 411 output[j].fields |= PERF_OUTPUT_SYM; 412 output[j].fields |= PERF_OUTPUT_DSO; 413 set_print_ip_opts(attr); 414 goto out; 415 } 416 } 417 } 418 419 out: 420 return 0; 421 } 422 423 static void print_sample_iregs(struct perf_sample *sample, 424 struct perf_event_attr *attr) 425 { 426 struct regs_dump *regs = &sample->intr_regs; 427 uint64_t mask = attr->sample_regs_intr; 428 unsigned i = 0, r; 429 430 if (!regs) 431 return; 432 433 for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { 434 u64 val = regs->regs[i++]; 435 printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val); 436 } 437 } 438 439 static void print_sample_start(struct perf_sample *sample, 440 struct thread *thread, 441 struct perf_evsel *evsel) 442 { 443 struct perf_event_attr *attr = &evsel->attr; 444 unsigned long secs; 445 unsigned long long nsecs; 446 447 if (PRINT_FIELD(COMM)) { 448 if (latency_format) 449 printf("%8.8s ", thread__comm_str(thread)); 450 else if (PRINT_FIELD(IP) && symbol_conf.use_callchain) 451 printf("%s ", thread__comm_str(thread)); 452 else 453 printf("%16s ", thread__comm_str(thread)); 454 } 455 456 if (PRINT_FIELD(PID) && PRINT_FIELD(TID)) 457 printf("%5d/%-5d ", sample->pid, sample->tid); 458 else if (PRINT_FIELD(PID)) 459 printf("%5d ", sample->pid); 460 else if (PRINT_FIELD(TID)) 461 printf("%5d ", sample->tid); 462 463 if (PRINT_FIELD(CPU)) { 464 if (latency_format) 465 printf("%3d ", sample->cpu); 466 else 467 printf("[%03d] ", sample->cpu); 468 } 469 470 if (PRINT_FIELD(TIME)) { 471 nsecs = sample->time; 472 secs = nsecs / NSEC_PER_SEC; 473 nsecs -= secs * NSEC_PER_SEC; 474 475 if (nanosecs) 476 printf("%5lu.%09llu: ", secs, nsecs); 477 else { 478 char sample_time[32]; 479 timestamp__scnprintf_usec(sample->time, sample_time, sizeof(sample_time)); 480 printf("%12s: ", sample_time); 481 } 482 } 483 } 484 485 static inline char 486 mispred_str(struct branch_entry *br) 487 { 488 if (!(br->flags.mispred || br->flags.predicted)) 489 return '-'; 490 491 return br->flags.predicted ? 'P' : 'M'; 492 } 493 494 static void print_sample_brstack(struct perf_sample *sample) 495 { 496 struct branch_stack *br = sample->branch_stack; 497 u64 i; 498 499 if (!(br && br->nr)) 500 return; 501 502 for (i = 0; i < br->nr; i++) { 503 printf(" 0x%"PRIx64"/0x%"PRIx64"/%c/%c/%c/%d ", 504 br->entries[i].from, 505 br->entries[i].to, 506 mispred_str( br->entries + i), 507 br->entries[i].flags.in_tx? 'X' : '-', 508 br->entries[i].flags.abort? 'A' : '-', 509 br->entries[i].flags.cycles); 510 } 511 } 512 513 static void print_sample_brstacksym(struct perf_sample *sample, 514 struct thread *thread) 515 { 516 struct branch_stack *br = sample->branch_stack; 517 struct addr_location alf, alt; 518 u64 i, from, to; 519 520 if (!(br && br->nr)) 521 return; 522 523 for (i = 0; i < br->nr; i++) { 524 525 memset(&alf, 0, sizeof(alf)); 526 memset(&alt, 0, sizeof(alt)); 527 from = br->entries[i].from; 528 to = br->entries[i].to; 529 530 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf); 531 if (alf.map) 532 alf.sym = map__find_symbol(alf.map, alf.addr); 533 534 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt); 535 if (alt.map) 536 alt.sym = map__find_symbol(alt.map, alt.addr); 537 538 symbol__fprintf_symname_offs(alf.sym, &alf, stdout); 539 putchar('/'); 540 symbol__fprintf_symname_offs(alt.sym, &alt, stdout); 541 printf("/%c/%c/%c/%d ", 542 mispred_str( br->entries + i), 543 br->entries[i].flags.in_tx? 'X' : '-', 544 br->entries[i].flags.abort? 'A' : '-', 545 br->entries[i].flags.cycles); 546 } 547 } 548 549 550 static void print_sample_addr(struct perf_sample *sample, 551 struct thread *thread, 552 struct perf_event_attr *attr) 553 { 554 struct addr_location al; 555 556 printf("%16" PRIx64, sample->addr); 557 558 if (!sample_addr_correlates_sym(attr)) 559 return; 560 561 thread__resolve(thread, &al, sample); 562 563 if (PRINT_FIELD(SYM)) { 564 printf(" "); 565 if (PRINT_FIELD(SYMOFFSET)) 566 symbol__fprintf_symname_offs(al.sym, &al, stdout); 567 else 568 symbol__fprintf_symname(al.sym, stdout); 569 } 570 571 if (PRINT_FIELD(DSO)) { 572 printf(" ("); 573 map__fprintf_dsoname(al.map, stdout); 574 printf(")"); 575 } 576 } 577 578 static void print_sample_callindent(struct perf_sample *sample, 579 struct perf_evsel *evsel, 580 struct thread *thread, 581 struct addr_location *al) 582 { 583 struct perf_event_attr *attr = &evsel->attr; 584 size_t depth = thread_stack__depth(thread); 585 struct addr_location addr_al; 586 const char *name = NULL; 587 static int spacing; 588 int len = 0; 589 u64 ip = 0; 590 591 /* 592 * The 'return' has already been popped off the stack so the depth has 593 * to be adjusted to match the 'call'. 594 */ 595 if (thread->ts && sample->flags & PERF_IP_FLAG_RETURN) 596 depth += 1; 597 598 if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) { 599 if (sample_addr_correlates_sym(attr)) { 600 thread__resolve(thread, &addr_al, sample); 601 if (addr_al.sym) 602 name = addr_al.sym->name; 603 else 604 ip = sample->addr; 605 } else { 606 ip = sample->addr; 607 } 608 } else if (sample->flags & (PERF_IP_FLAG_RETURN | PERF_IP_FLAG_TRACE_END)) { 609 if (al->sym) 610 name = al->sym->name; 611 else 612 ip = sample->ip; 613 } 614 615 if (name) 616 len = printf("%*s%s", (int)depth * 4, "", name); 617 else if (ip) 618 len = printf("%*s%16" PRIx64, (int)depth * 4, "", ip); 619 620 if (len < 0) 621 return; 622 623 /* 624 * Try to keep the output length from changing frequently so that the 625 * output lines up more nicely. 626 */ 627 if (len > spacing || (len && len < spacing - 52)) 628 spacing = round_up(len + 4, 32); 629 630 if (len < spacing) 631 printf("%*s", spacing - len, ""); 632 } 633 634 static void print_insn(struct perf_sample *sample, 635 struct perf_event_attr *attr) 636 { 637 if (PRINT_FIELD(INSNLEN)) 638 printf(" ilen: %d", sample->insn_len); 639 if (PRINT_FIELD(INSN)) { 640 int i; 641 642 printf(" insn:"); 643 for (i = 0; i < sample->insn_len; i++) 644 printf(" %02x", (unsigned char)sample->insn[i]); 645 } 646 } 647 648 static void print_sample_bts(struct perf_sample *sample, 649 struct perf_evsel *evsel, 650 struct thread *thread, 651 struct addr_location *al) 652 { 653 struct perf_event_attr *attr = &evsel->attr; 654 bool print_srcline_last = false; 655 656 if (PRINT_FIELD(CALLINDENT)) 657 print_sample_callindent(sample, evsel, thread, al); 658 659 /* print branch_from information */ 660 if (PRINT_FIELD(IP)) { 661 unsigned int print_opts = output[attr->type].print_ip_opts; 662 struct callchain_cursor *cursor = NULL; 663 664 if (symbol_conf.use_callchain && sample->callchain && 665 thread__resolve_callchain(al->thread, &callchain_cursor, evsel, 666 sample, NULL, NULL, scripting_max_stack) == 0) 667 cursor = &callchain_cursor; 668 669 if (cursor == NULL) { 670 putchar(' '); 671 if (print_opts & EVSEL__PRINT_SRCLINE) { 672 print_srcline_last = true; 673 print_opts &= ~EVSEL__PRINT_SRCLINE; 674 } 675 } else 676 putchar('\n'); 677 678 sample__fprintf_sym(sample, al, 0, print_opts, cursor, stdout); 679 } 680 681 /* print branch_to information */ 682 if (PRINT_FIELD(ADDR) || 683 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && 684 !output[attr->type].user_set)) { 685 printf(" => "); 686 print_sample_addr(sample, thread, attr); 687 } 688 689 if (print_srcline_last) 690 map__fprintf_srcline(al->map, al->addr, "\n ", stdout); 691 692 print_insn(sample, attr); 693 694 printf("\n"); 695 } 696 697 static struct { 698 u32 flags; 699 const char *name; 700 } sample_flags[] = { 701 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"}, 702 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"}, 703 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"}, 704 {PERF_IP_FLAG_BRANCH, "jmp"}, 705 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"}, 706 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"}, 707 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"}, 708 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"}, 709 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"}, 710 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT, "hw int"}, 711 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"}, 712 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"}, 713 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"}, 714 {0, NULL} 715 }; 716 717 static void print_sample_flags(u32 flags) 718 { 719 const char *chars = PERF_IP_FLAG_CHARS; 720 const int n = strlen(PERF_IP_FLAG_CHARS); 721 bool in_tx = flags & PERF_IP_FLAG_IN_TX; 722 const char *name = NULL; 723 char str[33]; 724 int i, pos = 0; 725 726 for (i = 0; sample_flags[i].name ; i++) { 727 if (sample_flags[i].flags == (flags & ~PERF_IP_FLAG_IN_TX)) { 728 name = sample_flags[i].name; 729 break; 730 } 731 } 732 733 for (i = 0; i < n; i++, flags >>= 1) { 734 if (flags & 1) 735 str[pos++] = chars[i]; 736 } 737 for (; i < 32; i++, flags >>= 1) { 738 if (flags & 1) 739 str[pos++] = '?'; 740 } 741 str[pos] = 0; 742 743 if (name) 744 printf(" %-7s%4s ", name, in_tx ? "(x)" : ""); 745 else 746 printf(" %-11s ", str); 747 } 748 749 struct printer_data { 750 int line_no; 751 bool hit_nul; 752 bool is_printable; 753 }; 754 755 static void 756 print_sample_bpf_output_printer(enum binary_printer_ops op, 757 unsigned int val, 758 void *extra) 759 { 760 unsigned char ch = (unsigned char)val; 761 struct printer_data *printer_data = extra; 762 763 switch (op) { 764 case BINARY_PRINT_DATA_BEGIN: 765 printf("\n"); 766 break; 767 case BINARY_PRINT_LINE_BEGIN: 768 printf("%17s", !printer_data->line_no ? "BPF output:" : 769 " "); 770 break; 771 case BINARY_PRINT_ADDR: 772 printf(" %04x:", val); 773 break; 774 case BINARY_PRINT_NUM_DATA: 775 printf(" %02x", val); 776 break; 777 case BINARY_PRINT_NUM_PAD: 778 printf(" "); 779 break; 780 case BINARY_PRINT_SEP: 781 printf(" "); 782 break; 783 case BINARY_PRINT_CHAR_DATA: 784 if (printer_data->hit_nul && ch) 785 printer_data->is_printable = false; 786 787 if (!isprint(ch)) { 788 printf("%c", '.'); 789 790 if (!printer_data->is_printable) 791 break; 792 793 if (ch == '\0') 794 printer_data->hit_nul = true; 795 else 796 printer_data->is_printable = false; 797 } else { 798 printf("%c", ch); 799 } 800 break; 801 case BINARY_PRINT_CHAR_PAD: 802 printf(" "); 803 break; 804 case BINARY_PRINT_LINE_END: 805 printf("\n"); 806 printer_data->line_no++; 807 break; 808 case BINARY_PRINT_DATA_END: 809 default: 810 break; 811 } 812 } 813 814 static void print_sample_bpf_output(struct perf_sample *sample) 815 { 816 unsigned int nr_bytes = sample->raw_size; 817 struct printer_data printer_data = {0, false, true}; 818 819 print_binary(sample->raw_data, nr_bytes, 8, 820 print_sample_bpf_output_printer, &printer_data); 821 822 if (printer_data.is_printable && printer_data.hit_nul) 823 printf("%17s \"%s\"\n", "BPF string:", 824 (char *)(sample->raw_data)); 825 } 826 827 struct perf_script { 828 struct perf_tool tool; 829 struct perf_session *session; 830 bool show_task_events; 831 bool show_mmap_events; 832 bool show_switch_events; 833 bool allocated; 834 struct cpu_map *cpus; 835 struct thread_map *threads; 836 int name_width; 837 const char *time_str; 838 struct perf_time_interval ptime; 839 }; 840 841 static int perf_evlist__max_name_len(struct perf_evlist *evlist) 842 { 843 struct perf_evsel *evsel; 844 int max = 0; 845 846 evlist__for_each_entry(evlist, evsel) { 847 int len = strlen(perf_evsel__name(evsel)); 848 849 max = MAX(len, max); 850 } 851 852 return max; 853 } 854 855 static size_t data_src__printf(u64 data_src) 856 { 857 struct mem_info mi = { .data_src.val = data_src }; 858 char decode[100]; 859 char out[100]; 860 static int maxlen; 861 int len; 862 863 perf_script__meminfo_scnprintf(decode, 100, &mi); 864 865 len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode); 866 if (maxlen < len) 867 maxlen = len; 868 869 return printf("%-*s", maxlen, out); 870 } 871 872 static void process_event(struct perf_script *script, 873 struct perf_sample *sample, struct perf_evsel *evsel, 874 struct addr_location *al) 875 { 876 struct thread *thread = al->thread; 877 struct perf_event_attr *attr = &evsel->attr; 878 879 if (output[attr->type].fields == 0) 880 return; 881 882 print_sample_start(sample, thread, evsel); 883 884 if (PRINT_FIELD(PERIOD)) 885 printf("%10" PRIu64 " ", sample->period); 886 887 if (PRINT_FIELD(EVNAME)) { 888 const char *evname = perf_evsel__name(evsel); 889 890 if (!script->name_width) 891 script->name_width = perf_evlist__max_name_len(script->session->evlist); 892 893 printf("%*s: ", script->name_width, 894 evname ? evname : "[unknown]"); 895 } 896 897 if (print_flags) 898 print_sample_flags(sample->flags); 899 900 if (is_bts_event(attr)) { 901 print_sample_bts(sample, evsel, thread, al); 902 return; 903 } 904 905 if (PRINT_FIELD(TRACE)) 906 event_format__print(evsel->tp_format, sample->cpu, 907 sample->raw_data, sample->raw_size); 908 if (PRINT_FIELD(ADDR)) 909 print_sample_addr(sample, thread, attr); 910 911 if (PRINT_FIELD(DATA_SRC)) 912 data_src__printf(sample->data_src); 913 914 if (PRINT_FIELD(WEIGHT)) 915 printf("%16" PRIu64, sample->weight); 916 917 if (PRINT_FIELD(IP)) { 918 struct callchain_cursor *cursor = NULL; 919 920 if (symbol_conf.use_callchain && sample->callchain && 921 thread__resolve_callchain(al->thread, &callchain_cursor, evsel, 922 sample, NULL, NULL, scripting_max_stack) == 0) 923 cursor = &callchain_cursor; 924 925 putchar(cursor ? '\n' : ' '); 926 sample__fprintf_sym(sample, al, 0, output[attr->type].print_ip_opts, cursor, stdout); 927 } 928 929 if (PRINT_FIELD(IREGS)) 930 print_sample_iregs(sample, attr); 931 932 if (PRINT_FIELD(BRSTACK)) 933 print_sample_brstack(sample); 934 else if (PRINT_FIELD(BRSTACKSYM)) 935 print_sample_brstacksym(sample, thread); 936 937 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) 938 print_sample_bpf_output(sample); 939 print_insn(sample, attr); 940 printf("\n"); 941 } 942 943 static struct scripting_ops *scripting_ops; 944 945 static void __process_stat(struct perf_evsel *counter, u64 tstamp) 946 { 947 int nthreads = thread_map__nr(counter->threads); 948 int ncpus = perf_evsel__nr_cpus(counter); 949 int cpu, thread; 950 static int header_printed; 951 952 if (counter->system_wide) 953 nthreads = 1; 954 955 if (!header_printed) { 956 printf("%3s %8s %15s %15s %15s %15s %s\n", 957 "CPU", "THREAD", "VAL", "ENA", "RUN", "TIME", "EVENT"); 958 header_printed = 1; 959 } 960 961 for (thread = 0; thread < nthreads; thread++) { 962 for (cpu = 0; cpu < ncpus; cpu++) { 963 struct perf_counts_values *counts; 964 965 counts = perf_counts(counter->counts, cpu, thread); 966 967 printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n", 968 counter->cpus->map[cpu], 969 thread_map__pid(counter->threads, thread), 970 counts->val, 971 counts->ena, 972 counts->run, 973 tstamp, 974 perf_evsel__name(counter)); 975 } 976 } 977 } 978 979 static void process_stat(struct perf_evsel *counter, u64 tstamp) 980 { 981 if (scripting_ops && scripting_ops->process_stat) 982 scripting_ops->process_stat(&stat_config, counter, tstamp); 983 else 984 __process_stat(counter, tstamp); 985 } 986 987 static void process_stat_interval(u64 tstamp) 988 { 989 if (scripting_ops && scripting_ops->process_stat_interval) 990 scripting_ops->process_stat_interval(tstamp); 991 } 992 993 static void setup_scripting(void) 994 { 995 setup_perl_scripting(); 996 setup_python_scripting(); 997 } 998 999 static int flush_scripting(void) 1000 { 1001 return scripting_ops ? scripting_ops->flush_script() : 0; 1002 } 1003 1004 static int cleanup_scripting(void) 1005 { 1006 pr_debug("\nperf script stopped\n"); 1007 1008 return scripting_ops ? scripting_ops->stop_script() : 0; 1009 } 1010 1011 static int process_sample_event(struct perf_tool *tool, 1012 union perf_event *event, 1013 struct perf_sample *sample, 1014 struct perf_evsel *evsel, 1015 struct machine *machine) 1016 { 1017 struct perf_script *scr = container_of(tool, struct perf_script, tool); 1018 struct addr_location al; 1019 1020 if (perf_time__skip_sample(&scr->ptime, sample->time)) 1021 return 0; 1022 1023 if (debug_mode) { 1024 if (sample->time < last_timestamp) { 1025 pr_err("Samples misordered, previous: %" PRIu64 1026 " this: %" PRIu64 "\n", last_timestamp, 1027 sample->time); 1028 nr_unordered++; 1029 } 1030 last_timestamp = sample->time; 1031 return 0; 1032 } 1033 1034 if (machine__resolve(machine, &al, sample) < 0) { 1035 pr_err("problem processing %d event, skipping it.\n", 1036 event->header.type); 1037 return -1; 1038 } 1039 1040 if (al.filtered) 1041 goto out_put; 1042 1043 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) 1044 goto out_put; 1045 1046 if (scripting_ops) 1047 scripting_ops->process_event(event, sample, evsel, &al); 1048 else 1049 process_event(scr, sample, evsel, &al); 1050 1051 out_put: 1052 addr_location__put(&al); 1053 return 0; 1054 } 1055 1056 static int process_attr(struct perf_tool *tool, union perf_event *event, 1057 struct perf_evlist **pevlist) 1058 { 1059 struct perf_script *scr = container_of(tool, struct perf_script, tool); 1060 struct perf_evlist *evlist; 1061 struct perf_evsel *evsel, *pos; 1062 int err; 1063 1064 err = perf_event__process_attr(tool, event, pevlist); 1065 if (err) 1066 return err; 1067 1068 evlist = *pevlist; 1069 evsel = perf_evlist__last(*pevlist); 1070 1071 if (evsel->attr.type >= PERF_TYPE_MAX) 1072 return 0; 1073 1074 evlist__for_each_entry(evlist, pos) { 1075 if (pos->attr.type == evsel->attr.type && pos != evsel) 1076 return 0; 1077 } 1078 1079 set_print_ip_opts(&evsel->attr); 1080 1081 if (evsel->attr.sample_type) 1082 err = perf_evsel__check_attr(evsel, scr->session); 1083 1084 return err; 1085 } 1086 1087 static int process_comm_event(struct perf_tool *tool, 1088 union perf_event *event, 1089 struct perf_sample *sample, 1090 struct machine *machine) 1091 { 1092 struct thread *thread; 1093 struct perf_script *script = container_of(tool, struct perf_script, tool); 1094 struct perf_session *session = script->session; 1095 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1096 int ret = -1; 1097 1098 thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid); 1099 if (thread == NULL) { 1100 pr_debug("problem processing COMM event, skipping it.\n"); 1101 return -1; 1102 } 1103 1104 if (perf_event__process_comm(tool, event, sample, machine) < 0) 1105 goto out; 1106 1107 if (!evsel->attr.sample_id_all) { 1108 sample->cpu = 0; 1109 sample->time = 0; 1110 sample->tid = event->comm.tid; 1111 sample->pid = event->comm.pid; 1112 } 1113 print_sample_start(sample, thread, evsel); 1114 perf_event__fprintf(event, stdout); 1115 ret = 0; 1116 out: 1117 thread__put(thread); 1118 return ret; 1119 } 1120 1121 static int process_fork_event(struct perf_tool *tool, 1122 union perf_event *event, 1123 struct perf_sample *sample, 1124 struct machine *machine) 1125 { 1126 struct thread *thread; 1127 struct perf_script *script = container_of(tool, struct perf_script, tool); 1128 struct perf_session *session = script->session; 1129 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1130 1131 if (perf_event__process_fork(tool, event, sample, machine) < 0) 1132 return -1; 1133 1134 thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); 1135 if (thread == NULL) { 1136 pr_debug("problem processing FORK event, skipping it.\n"); 1137 return -1; 1138 } 1139 1140 if (!evsel->attr.sample_id_all) { 1141 sample->cpu = 0; 1142 sample->time = event->fork.time; 1143 sample->tid = event->fork.tid; 1144 sample->pid = event->fork.pid; 1145 } 1146 print_sample_start(sample, thread, evsel); 1147 perf_event__fprintf(event, stdout); 1148 thread__put(thread); 1149 1150 return 0; 1151 } 1152 static int process_exit_event(struct perf_tool *tool, 1153 union perf_event *event, 1154 struct perf_sample *sample, 1155 struct machine *machine) 1156 { 1157 int err = 0; 1158 struct thread *thread; 1159 struct perf_script *script = container_of(tool, struct perf_script, tool); 1160 struct perf_session *session = script->session; 1161 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1162 1163 thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); 1164 if (thread == NULL) { 1165 pr_debug("problem processing EXIT event, skipping it.\n"); 1166 return -1; 1167 } 1168 1169 if (!evsel->attr.sample_id_all) { 1170 sample->cpu = 0; 1171 sample->time = 0; 1172 sample->tid = event->fork.tid; 1173 sample->pid = event->fork.pid; 1174 } 1175 print_sample_start(sample, thread, evsel); 1176 perf_event__fprintf(event, stdout); 1177 1178 if (perf_event__process_exit(tool, event, sample, machine) < 0) 1179 err = -1; 1180 1181 thread__put(thread); 1182 return err; 1183 } 1184 1185 static int process_mmap_event(struct perf_tool *tool, 1186 union perf_event *event, 1187 struct perf_sample *sample, 1188 struct machine *machine) 1189 { 1190 struct thread *thread; 1191 struct perf_script *script = container_of(tool, struct perf_script, tool); 1192 struct perf_session *session = script->session; 1193 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1194 1195 if (perf_event__process_mmap(tool, event, sample, machine) < 0) 1196 return -1; 1197 1198 thread = machine__findnew_thread(machine, event->mmap.pid, event->mmap.tid); 1199 if (thread == NULL) { 1200 pr_debug("problem processing MMAP event, skipping it.\n"); 1201 return -1; 1202 } 1203 1204 if (!evsel->attr.sample_id_all) { 1205 sample->cpu = 0; 1206 sample->time = 0; 1207 sample->tid = event->mmap.tid; 1208 sample->pid = event->mmap.pid; 1209 } 1210 print_sample_start(sample, thread, evsel); 1211 perf_event__fprintf(event, stdout); 1212 thread__put(thread); 1213 return 0; 1214 } 1215 1216 static int process_mmap2_event(struct perf_tool *tool, 1217 union perf_event *event, 1218 struct perf_sample *sample, 1219 struct machine *machine) 1220 { 1221 struct thread *thread; 1222 struct perf_script *script = container_of(tool, struct perf_script, tool); 1223 struct perf_session *session = script->session; 1224 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1225 1226 if (perf_event__process_mmap2(tool, event, sample, machine) < 0) 1227 return -1; 1228 1229 thread = machine__findnew_thread(machine, event->mmap2.pid, event->mmap2.tid); 1230 if (thread == NULL) { 1231 pr_debug("problem processing MMAP2 event, skipping it.\n"); 1232 return -1; 1233 } 1234 1235 if (!evsel->attr.sample_id_all) { 1236 sample->cpu = 0; 1237 sample->time = 0; 1238 sample->tid = event->mmap2.tid; 1239 sample->pid = event->mmap2.pid; 1240 } 1241 print_sample_start(sample, thread, evsel); 1242 perf_event__fprintf(event, stdout); 1243 thread__put(thread); 1244 return 0; 1245 } 1246 1247 static int process_switch_event(struct perf_tool *tool, 1248 union perf_event *event, 1249 struct perf_sample *sample, 1250 struct machine *machine) 1251 { 1252 struct thread *thread; 1253 struct perf_script *script = container_of(tool, struct perf_script, tool); 1254 struct perf_session *session = script->session; 1255 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1256 1257 if (perf_event__process_switch(tool, event, sample, machine) < 0) 1258 return -1; 1259 1260 thread = machine__findnew_thread(machine, sample->pid, 1261 sample->tid); 1262 if (thread == NULL) { 1263 pr_debug("problem processing SWITCH event, skipping it.\n"); 1264 return -1; 1265 } 1266 1267 print_sample_start(sample, thread, evsel); 1268 perf_event__fprintf(event, stdout); 1269 thread__put(thread); 1270 return 0; 1271 } 1272 1273 static void sig_handler(int sig __maybe_unused) 1274 { 1275 session_done = 1; 1276 } 1277 1278 static int __cmd_script(struct perf_script *script) 1279 { 1280 int ret; 1281 1282 signal(SIGINT, sig_handler); 1283 1284 /* override event processing functions */ 1285 if (script->show_task_events) { 1286 script->tool.comm = process_comm_event; 1287 script->tool.fork = process_fork_event; 1288 script->tool.exit = process_exit_event; 1289 } 1290 if (script->show_mmap_events) { 1291 script->tool.mmap = process_mmap_event; 1292 script->tool.mmap2 = process_mmap2_event; 1293 } 1294 if (script->show_switch_events) 1295 script->tool.context_switch = process_switch_event; 1296 1297 ret = perf_session__process_events(script->session); 1298 1299 if (debug_mode) 1300 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 1301 1302 return ret; 1303 } 1304 1305 struct script_spec { 1306 struct list_head node; 1307 struct scripting_ops *ops; 1308 char spec[0]; 1309 }; 1310 1311 static LIST_HEAD(script_specs); 1312 1313 static struct script_spec *script_spec__new(const char *spec, 1314 struct scripting_ops *ops) 1315 { 1316 struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1); 1317 1318 if (s != NULL) { 1319 strcpy(s->spec, spec); 1320 s->ops = ops; 1321 } 1322 1323 return s; 1324 } 1325 1326 static void script_spec__add(struct script_spec *s) 1327 { 1328 list_add_tail(&s->node, &script_specs); 1329 } 1330 1331 static struct script_spec *script_spec__find(const char *spec) 1332 { 1333 struct script_spec *s; 1334 1335 list_for_each_entry(s, &script_specs, node) 1336 if (strcasecmp(s->spec, spec) == 0) 1337 return s; 1338 return NULL; 1339 } 1340 1341 int script_spec_register(const char *spec, struct scripting_ops *ops) 1342 { 1343 struct script_spec *s; 1344 1345 s = script_spec__find(spec); 1346 if (s) 1347 return -1; 1348 1349 s = script_spec__new(spec, ops); 1350 if (!s) 1351 return -1; 1352 else 1353 script_spec__add(s); 1354 1355 return 0; 1356 } 1357 1358 static struct scripting_ops *script_spec__lookup(const char *spec) 1359 { 1360 struct script_spec *s = script_spec__find(spec); 1361 if (!s) 1362 return NULL; 1363 1364 return s->ops; 1365 } 1366 1367 static void list_available_languages(void) 1368 { 1369 struct script_spec *s; 1370 1371 fprintf(stderr, "\n"); 1372 fprintf(stderr, "Scripting language extensions (used in " 1373 "perf script -s [spec:]script.[spec]):\n\n"); 1374 1375 list_for_each_entry(s, &script_specs, node) 1376 fprintf(stderr, " %-42s [%s]\n", s->spec, s->ops->name); 1377 1378 fprintf(stderr, "\n"); 1379 } 1380 1381 static int parse_scriptname(const struct option *opt __maybe_unused, 1382 const char *str, int unset __maybe_unused) 1383 { 1384 char spec[PATH_MAX]; 1385 const char *script, *ext; 1386 int len; 1387 1388 if (strcmp(str, "lang") == 0) { 1389 list_available_languages(); 1390 exit(0); 1391 } 1392 1393 script = strchr(str, ':'); 1394 if (script) { 1395 len = script - str; 1396 if (len >= PATH_MAX) { 1397 fprintf(stderr, "invalid language specifier"); 1398 return -1; 1399 } 1400 strncpy(spec, str, len); 1401 spec[len] = '\0'; 1402 scripting_ops = script_spec__lookup(spec); 1403 if (!scripting_ops) { 1404 fprintf(stderr, "invalid language specifier"); 1405 return -1; 1406 } 1407 script++; 1408 } else { 1409 script = str; 1410 ext = strrchr(script, '.'); 1411 if (!ext) { 1412 fprintf(stderr, "invalid script extension"); 1413 return -1; 1414 } 1415 scripting_ops = script_spec__lookup(++ext); 1416 if (!scripting_ops) { 1417 fprintf(stderr, "invalid script extension"); 1418 return -1; 1419 } 1420 } 1421 1422 script_name = strdup(script); 1423 1424 return 0; 1425 } 1426 1427 static int parse_output_fields(const struct option *opt __maybe_unused, 1428 const char *arg, int unset __maybe_unused) 1429 { 1430 char *tok; 1431 int i, imax = ARRAY_SIZE(all_output_options); 1432 int j; 1433 int rc = 0; 1434 char *str = strdup(arg); 1435 int type = -1; 1436 1437 if (!str) 1438 return -ENOMEM; 1439 1440 /* first word can state for which event type the user is specifying 1441 * the fields. If no type exists, the specified fields apply to all 1442 * event types found in the file minus the invalid fields for a type. 1443 */ 1444 tok = strchr(str, ':'); 1445 if (tok) { 1446 *tok = '\0'; 1447 tok++; 1448 if (!strcmp(str, "hw")) 1449 type = PERF_TYPE_HARDWARE; 1450 else if (!strcmp(str, "sw")) 1451 type = PERF_TYPE_SOFTWARE; 1452 else if (!strcmp(str, "trace")) 1453 type = PERF_TYPE_TRACEPOINT; 1454 else if (!strcmp(str, "raw")) 1455 type = PERF_TYPE_RAW; 1456 else if (!strcmp(str, "break")) 1457 type = PERF_TYPE_BREAKPOINT; 1458 else { 1459 fprintf(stderr, "Invalid event type in field string.\n"); 1460 rc = -EINVAL; 1461 goto out; 1462 } 1463 1464 if (output[type].user_set) 1465 pr_warning("Overriding previous field request for %s events.\n", 1466 event_type(type)); 1467 1468 output[type].fields = 0; 1469 output[type].user_set = true; 1470 output[type].wildcard_set = false; 1471 1472 } else { 1473 tok = str; 1474 if (strlen(str) == 0) { 1475 fprintf(stderr, 1476 "Cannot set fields to 'none' for all event types.\n"); 1477 rc = -EINVAL; 1478 goto out; 1479 } 1480 1481 if (output_set_by_user()) 1482 pr_warning("Overriding previous field request for all events.\n"); 1483 1484 for (j = 0; j < PERF_TYPE_MAX; ++j) { 1485 output[j].fields = 0; 1486 output[j].user_set = true; 1487 output[j].wildcard_set = true; 1488 } 1489 } 1490 1491 for (tok = strtok(tok, ","); tok; tok = strtok(NULL, ",")) { 1492 for (i = 0; i < imax; ++i) { 1493 if (strcmp(tok, all_output_options[i].str) == 0) 1494 break; 1495 } 1496 if (i == imax && strcmp(tok, "flags") == 0) { 1497 print_flags = true; 1498 continue; 1499 } 1500 if (i == imax) { 1501 fprintf(stderr, "Invalid field requested.\n"); 1502 rc = -EINVAL; 1503 goto out; 1504 } 1505 1506 if (type == -1) { 1507 /* add user option to all events types for 1508 * which it is valid 1509 */ 1510 for (j = 0; j < PERF_TYPE_MAX; ++j) { 1511 if (output[j].invalid_fields & all_output_options[i].field) { 1512 pr_warning("\'%s\' not valid for %s events. Ignoring.\n", 1513 all_output_options[i].str, event_type(j)); 1514 } else 1515 output[j].fields |= all_output_options[i].field; 1516 } 1517 } else { 1518 if (output[type].invalid_fields & all_output_options[i].field) { 1519 fprintf(stderr, "\'%s\' not valid for %s events.\n", 1520 all_output_options[i].str, event_type(type)); 1521 1522 rc = -EINVAL; 1523 goto out; 1524 } 1525 output[type].fields |= all_output_options[i].field; 1526 } 1527 } 1528 1529 if (type >= 0) { 1530 if (output[type].fields == 0) { 1531 pr_debug("No fields requested for %s type. " 1532 "Events will not be displayed.\n", event_type(type)); 1533 } 1534 } 1535 1536 out: 1537 free(str); 1538 return rc; 1539 } 1540 1541 /* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */ 1542 static int is_directory(const char *base_path, const struct dirent *dent) 1543 { 1544 char path[PATH_MAX]; 1545 struct stat st; 1546 1547 sprintf(path, "%s/%s", base_path, dent->d_name); 1548 if (stat(path, &st)) 1549 return 0; 1550 1551 return S_ISDIR(st.st_mode); 1552 } 1553 1554 #define for_each_lang(scripts_path, scripts_dir, lang_dirent) \ 1555 while ((lang_dirent = readdir(scripts_dir)) != NULL) \ 1556 if ((lang_dirent->d_type == DT_DIR || \ 1557 (lang_dirent->d_type == DT_UNKNOWN && \ 1558 is_directory(scripts_path, lang_dirent))) && \ 1559 (strcmp(lang_dirent->d_name, ".")) && \ 1560 (strcmp(lang_dirent->d_name, ".."))) 1561 1562 #define for_each_script(lang_path, lang_dir, script_dirent) \ 1563 while ((script_dirent = readdir(lang_dir)) != NULL) \ 1564 if (script_dirent->d_type != DT_DIR && \ 1565 (script_dirent->d_type != DT_UNKNOWN || \ 1566 !is_directory(lang_path, script_dirent))) 1567 1568 1569 #define RECORD_SUFFIX "-record" 1570 #define REPORT_SUFFIX "-report" 1571 1572 struct script_desc { 1573 struct list_head node; 1574 char *name; 1575 char *half_liner; 1576 char *args; 1577 }; 1578 1579 static LIST_HEAD(script_descs); 1580 1581 static struct script_desc *script_desc__new(const char *name) 1582 { 1583 struct script_desc *s = zalloc(sizeof(*s)); 1584 1585 if (s != NULL && name) 1586 s->name = strdup(name); 1587 1588 return s; 1589 } 1590 1591 static void script_desc__delete(struct script_desc *s) 1592 { 1593 zfree(&s->name); 1594 zfree(&s->half_liner); 1595 zfree(&s->args); 1596 free(s); 1597 } 1598 1599 static void script_desc__add(struct script_desc *s) 1600 { 1601 list_add_tail(&s->node, &script_descs); 1602 } 1603 1604 static struct script_desc *script_desc__find(const char *name) 1605 { 1606 struct script_desc *s; 1607 1608 list_for_each_entry(s, &script_descs, node) 1609 if (strcasecmp(s->name, name) == 0) 1610 return s; 1611 return NULL; 1612 } 1613 1614 static struct script_desc *script_desc__findnew(const char *name) 1615 { 1616 struct script_desc *s = script_desc__find(name); 1617 1618 if (s) 1619 return s; 1620 1621 s = script_desc__new(name); 1622 if (!s) 1623 goto out_delete_desc; 1624 1625 script_desc__add(s); 1626 1627 return s; 1628 1629 out_delete_desc: 1630 script_desc__delete(s); 1631 1632 return NULL; 1633 } 1634 1635 static const char *ends_with(const char *str, const char *suffix) 1636 { 1637 size_t suffix_len = strlen(suffix); 1638 const char *p = str; 1639 1640 if (strlen(str) > suffix_len) { 1641 p = str + strlen(str) - suffix_len; 1642 if (!strncmp(p, suffix, suffix_len)) 1643 return p; 1644 } 1645 1646 return NULL; 1647 } 1648 1649 static int read_script_info(struct script_desc *desc, const char *filename) 1650 { 1651 char line[BUFSIZ], *p; 1652 FILE *fp; 1653 1654 fp = fopen(filename, "r"); 1655 if (!fp) 1656 return -1; 1657 1658 while (fgets(line, sizeof(line), fp)) { 1659 p = ltrim(line); 1660 if (strlen(p) == 0) 1661 continue; 1662 if (*p != '#') 1663 continue; 1664 p++; 1665 if (strlen(p) && *p == '!') 1666 continue; 1667 1668 p = ltrim(p); 1669 if (strlen(p) && p[strlen(p) - 1] == '\n') 1670 p[strlen(p) - 1] = '\0'; 1671 1672 if (!strncmp(p, "description:", strlen("description:"))) { 1673 p += strlen("description:"); 1674 desc->half_liner = strdup(ltrim(p)); 1675 continue; 1676 } 1677 1678 if (!strncmp(p, "args:", strlen("args:"))) { 1679 p += strlen("args:"); 1680 desc->args = strdup(ltrim(p)); 1681 continue; 1682 } 1683 } 1684 1685 fclose(fp); 1686 1687 return 0; 1688 } 1689 1690 static char *get_script_root(struct dirent *script_dirent, const char *suffix) 1691 { 1692 char *script_root, *str; 1693 1694 script_root = strdup(script_dirent->d_name); 1695 if (!script_root) 1696 return NULL; 1697 1698 str = (char *)ends_with(script_root, suffix); 1699 if (!str) { 1700 free(script_root); 1701 return NULL; 1702 } 1703 1704 *str = '\0'; 1705 return script_root; 1706 } 1707 1708 static int list_available_scripts(const struct option *opt __maybe_unused, 1709 const char *s __maybe_unused, 1710 int unset __maybe_unused) 1711 { 1712 struct dirent *script_dirent, *lang_dirent; 1713 char scripts_path[MAXPATHLEN]; 1714 DIR *scripts_dir, *lang_dir; 1715 char script_path[MAXPATHLEN]; 1716 char lang_path[MAXPATHLEN]; 1717 struct script_desc *desc; 1718 char first_half[BUFSIZ]; 1719 char *script_root; 1720 1721 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); 1722 1723 scripts_dir = opendir(scripts_path); 1724 if (!scripts_dir) { 1725 fprintf(stdout, 1726 "open(%s) failed.\n" 1727 "Check \"PERF_EXEC_PATH\" env to set scripts dir.\n", 1728 scripts_path); 1729 exit(-1); 1730 } 1731 1732 for_each_lang(scripts_path, scripts_dir, lang_dirent) { 1733 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 1734 lang_dirent->d_name); 1735 lang_dir = opendir(lang_path); 1736 if (!lang_dir) 1737 continue; 1738 1739 for_each_script(lang_path, lang_dir, script_dirent) { 1740 script_root = get_script_root(script_dirent, REPORT_SUFFIX); 1741 if (script_root) { 1742 desc = script_desc__findnew(script_root); 1743 snprintf(script_path, MAXPATHLEN, "%s/%s", 1744 lang_path, script_dirent->d_name); 1745 read_script_info(desc, script_path); 1746 free(script_root); 1747 } 1748 } 1749 } 1750 1751 fprintf(stdout, "List of available trace scripts:\n"); 1752 list_for_each_entry(desc, &script_descs, node) { 1753 sprintf(first_half, "%s %s", desc->name, 1754 desc->args ? desc->args : ""); 1755 fprintf(stdout, " %-36s %s\n", first_half, 1756 desc->half_liner ? desc->half_liner : ""); 1757 } 1758 1759 exit(0); 1760 } 1761 1762 /* 1763 * Some scripts specify the required events in their "xxx-record" file, 1764 * this function will check if the events in perf.data match those 1765 * mentioned in the "xxx-record". 1766 * 1767 * Fixme: All existing "xxx-record" are all in good formats "-e event ", 1768 * which is covered well now. And new parsing code should be added to 1769 * cover the future complexing formats like event groups etc. 1770 */ 1771 static int check_ev_match(char *dir_name, char *scriptname, 1772 struct perf_session *session) 1773 { 1774 char filename[MAXPATHLEN], evname[128]; 1775 char line[BUFSIZ], *p; 1776 struct perf_evsel *pos; 1777 int match, len; 1778 FILE *fp; 1779 1780 sprintf(filename, "%s/bin/%s-record", dir_name, scriptname); 1781 1782 fp = fopen(filename, "r"); 1783 if (!fp) 1784 return -1; 1785 1786 while (fgets(line, sizeof(line), fp)) { 1787 p = ltrim(line); 1788 if (*p == '#') 1789 continue; 1790 1791 while (strlen(p)) { 1792 p = strstr(p, "-e"); 1793 if (!p) 1794 break; 1795 1796 p += 2; 1797 p = ltrim(p); 1798 len = strcspn(p, " \t"); 1799 if (!len) 1800 break; 1801 1802 snprintf(evname, len + 1, "%s", p); 1803 1804 match = 0; 1805 evlist__for_each_entry(session->evlist, pos) { 1806 if (!strcmp(perf_evsel__name(pos), evname)) { 1807 match = 1; 1808 break; 1809 } 1810 } 1811 1812 if (!match) { 1813 fclose(fp); 1814 return -1; 1815 } 1816 } 1817 } 1818 1819 fclose(fp); 1820 return 0; 1821 } 1822 1823 /* 1824 * Return -1 if none is found, otherwise the actual scripts number. 1825 * 1826 * Currently the only user of this function is the script browser, which 1827 * will list all statically runnable scripts, select one, execute it and 1828 * show the output in a perf browser. 1829 */ 1830 int find_scripts(char **scripts_array, char **scripts_path_array) 1831 { 1832 struct dirent *script_dirent, *lang_dirent; 1833 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; 1834 DIR *scripts_dir, *lang_dir; 1835 struct perf_session *session; 1836 struct perf_data_file file = { 1837 .path = input_name, 1838 .mode = PERF_DATA_MODE_READ, 1839 }; 1840 char *temp; 1841 int i = 0; 1842 1843 session = perf_session__new(&file, false, NULL); 1844 if (!session) 1845 return -1; 1846 1847 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); 1848 1849 scripts_dir = opendir(scripts_path); 1850 if (!scripts_dir) { 1851 perf_session__delete(session); 1852 return -1; 1853 } 1854 1855 for_each_lang(scripts_path, scripts_dir, lang_dirent) { 1856 snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, 1857 lang_dirent->d_name); 1858 #ifdef NO_LIBPERL 1859 if (strstr(lang_path, "perl")) 1860 continue; 1861 #endif 1862 #ifdef NO_LIBPYTHON 1863 if (strstr(lang_path, "python")) 1864 continue; 1865 #endif 1866 1867 lang_dir = opendir(lang_path); 1868 if (!lang_dir) 1869 continue; 1870 1871 for_each_script(lang_path, lang_dir, script_dirent) { 1872 /* Skip those real time scripts: xxxtop.p[yl] */ 1873 if (strstr(script_dirent->d_name, "top.")) 1874 continue; 1875 sprintf(scripts_path_array[i], "%s/%s", lang_path, 1876 script_dirent->d_name); 1877 temp = strchr(script_dirent->d_name, '.'); 1878 snprintf(scripts_array[i], 1879 (temp - script_dirent->d_name) + 1, 1880 "%s", script_dirent->d_name); 1881 1882 if (check_ev_match(lang_path, 1883 scripts_array[i], session)) 1884 continue; 1885 1886 i++; 1887 } 1888 closedir(lang_dir); 1889 } 1890 1891 closedir(scripts_dir); 1892 perf_session__delete(session); 1893 return i; 1894 } 1895 1896 static char *get_script_path(const char *script_root, const char *suffix) 1897 { 1898 struct dirent *script_dirent, *lang_dirent; 1899 char scripts_path[MAXPATHLEN]; 1900 char script_path[MAXPATHLEN]; 1901 DIR *scripts_dir, *lang_dir; 1902 char lang_path[MAXPATHLEN]; 1903 char *__script_root; 1904 1905 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); 1906 1907 scripts_dir = opendir(scripts_path); 1908 if (!scripts_dir) 1909 return NULL; 1910 1911 for_each_lang(scripts_path, scripts_dir, lang_dirent) { 1912 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 1913 lang_dirent->d_name); 1914 lang_dir = opendir(lang_path); 1915 if (!lang_dir) 1916 continue; 1917 1918 for_each_script(lang_path, lang_dir, script_dirent) { 1919 __script_root = get_script_root(script_dirent, suffix); 1920 if (__script_root && !strcmp(script_root, __script_root)) { 1921 free(__script_root); 1922 closedir(lang_dir); 1923 closedir(scripts_dir); 1924 snprintf(script_path, MAXPATHLEN, "%s/%s", 1925 lang_path, script_dirent->d_name); 1926 return strdup(script_path); 1927 } 1928 free(__script_root); 1929 } 1930 closedir(lang_dir); 1931 } 1932 closedir(scripts_dir); 1933 1934 return NULL; 1935 } 1936 1937 static bool is_top_script(const char *script_path) 1938 { 1939 return ends_with(script_path, "top") == NULL ? false : true; 1940 } 1941 1942 static int has_required_arg(char *script_path) 1943 { 1944 struct script_desc *desc; 1945 int n_args = 0; 1946 char *p; 1947 1948 desc = script_desc__new(NULL); 1949 1950 if (read_script_info(desc, script_path)) 1951 goto out; 1952 1953 if (!desc->args) 1954 goto out; 1955 1956 for (p = desc->args; *p; p++) 1957 if (*p == '<') 1958 n_args++; 1959 out: 1960 script_desc__delete(desc); 1961 1962 return n_args; 1963 } 1964 1965 static int have_cmd(int argc, const char **argv) 1966 { 1967 char **__argv = malloc(sizeof(const char *) * argc); 1968 1969 if (!__argv) { 1970 pr_err("malloc failed\n"); 1971 return -1; 1972 } 1973 1974 memcpy(__argv, argv, sizeof(const char *) * argc); 1975 argc = parse_options(argc, (const char **)__argv, record_options, 1976 NULL, PARSE_OPT_STOP_AT_NON_OPTION); 1977 free(__argv); 1978 1979 system_wide = (argc == 0); 1980 1981 return 0; 1982 } 1983 1984 static void script__setup_sample_type(struct perf_script *script) 1985 { 1986 struct perf_session *session = script->session; 1987 u64 sample_type = perf_evlist__combined_sample_type(session->evlist); 1988 1989 if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) { 1990 if ((sample_type & PERF_SAMPLE_REGS_USER) && 1991 (sample_type & PERF_SAMPLE_STACK_USER)) 1992 callchain_param.record_mode = CALLCHAIN_DWARF; 1993 else if (sample_type & PERF_SAMPLE_BRANCH_STACK) 1994 callchain_param.record_mode = CALLCHAIN_LBR; 1995 else 1996 callchain_param.record_mode = CALLCHAIN_FP; 1997 } 1998 } 1999 2000 static int process_stat_round_event(struct perf_tool *tool __maybe_unused, 2001 union perf_event *event, 2002 struct perf_session *session) 2003 { 2004 struct stat_round_event *round = &event->stat_round; 2005 struct perf_evsel *counter; 2006 2007 evlist__for_each_entry(session->evlist, counter) { 2008 perf_stat_process_counter(&stat_config, counter); 2009 process_stat(counter, round->time); 2010 } 2011 2012 process_stat_interval(round->time); 2013 return 0; 2014 } 2015 2016 static int process_stat_config_event(struct perf_tool *tool __maybe_unused, 2017 union perf_event *event, 2018 struct perf_session *session __maybe_unused) 2019 { 2020 perf_event__read_stat_config(&stat_config, &event->stat_config); 2021 return 0; 2022 } 2023 2024 static int set_maps(struct perf_script *script) 2025 { 2026 struct perf_evlist *evlist = script->session->evlist; 2027 2028 if (!script->cpus || !script->threads) 2029 return 0; 2030 2031 if (WARN_ONCE(script->allocated, "stats double allocation\n")) 2032 return -EINVAL; 2033 2034 perf_evlist__set_maps(evlist, script->cpus, script->threads); 2035 2036 if (perf_evlist__alloc_stats(evlist, true)) 2037 return -ENOMEM; 2038 2039 script->allocated = true; 2040 return 0; 2041 } 2042 2043 static 2044 int process_thread_map_event(struct perf_tool *tool, 2045 union perf_event *event, 2046 struct perf_session *session __maybe_unused) 2047 { 2048 struct perf_script *script = container_of(tool, struct perf_script, tool); 2049 2050 if (script->threads) { 2051 pr_warning("Extra thread map event, ignoring.\n"); 2052 return 0; 2053 } 2054 2055 script->threads = thread_map__new_event(&event->thread_map); 2056 if (!script->threads) 2057 return -ENOMEM; 2058 2059 return set_maps(script); 2060 } 2061 2062 static 2063 int process_cpu_map_event(struct perf_tool *tool __maybe_unused, 2064 union perf_event *event, 2065 struct perf_session *session __maybe_unused) 2066 { 2067 struct perf_script *script = container_of(tool, struct perf_script, tool); 2068 2069 if (script->cpus) { 2070 pr_warning("Extra cpu map event, ignoring.\n"); 2071 return 0; 2072 } 2073 2074 script->cpus = cpu_map__new_data(&event->cpu_map.data); 2075 if (!script->cpus) 2076 return -ENOMEM; 2077 2078 return set_maps(script); 2079 } 2080 2081 int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) 2082 { 2083 bool show_full_info = false; 2084 bool header = false; 2085 bool header_only = false; 2086 bool script_started = false; 2087 char *rec_script_path = NULL; 2088 char *rep_script_path = NULL; 2089 struct perf_session *session; 2090 struct itrace_synth_opts itrace_synth_opts = { .set = false, }; 2091 char *script_path = NULL; 2092 const char **__argv; 2093 int i, j, err = 0; 2094 struct perf_script script = { 2095 .tool = { 2096 .sample = process_sample_event, 2097 .mmap = perf_event__process_mmap, 2098 .mmap2 = perf_event__process_mmap2, 2099 .comm = perf_event__process_comm, 2100 .exit = perf_event__process_exit, 2101 .fork = perf_event__process_fork, 2102 .attr = process_attr, 2103 .event_update = perf_event__process_event_update, 2104 .tracing_data = perf_event__process_tracing_data, 2105 .build_id = perf_event__process_build_id, 2106 .id_index = perf_event__process_id_index, 2107 .auxtrace_info = perf_event__process_auxtrace_info, 2108 .auxtrace = perf_event__process_auxtrace, 2109 .auxtrace_error = perf_event__process_auxtrace_error, 2110 .stat = perf_event__process_stat_event, 2111 .stat_round = process_stat_round_event, 2112 .stat_config = process_stat_config_event, 2113 .thread_map = process_thread_map_event, 2114 .cpu_map = process_cpu_map_event, 2115 .ordered_events = true, 2116 .ordering_requires_timestamps = true, 2117 }, 2118 }; 2119 struct perf_data_file file = { 2120 .mode = PERF_DATA_MODE_READ, 2121 }; 2122 const struct option options[] = { 2123 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 2124 "dump raw trace in ASCII"), 2125 OPT_INCR('v', "verbose", &verbose, 2126 "be more verbose (show symbol address, etc)"), 2127 OPT_BOOLEAN('L', "Latency", &latency_format, 2128 "show latency attributes (irqs/preemption disabled, etc)"), 2129 OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts", 2130 list_available_scripts), 2131 OPT_CALLBACK('s', "script", NULL, "name", 2132 "script file name (lang:script name, script name, or *)", 2133 parse_scriptname), 2134 OPT_STRING('g', "gen-script", &generate_script_lang, "lang", 2135 "generate perf-script.xx script in specified language"), 2136 OPT_STRING('i', "input", &input_name, "file", "input file name"), 2137 OPT_BOOLEAN('d', "debug-mode", &debug_mode, 2138 "do various checks like samples ordering and lost events"), 2139 OPT_BOOLEAN(0, "header", &header, "Show data header."), 2140 OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."), 2141 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 2142 "file", "vmlinux pathname"), 2143 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, 2144 "file", "kallsyms pathname"), 2145 OPT_BOOLEAN('G', "hide-call-graph", &no_callchain, 2146 "When printing symbols do not display call chain"), 2147 OPT_CALLBACK(0, "symfs", NULL, "directory", 2148 "Look for files with symbols relative to this directory", 2149 symbol__config_symfs), 2150 OPT_CALLBACK('F', "fields", NULL, "str", 2151 "comma separated output fields prepend with 'type:'. " 2152 "Valid types: hw,sw,trace,raw. " 2153 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 2154 "addr,symoff,period,iregs,brstack,brstacksym,flags," 2155 "bpf-output,callindent,insn,insnlen", parse_output_fields), 2156 OPT_BOOLEAN('a', "all-cpus", &system_wide, 2157 "system-wide collection from all CPUs"), 2158 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", 2159 "only consider these symbols"), 2160 OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]", 2161 "Stop display of callgraph at these symbols"), 2162 OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 2163 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", 2164 "only display events for these comms"), 2165 OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]", 2166 "only consider symbols in these pids"), 2167 OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]", 2168 "only consider symbols in these tids"), 2169 OPT_UINTEGER(0, "max-stack", &scripting_max_stack, 2170 "Set the maximum stack depth when parsing the callchain, " 2171 "anything beyond the specified depth will be ignored. " 2172 "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)), 2173 OPT_BOOLEAN('I', "show-info", &show_full_info, 2174 "display extended information from perf.data file"), 2175 OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path, 2176 "Show the path of [kernel.kallsyms]"), 2177 OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events, 2178 "Show the fork/comm/exit events"), 2179 OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events, 2180 "Show the mmap events"), 2181 OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events, 2182 "Show context switch events (if recorded)"), 2183 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), 2184 OPT_BOOLEAN(0, "ns", &nanosecs, 2185 "Use 9 decimal places when displaying time"), 2186 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", 2187 "Instruction Tracing options", 2188 itrace_parse_synth_opts), 2189 OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename, 2190 "Show full source file name path for source lines"), 2191 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, 2192 "Enable symbol demangling"), 2193 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, 2194 "Enable kernel symbol demangling"), 2195 OPT_STRING(0, "time", &script.time_str, "str", 2196 "Time span of interest (start,stop)"), 2197 OPT_END() 2198 }; 2199 const char * const script_subcommands[] = { "record", "report", NULL }; 2200 const char *script_usage[] = { 2201 "perf script [<options>]", 2202 "perf script [<options>] record <script> [<record-options>] <command>", 2203 "perf script [<options>] report <script> [script-args]", 2204 "perf script [<options>] <script> [<record-options>] <command>", 2205 "perf script [<options>] <top-script> [script-args]", 2206 NULL 2207 }; 2208 2209 setup_scripting(); 2210 2211 argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage, 2212 PARSE_OPT_STOP_AT_NON_OPTION); 2213 2214 file.path = input_name; 2215 file.force = symbol_conf.force; 2216 2217 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { 2218 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); 2219 if (!rec_script_path) 2220 return cmd_record(argc, argv, NULL); 2221 } 2222 2223 if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) { 2224 rep_script_path = get_script_path(argv[1], REPORT_SUFFIX); 2225 if (!rep_script_path) { 2226 fprintf(stderr, 2227 "Please specify a valid report script" 2228 "(see 'perf script -l' for listing)\n"); 2229 return -1; 2230 } 2231 } 2232 2233 if (itrace_synth_opts.callchain && 2234 itrace_synth_opts.callchain_sz > scripting_max_stack) 2235 scripting_max_stack = itrace_synth_opts.callchain_sz; 2236 2237 /* make sure PERF_EXEC_PATH is set for scripts */ 2238 set_argv_exec_path(get_argv_exec_path()); 2239 2240 if (argc && !script_name && !rec_script_path && !rep_script_path) { 2241 int live_pipe[2]; 2242 int rep_args; 2243 pid_t pid; 2244 2245 rec_script_path = get_script_path(argv[0], RECORD_SUFFIX); 2246 rep_script_path = get_script_path(argv[0], REPORT_SUFFIX); 2247 2248 if (!rec_script_path && !rep_script_path) { 2249 usage_with_options_msg(script_usage, options, 2250 "Couldn't find script `%s'\n\n See perf" 2251 " script -l for available scripts.\n", argv[0]); 2252 } 2253 2254 if (is_top_script(argv[0])) { 2255 rep_args = argc - 1; 2256 } else { 2257 int rec_args; 2258 2259 rep_args = has_required_arg(rep_script_path); 2260 rec_args = (argc - 1) - rep_args; 2261 if (rec_args < 0) { 2262 usage_with_options_msg(script_usage, options, 2263 "`%s' script requires options." 2264 "\n\n See perf script -l for available " 2265 "scripts and options.\n", argv[0]); 2266 } 2267 } 2268 2269 if (pipe(live_pipe) < 0) { 2270 perror("failed to create pipe"); 2271 return -1; 2272 } 2273 2274 pid = fork(); 2275 if (pid < 0) { 2276 perror("failed to fork"); 2277 return -1; 2278 } 2279 2280 if (!pid) { 2281 j = 0; 2282 2283 dup2(live_pipe[1], 1); 2284 close(live_pipe[0]); 2285 2286 if (is_top_script(argv[0])) { 2287 system_wide = true; 2288 } else if (!system_wide) { 2289 if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) { 2290 err = -1; 2291 goto out; 2292 } 2293 } 2294 2295 __argv = malloc((argc + 6) * sizeof(const char *)); 2296 if (!__argv) { 2297 pr_err("malloc failed\n"); 2298 err = -ENOMEM; 2299 goto out; 2300 } 2301 2302 __argv[j++] = "/bin/sh"; 2303 __argv[j++] = rec_script_path; 2304 if (system_wide) 2305 __argv[j++] = "-a"; 2306 __argv[j++] = "-q"; 2307 __argv[j++] = "-o"; 2308 __argv[j++] = "-"; 2309 for (i = rep_args + 1; i < argc; i++) 2310 __argv[j++] = argv[i]; 2311 __argv[j++] = NULL; 2312 2313 execvp("/bin/sh", (char **)__argv); 2314 free(__argv); 2315 exit(-1); 2316 } 2317 2318 dup2(live_pipe[0], 0); 2319 close(live_pipe[1]); 2320 2321 __argv = malloc((argc + 4) * sizeof(const char *)); 2322 if (!__argv) { 2323 pr_err("malloc failed\n"); 2324 err = -ENOMEM; 2325 goto out; 2326 } 2327 2328 j = 0; 2329 __argv[j++] = "/bin/sh"; 2330 __argv[j++] = rep_script_path; 2331 for (i = 1; i < rep_args + 1; i++) 2332 __argv[j++] = argv[i]; 2333 __argv[j++] = "-i"; 2334 __argv[j++] = "-"; 2335 __argv[j++] = NULL; 2336 2337 execvp("/bin/sh", (char **)__argv); 2338 free(__argv); 2339 exit(-1); 2340 } 2341 2342 if (rec_script_path) 2343 script_path = rec_script_path; 2344 if (rep_script_path) 2345 script_path = rep_script_path; 2346 2347 if (script_path) { 2348 j = 0; 2349 2350 if (!rec_script_path) 2351 system_wide = false; 2352 else if (!system_wide) { 2353 if (have_cmd(argc - 1, &argv[1]) != 0) { 2354 err = -1; 2355 goto out; 2356 } 2357 } 2358 2359 __argv = malloc((argc + 2) * sizeof(const char *)); 2360 if (!__argv) { 2361 pr_err("malloc failed\n"); 2362 err = -ENOMEM; 2363 goto out; 2364 } 2365 2366 __argv[j++] = "/bin/sh"; 2367 __argv[j++] = script_path; 2368 if (system_wide) 2369 __argv[j++] = "-a"; 2370 for (i = 2; i < argc; i++) 2371 __argv[j++] = argv[i]; 2372 __argv[j++] = NULL; 2373 2374 execvp("/bin/sh", (char **)__argv); 2375 free(__argv); 2376 exit(-1); 2377 } 2378 2379 if (!script_name) 2380 setup_pager(); 2381 2382 session = perf_session__new(&file, false, &script.tool); 2383 if (session == NULL) 2384 return -1; 2385 2386 if (header || header_only) { 2387 perf_session__fprintf_info(session, stdout, show_full_info); 2388 if (header_only) 2389 goto out_delete; 2390 } 2391 2392 if (symbol__init(&session->header.env) < 0) 2393 goto out_delete; 2394 2395 script.session = session; 2396 script__setup_sample_type(&script); 2397 2398 if (output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT) 2399 itrace_synth_opts.thread_stack = true; 2400 2401 session->itrace_synth_opts = &itrace_synth_opts; 2402 2403 if (cpu_list) { 2404 err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap); 2405 if (err < 0) 2406 goto out_delete; 2407 } 2408 2409 if (!no_callchain) 2410 symbol_conf.use_callchain = true; 2411 else 2412 symbol_conf.use_callchain = false; 2413 2414 if (session->tevent.pevent && 2415 pevent_set_function_resolver(session->tevent.pevent, 2416 machine__resolve_kernel_addr, 2417 &session->machines.host) < 0) { 2418 pr_err("%s: failed to set libtraceevent function resolver\n", __func__); 2419 return -1; 2420 } 2421 2422 if (generate_script_lang) { 2423 struct stat perf_stat; 2424 int input; 2425 2426 if (output_set_by_user()) { 2427 fprintf(stderr, 2428 "custom fields not supported for generated scripts"); 2429 err = -EINVAL; 2430 goto out_delete; 2431 } 2432 2433 input = open(file.path, O_RDONLY); /* input_name */ 2434 if (input < 0) { 2435 err = -errno; 2436 perror("failed to open file"); 2437 goto out_delete; 2438 } 2439 2440 err = fstat(input, &perf_stat); 2441 if (err < 0) { 2442 perror("failed to stat file"); 2443 goto out_delete; 2444 } 2445 2446 if (!perf_stat.st_size) { 2447 fprintf(stderr, "zero-sized file, nothing to do!\n"); 2448 goto out_delete; 2449 } 2450 2451 scripting_ops = script_spec__lookup(generate_script_lang); 2452 if (!scripting_ops) { 2453 fprintf(stderr, "invalid language specifier"); 2454 err = -ENOENT; 2455 goto out_delete; 2456 } 2457 2458 err = scripting_ops->generate_script(session->tevent.pevent, 2459 "perf-script"); 2460 goto out_delete; 2461 } 2462 2463 if (script_name) { 2464 err = scripting_ops->start_script(script_name, argc, argv); 2465 if (err) 2466 goto out_delete; 2467 pr_debug("perf script started with script %s\n\n", script_name); 2468 script_started = true; 2469 } 2470 2471 2472 err = perf_session__check_output_opt(session); 2473 if (err < 0) 2474 goto out_delete; 2475 2476 /* needs to be parsed after looking up reference time */ 2477 if (perf_time__parse_str(&script.ptime, script.time_str) != 0) { 2478 pr_err("Invalid time string\n"); 2479 return -EINVAL; 2480 } 2481 2482 err = __cmd_script(&script); 2483 2484 flush_scripting(); 2485 2486 out_delete: 2487 perf_evlist__free_stats(session->evlist); 2488 perf_session__delete(session); 2489 2490 if (script_started) 2491 cleanup_scripting(); 2492 out: 2493 return err; 2494 } 2495