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