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