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