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