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