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