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