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