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