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