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