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