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