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