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