1 // SPDX-License-Identifier: GPL-2.0 2 #include <errno.h> 3 #include <inttypes.h> 4 #include <signal.h> 5 #include <stdio.h> 6 7 #include <dirent.h> 8 #include <fcntl.h> 9 #include <linux/bitmap.h> 10 #include <linux/compiler.h> 11 #include <linux/ctype.h> 12 #include <linux/err.h> 13 #include <linux/kernel.h> 14 #include <linux/stringify.h> 15 #include <linux/time64.h> 16 #include <linux/unaligned.h> 17 #include <linux/zalloc.h> 18 #include <sys/param.h> 19 #include <sys/stat.h> 20 #include <sys/types.h> 21 #include <sys/utsname.h> 22 #include <unistd.h> 23 24 #include <perf/evlist.h> 25 #include <subcmd/exec-cmd.h> 26 #include <subcmd/pager.h> 27 #include <subcmd/parse-options.h> 28 29 #include "asm/bug.h" 30 #include "builtin.h" 31 #include "perf.h" 32 #include "print_binary.h" 33 #include "print_insn.h" 34 #include "ui/ui.h" 35 #include "util/annotate.h" 36 #include "util/auxtrace.h" 37 #include "util/cgroup.h" 38 #include "util/color.h" 39 #include "util/counts.h" 40 #include "util/cpumap.h" 41 #include "util/data.h" 42 #include "util/debug.h" 43 #include "util/dlfilter.h" 44 #include "util/dso.h" 45 #include "util/dump-insn.h" 46 #include "util/env.h" 47 #include "util/event.h" 48 #include "util/evlist.h" 49 #include "util/evsel.h" 50 #include "util/evsel_fprintf.h" 51 #include "util/evswitch.h" 52 #include "util/header.h" 53 #include "util/map.h" 54 #include "util/mem-events.h" 55 #include "util/mem-info.h" 56 #include "util/metricgroup.h" 57 #include "util/path.h" 58 #include "util/perf_regs.h" 59 #include "util/pmu.h" 60 #include "util/record.h" 61 #include "util/session.h" 62 #include "util/sort.h" 63 #include "util/srcline.h" 64 #include "util/stat.h" 65 #include "util/string2.h" 66 #include "util/symbol.h" 67 #include "util/thread-stack.h" 68 #include "util/thread.h" 69 #include "util/thread_map.h" 70 #include "util/time-utils.h" 71 #include "util/tool.h" 72 #include "util/trace-event.h" 73 #include "util/unwind.h" 74 #include "util/util.h" 75 76 #ifdef HAVE_LIBTRACEEVENT 77 #include <event-parse.h> 78 #endif 79 80 static char const *script_name; 81 static char const *generate_script_lang; 82 static bool reltime; 83 static bool deltatime; 84 static u64 initial_time; 85 static u64 previous_time; 86 static bool debug_mode; 87 static u64 last_timestamp; 88 static u64 nr_unordered; 89 static bool no_callchain; 90 static bool latency_format; 91 static bool system_wide; 92 static bool print_flags; 93 static const char *cpu_list; 94 static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 95 static int max_blocks; 96 static struct dlfilter *dlfilter; 97 static int dlargc; 98 static char **dlargv; 99 100 enum perf_output_field { 101 PERF_OUTPUT_COMM = 1ULL << 0, 102 PERF_OUTPUT_TID = 1ULL << 1, 103 PERF_OUTPUT_PID = 1ULL << 2, 104 PERF_OUTPUT_TIME = 1ULL << 3, 105 PERF_OUTPUT_CPU = 1ULL << 4, 106 PERF_OUTPUT_EVNAME = 1ULL << 5, 107 PERF_OUTPUT_TRACE = 1ULL << 6, 108 PERF_OUTPUT_IP = 1ULL << 7, 109 PERF_OUTPUT_SYM = 1ULL << 8, 110 PERF_OUTPUT_DSO = 1ULL << 9, 111 PERF_OUTPUT_ADDR = 1ULL << 10, 112 PERF_OUTPUT_SYMOFFSET = 1ULL << 11, 113 PERF_OUTPUT_SRCLINE = 1ULL << 12, 114 PERF_OUTPUT_PERIOD = 1ULL << 13, 115 PERF_OUTPUT_IREGS = 1ULL << 14, 116 PERF_OUTPUT_BRSTACK = 1ULL << 15, 117 PERF_OUTPUT_BRSTACKSYM = 1ULL << 16, 118 PERF_OUTPUT_DATA_SRC = 1ULL << 17, 119 PERF_OUTPUT_WEIGHT = 1ULL << 18, 120 PERF_OUTPUT_BPF_OUTPUT = 1ULL << 19, 121 PERF_OUTPUT_CALLINDENT = 1ULL << 20, 122 PERF_OUTPUT_INSN = 1ULL << 21, 123 PERF_OUTPUT_INSNLEN = 1ULL << 22, 124 PERF_OUTPUT_BRSTACKINSN = 1ULL << 23, 125 PERF_OUTPUT_BRSTACKOFF = 1ULL << 24, 126 PERF_OUTPUT_SYNTH = 1ULL << 25, 127 PERF_OUTPUT_PHYS_ADDR = 1ULL << 26, 128 PERF_OUTPUT_UREGS = 1ULL << 27, 129 PERF_OUTPUT_METRIC = 1ULL << 28, 130 PERF_OUTPUT_MISC = 1ULL << 29, 131 PERF_OUTPUT_SRCCODE = 1ULL << 30, 132 PERF_OUTPUT_IPC = 1ULL << 31, 133 PERF_OUTPUT_TOD = 1ULL << 32, 134 PERF_OUTPUT_DATA_PAGE_SIZE = 1ULL << 33, 135 PERF_OUTPUT_CODE_PAGE_SIZE = 1ULL << 34, 136 PERF_OUTPUT_INS_LAT = 1ULL << 35, 137 PERF_OUTPUT_BRSTACKINSNLEN = 1ULL << 36, 138 PERF_OUTPUT_MACHINE_PID = 1ULL << 37, 139 PERF_OUTPUT_VCPU = 1ULL << 38, 140 PERF_OUTPUT_CGROUP = 1ULL << 39, 141 PERF_OUTPUT_RETIRE_LAT = 1ULL << 40, 142 PERF_OUTPUT_DSOFF = 1ULL << 41, 143 PERF_OUTPUT_DISASM = 1ULL << 42, 144 PERF_OUTPUT_BRSTACKDISASM = 1ULL << 43, 145 PERF_OUTPUT_BRCNTR = 1ULL << 44, 146 }; 147 148 struct perf_script { 149 struct perf_tool tool; 150 struct perf_session *session; 151 bool show_task_events; 152 bool show_mmap_events; 153 bool show_switch_events; 154 bool show_namespace_events; 155 bool show_lost_events; 156 bool show_round_events; 157 bool show_bpf_events; 158 bool show_cgroup_events; 159 bool show_text_poke_events; 160 bool allocated; 161 bool per_event_dump; 162 bool stitch_lbr; 163 struct evswitch evswitch; 164 struct perf_cpu_map *cpus; 165 struct perf_thread_map *threads; 166 int name_width; 167 const char *time_str; 168 struct perf_time_interval *ptime_range; 169 int range_size; 170 int range_num; 171 }; 172 173 static struct output_option { 174 const char *str; 175 enum perf_output_field field; 176 } all_output_options[] = { 177 {.str = "comm", .field = PERF_OUTPUT_COMM}, 178 {.str = "tid", .field = PERF_OUTPUT_TID}, 179 {.str = "pid", .field = PERF_OUTPUT_PID}, 180 {.str = "time", .field = PERF_OUTPUT_TIME}, 181 {.str = "cpu", .field = PERF_OUTPUT_CPU}, 182 {.str = "event", .field = PERF_OUTPUT_EVNAME}, 183 {.str = "trace", .field = PERF_OUTPUT_TRACE}, 184 {.str = "ip", .field = PERF_OUTPUT_IP}, 185 {.str = "sym", .field = PERF_OUTPUT_SYM}, 186 {.str = "dso", .field = PERF_OUTPUT_DSO}, 187 {.str = "dsoff", .field = PERF_OUTPUT_DSOFF}, 188 {.str = "addr", .field = PERF_OUTPUT_ADDR}, 189 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET}, 190 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, 191 {.str = "period", .field = PERF_OUTPUT_PERIOD}, 192 {.str = "iregs", .field = PERF_OUTPUT_IREGS}, 193 {.str = "uregs", .field = PERF_OUTPUT_UREGS}, 194 {.str = "brstack", .field = PERF_OUTPUT_BRSTACK}, 195 {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM}, 196 {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC}, 197 {.str = "weight", .field = PERF_OUTPUT_WEIGHT}, 198 {.str = "bpf-output", .field = PERF_OUTPUT_BPF_OUTPUT}, 199 {.str = "callindent", .field = PERF_OUTPUT_CALLINDENT}, 200 {.str = "insn", .field = PERF_OUTPUT_INSN}, 201 {.str = "disasm", .field = PERF_OUTPUT_DISASM}, 202 {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN}, 203 {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN}, 204 {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF}, 205 {.str = "synth", .field = PERF_OUTPUT_SYNTH}, 206 {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR}, 207 {.str = "metric", .field = PERF_OUTPUT_METRIC}, 208 {.str = "misc", .field = PERF_OUTPUT_MISC}, 209 {.str = "srccode", .field = PERF_OUTPUT_SRCCODE}, 210 {.str = "ipc", .field = PERF_OUTPUT_IPC}, 211 {.str = "tod", .field = PERF_OUTPUT_TOD}, 212 {.str = "data_page_size", .field = PERF_OUTPUT_DATA_PAGE_SIZE}, 213 {.str = "code_page_size", .field = PERF_OUTPUT_CODE_PAGE_SIZE}, 214 {.str = "ins_lat", .field = PERF_OUTPUT_INS_LAT}, 215 {.str = "brstackinsnlen", .field = PERF_OUTPUT_BRSTACKINSNLEN}, 216 {.str = "machine_pid", .field = PERF_OUTPUT_MACHINE_PID}, 217 {.str = "vcpu", .field = PERF_OUTPUT_VCPU}, 218 {.str = "cgroup", .field = PERF_OUTPUT_CGROUP}, 219 {.str = "retire_lat", .field = PERF_OUTPUT_RETIRE_LAT}, 220 {.str = "brstackdisasm", .field = PERF_OUTPUT_BRSTACKDISASM}, 221 {.str = "brcntr", .field = PERF_OUTPUT_BRCNTR}, 222 }; 223 224 enum { 225 OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX, 226 OUTPUT_TYPE_OTHER, 227 OUTPUT_TYPE_MAX 228 }; 229 230 // We need to refactor the evsel->priv use in 'perf script' to allow for 231 // using that area, that is being used only in some cases. 232 #define OUTPUT_TYPE_UNSET -1 233 234 /* default set to maintain compatibility with current format */ 235 static struct { 236 bool user_set; 237 bool wildcard_set; 238 unsigned int print_ip_opts; 239 u64 fields; 240 u64 invalid_fields; 241 u64 user_set_fields; 242 u64 user_unset_fields; 243 } output[OUTPUT_TYPE_MAX] = { 244 245 [PERF_TYPE_HARDWARE] = { 246 .user_set = false, 247 248 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 249 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 250 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 251 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET | 252 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD, 253 254 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 255 }, 256 257 [PERF_TYPE_SOFTWARE] = { 258 .user_set = false, 259 260 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 261 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 262 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 263 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET | 264 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD | 265 PERF_OUTPUT_BPF_OUTPUT, 266 267 .invalid_fields = PERF_OUTPUT_TRACE, 268 }, 269 270 [PERF_TYPE_TRACEPOINT] = { 271 .user_set = false, 272 273 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 274 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 275 PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE 276 }, 277 278 [PERF_TYPE_HW_CACHE] = { 279 .user_set = false, 280 281 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 282 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 283 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 284 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET | 285 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD, 286 287 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 288 }, 289 290 [PERF_TYPE_RAW] = { 291 .user_set = false, 292 293 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 294 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 295 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 296 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET | 297 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD | 298 PERF_OUTPUT_ADDR | PERF_OUTPUT_DATA_SRC | 299 PERF_OUTPUT_WEIGHT | PERF_OUTPUT_PHYS_ADDR | 300 PERF_OUTPUT_DATA_PAGE_SIZE | PERF_OUTPUT_CODE_PAGE_SIZE | 301 PERF_OUTPUT_INS_LAT | PERF_OUTPUT_RETIRE_LAT, 302 303 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 304 }, 305 306 [PERF_TYPE_BREAKPOINT] = { 307 .user_set = false, 308 309 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 310 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 311 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 312 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET | 313 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD, 314 315 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 316 }, 317 318 [OUTPUT_TYPE_SYNTH] = { 319 .user_set = false, 320 321 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 322 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 323 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 324 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET | 325 PERF_OUTPUT_DSO | PERF_OUTPUT_SYNTH, 326 327 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 328 }, 329 330 [OUTPUT_TYPE_OTHER] = { 331 .user_set = false, 332 333 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | 334 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | 335 PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | 336 PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET | 337 PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD, 338 339 .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, 340 }, 341 }; 342 343 struct evsel_script { 344 char *filename; 345 FILE *fp; 346 u64 samples; 347 }; 348 349 static struct evsel_script *evsel_script__new(struct evsel *evsel, struct perf_data *data) 350 { 351 struct evsel_script *es = zalloc(sizeof(*es)); 352 353 if (es != NULL) { 354 if (asprintf(&es->filename, "%s.%s.dump", data->file.path, evsel__name(evsel)) < 0) 355 goto out_free; 356 es->fp = fopen(es->filename, "w"); 357 if (es->fp == NULL) 358 goto out_free_filename; 359 } 360 361 return es; 362 out_free_filename: 363 zfree(&es->filename); 364 out_free: 365 free(es); 366 return NULL; 367 } 368 369 static void evsel_script__delete(struct evsel_script *es) 370 { 371 zfree(&es->filename); 372 fclose(es->fp); 373 es->fp = NULL; 374 free(es); 375 } 376 377 static int evsel_script__fprintf(struct evsel_script *es, FILE *fp) 378 { 379 struct stat st; 380 381 fstat(fileno(es->fp), &st); 382 return fprintf(fp, "[ perf script: Wrote %.3f MB %s (%" PRIu64 " samples) ]\n", 383 st.st_size / 1024.0 / 1024.0, es->filename, es->samples); 384 } 385 386 static inline int output_type(unsigned int type) 387 { 388 switch (type) { 389 case PERF_TYPE_SYNTH: 390 return OUTPUT_TYPE_SYNTH; 391 default: 392 if (type < PERF_TYPE_MAX) 393 return type; 394 } 395 396 return OUTPUT_TYPE_OTHER; 397 } 398 399 static inline int evsel__output_type(struct evsel *evsel) 400 { 401 int type = evsel->script_output_type; 402 403 if (type == OUTPUT_TYPE_UNSET) { 404 type = output_type(evsel->core.attr.type); 405 if (type == OUTPUT_TYPE_OTHER) { 406 struct perf_pmu *pmu = evsel__find_pmu(evsel); 407 408 if (pmu && pmu->is_core) 409 type = PERF_TYPE_RAW; 410 } 411 evsel->script_output_type = type; 412 } 413 414 return type; 415 } 416 417 static bool output_set_by_user(void) 418 { 419 int j; 420 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) { 421 if (output[j].user_set) 422 return true; 423 } 424 return false; 425 } 426 427 static const char *output_field2str(enum perf_output_field field) 428 { 429 int i, imax = ARRAY_SIZE(all_output_options); 430 const char *str = ""; 431 432 for (i = 0; i < imax; ++i) { 433 if (all_output_options[i].field == field) { 434 str = all_output_options[i].str; 435 break; 436 } 437 } 438 return str; 439 } 440 441 #define PRINT_FIELD(x) (output[evsel__output_type(evsel)].fields & PERF_OUTPUT_##x) 442 443 static int evsel__do_check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg, 444 enum perf_output_field field, bool allow_user_set) 445 { 446 struct perf_event_attr *attr = &evsel->core.attr; 447 int type = evsel__output_type(evsel); 448 const char *evname; 449 450 if (attr->sample_type & sample_type) 451 return 0; 452 453 if (output[type].user_set_fields & field) { 454 if (allow_user_set) 455 return 0; 456 evname = evsel__name(evsel); 457 pr_err("Samples for '%s' event do not have %s attribute set. " 458 "Cannot print '%s' field.\n", 459 evname, sample_msg, output_field2str(field)); 460 return -1; 461 } 462 463 /* user did not ask for it explicitly so remove from the default list */ 464 output[type].fields &= ~field; 465 evname = evsel__name(evsel); 466 pr_debug("Samples for '%s' event do not have %s attribute set. " 467 "Skipping '%s' field.\n", 468 evname, sample_msg, output_field2str(field)); 469 470 return 0; 471 } 472 473 static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg, 474 enum perf_output_field field) 475 { 476 return evsel__do_check_stype(evsel, sample_type, sample_msg, field, false); 477 } 478 479 static int evsel__check_attr(struct evsel *evsel, struct perf_session *session) 480 { 481 bool allow_user_set; 482 483 if (evsel__is_dummy_event(evsel)) 484 return 0; 485 486 if (perf_header__has_feat(&session->header, HEADER_STAT)) 487 return 0; 488 489 allow_user_set = perf_header__has_feat(&session->header, 490 HEADER_AUXTRACE); 491 492 if (PRINT_FIELD(TRACE) && 493 !perf_session__has_traces(session, "record -R")) 494 return -EINVAL; 495 496 if (PRINT_FIELD(IP)) { 497 if (evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", PERF_OUTPUT_IP)) 498 return -EINVAL; 499 } 500 501 if (PRINT_FIELD(ADDR) && 502 evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", PERF_OUTPUT_ADDR, allow_user_set)) 503 return -EINVAL; 504 505 if (PRINT_FIELD(DATA_SRC) && 506 evsel__do_check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC", PERF_OUTPUT_DATA_SRC, allow_user_set)) 507 return -EINVAL; 508 509 if (PRINT_FIELD(WEIGHT) && 510 evsel__do_check_stype(evsel, PERF_SAMPLE_WEIGHT_TYPE, "WEIGHT", PERF_OUTPUT_WEIGHT, allow_user_set)) 511 return -EINVAL; 512 513 if (PRINT_FIELD(SYM) && 514 !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) { 515 pr_err("Display of symbols requested but neither sample IP nor " 516 "sample address\navailable. Hence, no addresses to convert " 517 "to symbols.\n"); 518 return -EINVAL; 519 } 520 if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) { 521 pr_err("Display of offsets requested but symbol is not" 522 "selected.\n"); 523 return -EINVAL; 524 } 525 if (PRINT_FIELD(DSO) && 526 !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) { 527 pr_err("Display of DSO requested but no address to convert.\n"); 528 return -EINVAL; 529 } 530 if ((PRINT_FIELD(SRCLINE) || PRINT_FIELD(SRCCODE)) && !PRINT_FIELD(IP)) { 531 pr_err("Display of source line number requested but sample IP is not\n" 532 "selected. Hence, no address to lookup the source line number.\n"); 533 return -EINVAL; 534 } 535 if ((PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN) || PRINT_FIELD(BRSTACKDISASM)) 536 && !allow_user_set && 537 !(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY)) { 538 pr_err("Display of branch stack assembler requested, but non all-branch filter set\n" 539 "Hint: run 'perf record -b ...'\n"); 540 return -EINVAL; 541 } 542 if (PRINT_FIELD(BRCNTR) && 543 !(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_COUNTERS)) { 544 pr_err("Display of branch counter requested but it's not enabled\n" 545 "Hint: run 'perf record -j any,counter ...'\n"); 546 return -EINVAL; 547 } 548 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && 549 evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", PERF_OUTPUT_TID|PERF_OUTPUT_PID)) 550 return -EINVAL; 551 552 if (PRINT_FIELD(TIME) && 553 evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", PERF_OUTPUT_TIME)) 554 return -EINVAL; 555 556 if (PRINT_FIELD(CPU) && 557 evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU", PERF_OUTPUT_CPU, allow_user_set)) 558 return -EINVAL; 559 560 if (PRINT_FIELD(IREGS) && 561 evsel__do_check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", PERF_OUTPUT_IREGS, allow_user_set)) 562 return -EINVAL; 563 564 if (PRINT_FIELD(UREGS) && 565 evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS", PERF_OUTPUT_UREGS)) 566 return -EINVAL; 567 568 if (PRINT_FIELD(PHYS_ADDR) && 569 evsel__do_check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", PERF_OUTPUT_PHYS_ADDR, allow_user_set)) 570 return -EINVAL; 571 572 if (PRINT_FIELD(DATA_PAGE_SIZE) && 573 evsel__check_stype(evsel, PERF_SAMPLE_DATA_PAGE_SIZE, "DATA_PAGE_SIZE", PERF_OUTPUT_DATA_PAGE_SIZE)) 574 return -EINVAL; 575 576 if (PRINT_FIELD(CODE_PAGE_SIZE) && 577 evsel__check_stype(evsel, PERF_SAMPLE_CODE_PAGE_SIZE, "CODE_PAGE_SIZE", PERF_OUTPUT_CODE_PAGE_SIZE)) 578 return -EINVAL; 579 580 if (PRINT_FIELD(INS_LAT) && 581 evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT_STRUCT, "WEIGHT_STRUCT", PERF_OUTPUT_INS_LAT)) 582 return -EINVAL; 583 584 if (PRINT_FIELD(CGROUP) && 585 evsel__check_stype(evsel, PERF_SAMPLE_CGROUP, "CGROUP", PERF_OUTPUT_CGROUP)) { 586 pr_err("Hint: run 'perf record --all-cgroups ...'\n"); 587 return -EINVAL; 588 } 589 590 if (PRINT_FIELD(RETIRE_LAT) && 591 evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT_STRUCT, "WEIGHT_STRUCT", PERF_OUTPUT_RETIRE_LAT)) 592 return -EINVAL; 593 594 return 0; 595 } 596 597 static void evsel__set_print_ip_opts(struct evsel *evsel) 598 { 599 unsigned int type = evsel__output_type(evsel); 600 601 output[type].print_ip_opts = 0; 602 if (PRINT_FIELD(IP)) 603 output[type].print_ip_opts |= EVSEL__PRINT_IP; 604 605 if (PRINT_FIELD(SYM)) 606 output[type].print_ip_opts |= EVSEL__PRINT_SYM; 607 608 if (PRINT_FIELD(DSO)) 609 output[type].print_ip_opts |= EVSEL__PRINT_DSO; 610 611 if (PRINT_FIELD(DSOFF)) 612 output[type].print_ip_opts |= EVSEL__PRINT_DSOFF; 613 614 if (PRINT_FIELD(SYMOFFSET)) 615 output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET; 616 617 if (PRINT_FIELD(SRCLINE)) 618 output[type].print_ip_opts |= EVSEL__PRINT_SRCLINE; 619 } 620 621 static struct evsel *find_first_output_type(struct evlist *evlist, 622 unsigned int type) 623 { 624 struct evsel *evsel; 625 626 evlist__for_each_entry(evlist, evsel) { 627 if (evsel__is_dummy_event(evsel)) 628 continue; 629 if (evsel__output_type(evsel) == (int)type) 630 return evsel; 631 } 632 return NULL; 633 } 634 635 /* 636 * verify all user requested events exist and the samples 637 * have the expected data 638 */ 639 static int perf_session__check_output_opt(struct perf_session *session) 640 { 641 bool tod = false; 642 unsigned int j; 643 struct evsel *evsel; 644 645 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) { 646 evsel = find_first_output_type(session->evlist, j); 647 648 /* 649 * even if fields is set to 0 (ie., show nothing) event must 650 * exist if user explicitly includes it on the command line 651 */ 652 if (!evsel && output[j].user_set && !output[j].wildcard_set && 653 j != OUTPUT_TYPE_SYNTH) { 654 pr_err("%s events do not exist. " 655 "Remove corresponding -F option to proceed.\n", 656 event_type(j)); 657 return -1; 658 } 659 660 if (evsel && output[j].fields && 661 evsel__check_attr(evsel, session)) 662 return -1; 663 664 if (evsel == NULL) 665 continue; 666 667 /* 'dsoff' implys 'dso' field */ 668 if (output[j].fields & PERF_OUTPUT_DSOFF) 669 output[j].fields |= PERF_OUTPUT_DSO; 670 671 evsel__set_print_ip_opts(evsel); 672 tod |= output[j].fields & PERF_OUTPUT_TOD; 673 } 674 675 if (!no_callchain) { 676 bool use_callchain = false; 677 bool not_pipe = false; 678 679 evlist__for_each_entry(session->evlist, evsel) { 680 not_pipe = true; 681 if (evsel__has_callchain(evsel) || evsel__is_offcpu_event(evsel)) { 682 use_callchain = true; 683 break; 684 } 685 } 686 if (not_pipe && !use_callchain) 687 symbol_conf.use_callchain = false; 688 } 689 690 /* 691 * set default for tracepoints to print symbols only 692 * if callchains are present 693 */ 694 if (symbol_conf.use_callchain && 695 !output[PERF_TYPE_TRACEPOINT].user_set) { 696 j = PERF_TYPE_TRACEPOINT; 697 698 evlist__for_each_entry(session->evlist, evsel) { 699 if (evsel->core.attr.type != j) 700 continue; 701 702 if (evsel__has_callchain(evsel)) { 703 output[j].fields |= PERF_OUTPUT_IP; 704 output[j].fields |= PERF_OUTPUT_SYM; 705 output[j].fields |= PERF_OUTPUT_SYMOFFSET; 706 output[j].fields |= PERF_OUTPUT_DSO; 707 evsel__set_print_ip_opts(evsel); 708 goto out; 709 } 710 } 711 } 712 713 if (tod && !perf_session__env(session)->clock.enabled) { 714 pr_err("Can't provide 'tod' time, missing clock data. " 715 "Please record with -k/--clockid option.\n"); 716 return -1; 717 } 718 out: 719 return 0; 720 } 721 722 static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, 723 uint16_t e_machine, uint32_t e_flags, 724 FILE *fp) 725 { 726 unsigned i = 0, r; 727 int printed = 0; 728 729 if (!regs || !regs->regs) 730 return 0; 731 732 printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi); 733 734 for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { 735 u64 val = regs->regs[i++]; 736 printed += fprintf(fp, "%5s:0x%"PRIx64" ", 737 perf_reg_name(r, e_machine, e_flags), 738 val); 739 } 740 741 return printed; 742 } 743 744 #define DEFAULT_TOD_FMT "%F %H:%M:%S" 745 746 static char* 747 tod_scnprintf(struct perf_script *script, char *buf, int buflen, 748 u64 timestamp) 749 { 750 u64 tod_ns, clockid_ns; 751 struct perf_env *env; 752 unsigned long nsec; 753 struct tm ltime; 754 char date[64]; 755 time_t sec; 756 757 buf[0] = '\0'; 758 if (buflen < 64 || !script) 759 return buf; 760 761 env = perf_session__env(script->session); 762 if (!env->clock.enabled) { 763 scnprintf(buf, buflen, "disabled"); 764 return buf; 765 } 766 767 clockid_ns = env->clock.clockid_ns; 768 tod_ns = env->clock.tod_ns; 769 770 if (timestamp > clockid_ns) 771 tod_ns += timestamp - clockid_ns; 772 else 773 tod_ns -= clockid_ns - timestamp; 774 775 sec = (time_t) (tod_ns / NSEC_PER_SEC); 776 nsec = tod_ns - sec * NSEC_PER_SEC; 777 778 if (localtime_r(&sec, <ime) == NULL) { 779 scnprintf(buf, buflen, "failed"); 780 } else { 781 strftime(date, sizeof(date), DEFAULT_TOD_FMT, <ime); 782 783 if (symbol_conf.nanosecs) { 784 snprintf(buf, buflen, "%s.%09lu", date, nsec); 785 } else { 786 snprintf(buf, buflen, "%s.%06lu", 787 date, nsec / NSEC_PER_USEC); 788 } 789 } 790 791 return buf; 792 } 793 794 static int perf_sample__fprintf_iregs(struct perf_sample *sample, 795 struct perf_event_attr *attr, 796 uint16_t e_machine, 797 uint32_t e_flags, 798 FILE *fp) 799 { 800 if (!sample->intr_regs) 801 return 0; 802 803 return perf_sample__fprintf_regs(perf_sample__intr_regs(sample), 804 attr->sample_regs_intr, e_machine, e_flags, fp); 805 } 806 807 static int perf_sample__fprintf_uregs(struct perf_sample *sample, 808 struct perf_event_attr *attr, 809 uint16_t e_machine, 810 uint32_t e_flags, 811 FILE *fp) 812 { 813 if (!sample->user_regs) 814 return 0; 815 816 return perf_sample__fprintf_regs(perf_sample__user_regs(sample), 817 attr->sample_regs_user, e_machine, e_flags, fp); 818 } 819 820 static int perf_sample__fprintf_start(struct perf_script *script, 821 struct perf_sample *sample, 822 struct thread *thread, 823 struct evsel *evsel, 824 u32 type, FILE *fp) 825 { 826 unsigned long secs; 827 unsigned long long nsecs; 828 int printed = 0; 829 char tstr[128]; 830 831 /* 832 * Print the branch counter's abbreviation list, 833 * if the branch counter is available. 834 */ 835 if (PRINT_FIELD(BRCNTR) && !verbose) { 836 char *buf; 837 838 if (!annotation_br_cntr_abbr_list(&buf, evsel, true)) { 839 printed += fprintf(stdout, "%s", buf); 840 free(buf); 841 } 842 } 843 844 if (PRINT_FIELD(MACHINE_PID) && sample->machine_pid) 845 printed += fprintf(fp, "VM:%5d ", sample->machine_pid); 846 847 /* Print VCPU only for guest events i.e. with machine_pid */ 848 if (PRINT_FIELD(VCPU) && sample->machine_pid) 849 printed += fprintf(fp, "VCPU:%03d ", sample->vcpu); 850 851 if (PRINT_FIELD(COMM)) { 852 const char *comm = thread ? thread__comm_str(thread) : ":-1"; 853 854 if (latency_format) 855 printed += fprintf(fp, "%8.8s ", comm); 856 else if (PRINT_FIELD(IP) && evsel__has_callchain(evsel) && symbol_conf.use_callchain) 857 printed += fprintf(fp, "%s ", comm); 858 else 859 printed += fprintf(fp, "%16s ", comm); 860 } 861 862 if (PRINT_FIELD(PID) && PRINT_FIELD(TID)) 863 printed += fprintf(fp, "%7d/%-7d ", sample->pid, sample->tid); 864 else if (PRINT_FIELD(PID)) 865 printed += fprintf(fp, "%7d ", sample->pid); 866 else if (PRINT_FIELD(TID)) 867 printed += fprintf(fp, "%7d ", sample->tid); 868 869 if (PRINT_FIELD(CPU)) { 870 if (latency_format) 871 printed += fprintf(fp, "%3d ", sample->cpu); 872 else 873 printed += fprintf(fp, "[%03d] ", sample->cpu); 874 } 875 876 if (PRINT_FIELD(MISC)) { 877 int ret = 0; 878 879 #define has(m) \ 880 (sample->misc & PERF_RECORD_MISC_##m) == PERF_RECORD_MISC_##m 881 882 if (has(KERNEL)) 883 ret += fprintf(fp, "K"); 884 if (has(USER)) 885 ret += fprintf(fp, "U"); 886 if (has(HYPERVISOR)) 887 ret += fprintf(fp, "H"); 888 if (has(GUEST_KERNEL)) 889 ret += fprintf(fp, "G"); 890 if (has(GUEST_USER)) 891 ret += fprintf(fp, "g"); 892 893 switch (type) { 894 case PERF_RECORD_MMAP: 895 case PERF_RECORD_MMAP2: 896 if (has(MMAP_DATA)) 897 ret += fprintf(fp, "M"); 898 break; 899 case PERF_RECORD_COMM: 900 if (has(COMM_EXEC)) 901 ret += fprintf(fp, "E"); 902 break; 903 case PERF_RECORD_SWITCH: 904 case PERF_RECORD_SWITCH_CPU_WIDE: 905 if (has(SWITCH_OUT)) { 906 ret += fprintf(fp, "S"); 907 if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT) 908 ret += fprintf(fp, "p"); 909 } 910 default: 911 break; 912 } 913 914 #undef has 915 916 ret += fprintf(fp, "%*s", 6 - ret, " "); 917 printed += ret; 918 } 919 920 if (PRINT_FIELD(TOD)) { 921 tod_scnprintf(script, tstr, sizeof(tstr), sample->time); 922 printed += fprintf(fp, "%s ", tstr); 923 } 924 925 if (PRINT_FIELD(TIME)) { 926 u64 t = sample->time; 927 if (reltime) { 928 if (!initial_time) 929 initial_time = sample->time; 930 t = sample->time - initial_time; 931 } else if (deltatime) { 932 if (previous_time) 933 t = sample->time - previous_time; 934 else { 935 t = 0; 936 } 937 previous_time = sample->time; 938 } 939 nsecs = t; 940 secs = nsecs / NSEC_PER_SEC; 941 nsecs -= secs * NSEC_PER_SEC; 942 943 if (symbol_conf.nanosecs) 944 printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs); 945 else { 946 char sample_time[32]; 947 timestamp__scnprintf_usec(t, sample_time, sizeof(sample_time)); 948 printed += fprintf(fp, "%12s: ", sample_time); 949 } 950 } 951 952 return printed; 953 } 954 955 static inline size_t 956 bstack_event_str(struct branch_entry *br, char *buf, size_t sz) 957 { 958 if (!(br->flags.mispred || br->flags.predicted || br->flags.not_taken)) 959 return snprintf(buf, sz, "-"); 960 961 return snprintf(buf, sz, "%s%s", 962 br->flags.predicted ? "P" : "M", 963 br->flags.not_taken ? "N" : ""); 964 } 965 966 static int print_bstack_flags(FILE *fp, struct branch_entry *br) 967 { 968 char events[16] = { 0 }; 969 size_t pos; 970 971 pos = bstack_event_str(br, events, sizeof(events)); 972 return fprintf(fp, "/%s/%c/%c/%d/%s/%s ", 973 pos < 0 ? "-" : events, 974 br->flags.in_tx ? 'X' : '-', 975 br->flags.abort ? 'A' : '-', 976 br->flags.cycles, 977 get_branch_type(br), 978 br->flags.spec ? branch_spec_desc(br->flags.spec) : "-"); 979 } 980 981 static int perf_sample__fprintf_brstack(struct perf_sample *sample, 982 struct thread *thread, 983 struct evsel *evsel, FILE *fp) 984 { 985 struct branch_stack *br = sample->branch_stack; 986 struct branch_entry *entries = perf_sample__branch_entries(sample); 987 u64 i, from, to; 988 int printed = 0; 989 990 if (!(br && br->nr)) 991 return 0; 992 993 for (i = 0; i < br->nr; i++) { 994 from = entries[i].from; 995 to = entries[i].to; 996 997 printed += fprintf(fp, " 0x%"PRIx64, from); 998 if (PRINT_FIELD(DSO)) { 999 struct addr_location alf, alt; 1000 1001 addr_location__init(&alf); 1002 addr_location__init(&alt); 1003 thread__find_map_fb(thread, sample->cpumode, from, &alf); 1004 thread__find_map_fb(thread, sample->cpumode, to, &alt); 1005 1006 printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp); 1007 printed += fprintf(fp, "/0x%"PRIx64, to); 1008 printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp); 1009 addr_location__exit(&alt); 1010 addr_location__exit(&alf); 1011 } else 1012 printed += fprintf(fp, "/0x%"PRIx64, to); 1013 1014 printed += print_bstack_flags(fp, entries + i); 1015 } 1016 1017 return printed; 1018 } 1019 1020 static int perf_sample__fprintf_brstacksym(struct perf_sample *sample, 1021 struct thread *thread, 1022 struct evsel *evsel, FILE *fp) 1023 { 1024 struct branch_stack *br = sample->branch_stack; 1025 struct branch_entry *entries = perf_sample__branch_entries(sample); 1026 u64 i, from, to; 1027 int printed = 0; 1028 1029 if (!(br && br->nr)) 1030 return 0; 1031 1032 for (i = 0; i < br->nr; i++) { 1033 struct addr_location alf, alt; 1034 1035 addr_location__init(&alf); 1036 addr_location__init(&alt); 1037 from = entries[i].from; 1038 to = entries[i].to; 1039 1040 thread__find_symbol_fb(thread, sample->cpumode, from, &alf); 1041 thread__find_symbol_fb(thread, sample->cpumode, to, &alt); 1042 1043 printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp); 1044 if (PRINT_FIELD(DSO)) 1045 printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp); 1046 printed += fprintf(fp, "%c", '/'); 1047 printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp); 1048 if (PRINT_FIELD(DSO)) 1049 printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp); 1050 printed += print_bstack_flags(fp, entries + i); 1051 addr_location__exit(&alt); 1052 addr_location__exit(&alf); 1053 } 1054 1055 return printed; 1056 } 1057 1058 static int perf_sample__fprintf_brstackoff(struct perf_sample *sample, 1059 struct thread *thread, 1060 struct evsel *evsel, FILE *fp) 1061 { 1062 struct branch_stack *br = sample->branch_stack; 1063 struct branch_entry *entries = perf_sample__branch_entries(sample); 1064 u64 i, from, to; 1065 int printed = 0; 1066 1067 if (!(br && br->nr)) 1068 return 0; 1069 1070 for (i = 0; i < br->nr; i++) { 1071 struct addr_location alf, alt; 1072 1073 addr_location__init(&alf); 1074 addr_location__init(&alt); 1075 from = entries[i].from; 1076 to = entries[i].to; 1077 1078 if (thread__find_map_fb(thread, sample->cpumode, from, &alf) && 1079 !dso__adjust_symbols(map__dso(alf.map))) 1080 from = map__dso_map_ip(alf.map, from); 1081 1082 if (thread__find_map_fb(thread, sample->cpumode, to, &alt) && 1083 !dso__adjust_symbols(map__dso(alt.map))) 1084 to = map__dso_map_ip(alt.map, to); 1085 1086 printed += fprintf(fp, " 0x%"PRIx64, from); 1087 if (PRINT_FIELD(DSO)) 1088 printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp); 1089 printed += fprintf(fp, "/0x%"PRIx64, to); 1090 if (PRINT_FIELD(DSO)) 1091 printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp); 1092 printed += print_bstack_flags(fp, entries + i); 1093 addr_location__exit(&alt); 1094 addr_location__exit(&alf); 1095 } 1096 1097 return printed; 1098 } 1099 #define MAXBB 16384UL 1100 1101 static int grab_bb(u8 *buffer, u64 start, u64 end, 1102 struct machine *machine, struct thread *thread, 1103 bool *is64bit, u8 *cpumode, bool last) 1104 { 1105 long offset, len; 1106 struct addr_location al; 1107 bool kernel; 1108 struct dso *dso; 1109 int ret = 0; 1110 1111 if (!start || !end) 1112 return 0; 1113 1114 kernel = machine__kernel_ip(machine, start); 1115 if (kernel) 1116 *cpumode = PERF_RECORD_MISC_KERNEL; 1117 else 1118 *cpumode = PERF_RECORD_MISC_USER; 1119 1120 /* 1121 * Block overlaps between kernel and user. 1122 * This can happen due to ring filtering 1123 * On Intel CPUs the entry into the kernel is filtered, 1124 * but the exit is not. Let the caller patch it up. 1125 */ 1126 if (kernel != machine__kernel_ip(machine, end)) { 1127 pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end); 1128 return -ENXIO; 1129 } 1130 1131 if (end - start > MAXBB - MAXINSN) { 1132 if (last) 1133 pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end); 1134 else 1135 pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start); 1136 return 0; 1137 } 1138 1139 addr_location__init(&al); 1140 if (!thread__find_map(thread, *cpumode, start, &al) || (dso = map__dso(al.map)) == NULL) { 1141 pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); 1142 goto out; 1143 } 1144 if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR) { 1145 pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); 1146 goto out; 1147 } 1148 1149 /* Load maps to ensure dso->is_64_bit has been updated */ 1150 map__load(al.map); 1151 1152 offset = map__map_ip(al.map, start); 1153 len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer, 1154 end - start + MAXINSN); 1155 1156 *is64bit = dso__is_64_bit(dso); 1157 if (len <= 0) 1158 pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n", 1159 start, end); 1160 ret = len; 1161 out: 1162 addr_location__exit(&al); 1163 return ret; 1164 } 1165 1166 static int map__fprintf_srccode(struct map *map, u64 addr, FILE *fp, struct srccode_state *state) 1167 { 1168 char *srcfile; 1169 int ret = 0; 1170 unsigned line; 1171 int len; 1172 char *srccode; 1173 struct dso *dso; 1174 1175 if (!map || (dso = map__dso(map)) == NULL) 1176 return 0; 1177 srcfile = get_srcline_split(dso, 1178 map__rip_2objdump(map, addr), 1179 &line); 1180 if (!srcfile) 1181 return 0; 1182 1183 /* Avoid redundant printing */ 1184 if (state && 1185 state->srcfile && 1186 !strcmp(state->srcfile, srcfile) && 1187 state->line == line) { 1188 free(srcfile); 1189 return 0; 1190 } 1191 1192 srccode = find_sourceline(srcfile, line, &len); 1193 if (!srccode) 1194 goto out_free_line; 1195 1196 ret = fprintf(fp, "|%-8d %.*s", line, len, srccode); 1197 1198 if (state) { 1199 state->srcfile = srcfile; 1200 state->line = line; 1201 } 1202 return ret; 1203 1204 out_free_line: 1205 free(srcfile); 1206 return ret; 1207 } 1208 1209 static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr) 1210 { 1211 struct addr_location al; 1212 int ret = 0; 1213 1214 addr_location__init(&al); 1215 thread__find_map(thread, cpumode, addr, &al); 1216 if (!al.map) 1217 goto out; 1218 ret = map__fprintf_srccode(al.map, al.addr, stdout, 1219 thread__srccode_state(thread)); 1220 if (ret) 1221 ret += printf("\n"); 1222 out: 1223 addr_location__exit(&al); 1224 return ret; 1225 } 1226 1227 static int any_dump_insn(struct evsel *evsel __maybe_unused, 1228 struct perf_insn *x, uint64_t ip, 1229 u8 *inbuf, int inlen, int *lenp, 1230 FILE *fp) 1231 { 1232 if (PRINT_FIELD(BRSTACKDISASM)) { 1233 int printed = fprintf_insn_asm(x->machine, x->thread, x->cpumode, x->is64bit, 1234 (uint8_t *)inbuf, inlen, ip, lenp, 1235 PRINT_INSN_IMM_HEX, fp); 1236 1237 if (printed > 0) 1238 return printed; 1239 } 1240 return fprintf(fp, "%s", dump_insn(x, ip, inbuf, inlen, lenp)); 1241 } 1242 1243 static int add_padding(FILE *fp, int printed, int padding) 1244 { 1245 if (printed >= 0 && printed < padding) 1246 printed += fprintf(fp, "%*s", padding - printed, ""); 1247 return printed; 1248 } 1249 1250 static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en, 1251 struct perf_insn *x, u8 *inbuf, int len, 1252 int insn, FILE *fp, int *total_cycles, 1253 struct evsel *evsel, 1254 struct thread *thread, 1255 u64 br_cntr) 1256 { 1257 int ilen = 0; 1258 int printed = fprintf(fp, "\t%016" PRIx64 "\t", ip); 1259 1260 printed += add_padding(fp, any_dump_insn(evsel, x, ip, inbuf, len, &ilen, fp), 30); 1261 printed += fprintf(fp, "\t"); 1262 1263 if (PRINT_FIELD(BRSTACKINSNLEN)) 1264 printed += fprintf(fp, "ilen: %d\t", ilen); 1265 1266 if (PRINT_FIELD(SRCLINE)) { 1267 struct addr_location al; 1268 1269 addr_location__init(&al); 1270 thread__find_map(thread, x->cpumode, ip, &al); 1271 printed += map__fprintf_srcline(al.map, al.addr, " srcline: ", fp); 1272 printed += fprintf(fp, "\t"); 1273 addr_location__exit(&al); 1274 } 1275 1276 if (PRINT_FIELD(BRCNTR)) { 1277 struct evsel *pos = evsel__leader(evsel); 1278 unsigned int i = 0, j, num, mask, width, numprinted = 0; 1279 1280 perf_env__find_br_cntr_info(evsel__env(evsel), NULL, &width); 1281 mask = (1L << width) - 1; 1282 printed += fprintf(fp, "\t# br_cntr: "); 1283 evlist__for_each_entry_from(evsel->evlist, pos) { 1284 if (!(pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS)) 1285 continue; 1286 if (evsel__leader(pos) != evsel__leader(evsel)) 1287 break; 1288 1289 num = (br_cntr >> (i++ * width)) & mask; 1290 numprinted += num; 1291 if (!verbose) { 1292 for (j = 0; j < num; j++) 1293 printed += fprintf(fp, "%s", pos->abbr_name); 1294 if (mask && (num == mask)) 1295 printed += fprintf(fp, "+"); 1296 } else { 1297 printed += fprintf(fp, "%s %d%s", pos->name, 1298 num, mask && (num == mask) ? "+ " : " "); 1299 } 1300 } 1301 if (numprinted == 0 && !verbose) 1302 printed += fprintf(fp, "-"); 1303 printed += fprintf(fp, " "); 1304 } 1305 1306 printed += fprintf(fp, "%s%s%s%s%s", 1307 !PRINT_FIELD(BRCNTR) ? "#" : "", 1308 en->flags.predicted ? " PRED" : "", 1309 en->flags.mispred ? " MISPRED" : "", 1310 en->flags.in_tx ? " INTX" : "", 1311 en->flags.abort ? " ABORT" : ""); 1312 if (en->flags.cycles) { 1313 *total_cycles += en->flags.cycles; 1314 printed += fprintf(fp, " %d cycles [%d]", en->flags.cycles, *total_cycles); 1315 if (insn) 1316 printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles); 1317 } 1318 1319 return printed + fprintf(fp, "\n"); 1320 } 1321 1322 static int ip__fprintf_sym(uint64_t addr, struct thread *thread, 1323 u8 cpumode, int cpu, struct symbol **lastsym, 1324 struct evsel *evsel, FILE *fp) 1325 { 1326 struct addr_location al; 1327 int off, printed = 0, ret = 0; 1328 1329 addr_location__init(&al); 1330 thread__find_map(thread, cpumode, addr, &al); 1331 1332 if ((*lastsym) && al.addr >= (*lastsym)->start && al.addr < (*lastsym)->end) 1333 goto out; 1334 1335 al.cpu = cpu; 1336 al.sym = NULL; 1337 if (al.map) 1338 al.sym = map__find_symbol(al.map, al.addr); 1339 1340 if (!al.sym) 1341 goto out; 1342 1343 if (al.addr < al.sym->end) 1344 off = al.addr - al.sym->start; 1345 else 1346 off = al.addr - map__start(al.map) - al.sym->start; 1347 printed += fprintf(fp, "\t%s", al.sym->name); 1348 if (off) 1349 printed += fprintf(fp, "%+d", off); 1350 printed += fprintf(fp, ":"); 1351 if (PRINT_FIELD(SRCLINE)) 1352 printed += map__fprintf_srcline(al.map, al.addr, "\t", fp); 1353 printed += fprintf(fp, "\n"); 1354 *lastsym = al.sym; 1355 1356 ret = printed; 1357 out: 1358 addr_location__exit(&al); 1359 return ret; 1360 } 1361 1362 static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, 1363 struct evsel *evsel, 1364 struct thread *thread, 1365 struct perf_event_attr *attr, 1366 struct machine *machine, FILE *fp) 1367 { 1368 struct branch_stack *br = sample->branch_stack; 1369 struct branch_entry *entries = perf_sample__branch_entries(sample); 1370 u64 start, end; 1371 int i, insn, len, nr, ilen, printed = 0; 1372 struct perf_insn x; 1373 u8 buffer[MAXBB]; 1374 unsigned off; 1375 struct symbol *lastsym = NULL; 1376 int total_cycles = 0; 1377 u64 br_cntr = 0; 1378 1379 if (!(br && br->nr)) 1380 return 0; 1381 nr = br->nr; 1382 if (max_blocks && nr > max_blocks + 1) 1383 nr = max_blocks + 1; 1384 1385 x.thread = thread; 1386 x.machine = machine; 1387 x.cpu = sample->cpu; 1388 1389 if (PRINT_FIELD(BRCNTR) && sample->branch_stack_cntr) 1390 br_cntr = sample->branch_stack_cntr[nr - 1]; 1391 1392 printed += fprintf(fp, "%c", '\n'); 1393 1394 /* Handle first from jump, of which we don't know the entry. */ 1395 len = grab_bb(buffer, entries[nr-1].from, 1396 entries[nr-1].from, 1397 machine, thread, &x.is64bit, &x.cpumode, false); 1398 if (len > 0) { 1399 printed += ip__fprintf_sym(entries[nr - 1].from, thread, 1400 x.cpumode, x.cpu, &lastsym, evsel, fp); 1401 printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1], 1402 &x, buffer, len, 0, fp, &total_cycles, 1403 evsel, thread, br_cntr); 1404 if (PRINT_FIELD(SRCCODE)) 1405 printed += print_srccode(thread, x.cpumode, entries[nr - 1].from); 1406 } 1407 1408 /* Print all blocks */ 1409 for (i = nr - 2; i >= 0; i--) { 1410 if (entries[i].from || entries[i].to) 1411 pr_debug("%d: %" PRIx64 "-%" PRIx64 "\n", i, 1412 entries[i].from, 1413 entries[i].to); 1414 start = entries[i + 1].to; 1415 end = entries[i].from; 1416 1417 len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false); 1418 /* Patch up missing kernel transfers due to ring filters */ 1419 if (len == -ENXIO && i > 0) { 1420 end = entries[--i].from; 1421 pr_debug("\tpatching up to %" PRIx64 "-%" PRIx64 "\n", start, end); 1422 len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, false); 1423 } 1424 if (len <= 0) 1425 continue; 1426 1427 insn = 0; 1428 for (off = 0; off < (unsigned)len; off += ilen) { 1429 uint64_t ip = start + off; 1430 1431 printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, evsel, fp); 1432 if (ip == end) { 1433 if (PRINT_FIELD(BRCNTR) && sample->branch_stack_cntr) 1434 br_cntr = sample->branch_stack_cntr[i]; 1435 printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp, 1436 &total_cycles, evsel, thread, br_cntr); 1437 if (PRINT_FIELD(SRCCODE)) 1438 printed += print_srccode(thread, x.cpumode, ip); 1439 break; 1440 } else { 1441 ilen = 0; 1442 printed += fprintf(fp, "\t%016" PRIx64 "\t", ip); 1443 printed += any_dump_insn(evsel, &x, ip, buffer + off, len - off, &ilen, fp); 1444 if (PRINT_FIELD(BRSTACKINSNLEN)) 1445 printed += fprintf(fp, "\tilen: %d", ilen); 1446 printed += fprintf(fp, "\n"); 1447 if (ilen == 0) 1448 break; 1449 if (PRINT_FIELD(SRCCODE)) 1450 print_srccode(thread, x.cpumode, ip); 1451 insn++; 1452 } 1453 } 1454 if (off != end - start) 1455 printed += fprintf(fp, "\tmismatch of LBR data and executable\n"); 1456 } 1457 1458 /* 1459 * Hit the branch? In this case we are already done, and the target 1460 * has not been executed yet. 1461 */ 1462 if (entries[0].from == sample->ip) 1463 goto out; 1464 if (entries[0].flags.abort) 1465 goto out; 1466 1467 /* 1468 * Print final block up to sample 1469 * 1470 * Due to pipeline delays the LBRs might be missing a branch 1471 * or two, which can result in very large or negative blocks 1472 * between final branch and sample. When this happens just 1473 * continue walking after the last TO. 1474 */ 1475 start = entries[0].to; 1476 end = sample->ip; 1477 if (end < start) { 1478 /* Missing jump. Scan 128 bytes for the next branch */ 1479 end = start + 128; 1480 } 1481 len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true); 1482 printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, evsel, fp); 1483 if (len <= 0) { 1484 /* Print at least last IP if basic block did not work */ 1485 len = grab_bb(buffer, sample->ip, sample->ip, 1486 machine, thread, &x.is64bit, &x.cpumode, false); 1487 if (len <= 0) 1488 goto out; 1489 ilen = 0; 1490 printed += fprintf(fp, "\t%016" PRIx64 "\t", sample->ip); 1491 printed += any_dump_insn(evsel, &x, sample->ip, buffer, len, &ilen, fp); 1492 if (PRINT_FIELD(BRSTACKINSNLEN)) 1493 printed += fprintf(fp, "\tilen: %d", ilen); 1494 printed += fprintf(fp, "\n"); 1495 if (PRINT_FIELD(SRCCODE)) 1496 print_srccode(thread, x.cpumode, sample->ip); 1497 goto out; 1498 } 1499 for (off = 0; off <= end - start; off += ilen) { 1500 ilen = 0; 1501 printed += fprintf(fp, "\t%016" PRIx64 "\t", start + off); 1502 printed += any_dump_insn(evsel, &x, start + off, buffer + off, len - off, &ilen, fp); 1503 if (PRINT_FIELD(BRSTACKINSNLEN)) 1504 printed += fprintf(fp, "\tilen: %d", ilen); 1505 printed += fprintf(fp, "\n"); 1506 if (ilen == 0) 1507 break; 1508 if ((attr->branch_sample_type == 0 || attr->branch_sample_type & PERF_SAMPLE_BRANCH_ANY) 1509 && arch_is_uncond_branch(buffer + off, len - off, x.is64bit) 1510 && start + off != sample->ip) { 1511 /* 1512 * Hit a missing branch. Just stop. 1513 */ 1514 printed += fprintf(fp, "\t... not reaching sample ...\n"); 1515 break; 1516 } 1517 if (PRINT_FIELD(SRCCODE)) 1518 print_srccode(thread, x.cpumode, start + off); 1519 } 1520 out: 1521 return printed; 1522 } 1523 1524 static int perf_sample__fprintf_addr(struct perf_sample *sample, 1525 struct thread *thread, 1526 struct evsel *evsel, FILE *fp) 1527 { 1528 struct addr_location al; 1529 int printed = fprintf(fp, "%16" PRIx64, sample->addr); 1530 1531 addr_location__init(&al); 1532 if (!sample_addr_correlates_sym(&evsel->core.attr)) 1533 goto out; 1534 1535 thread__resolve(thread, &al, sample); 1536 1537 if (PRINT_FIELD(SYM)) { 1538 printed += fprintf(fp, " "); 1539 if (PRINT_FIELD(SYMOFFSET)) 1540 printed += symbol__fprintf_symname_offs(al.sym, &al, fp); 1541 else 1542 printed += symbol__fprintf_symname(al.sym, fp); 1543 } 1544 1545 if (PRINT_FIELD(DSO)) 1546 printed += map__fprintf_dsoname_dsoff(al.map, PRINT_FIELD(DSOFF), al.addr, fp); 1547 out: 1548 addr_location__exit(&al); 1549 return printed; 1550 } 1551 1552 static const char *resolve_branch_sym(struct perf_sample *sample, 1553 struct evsel *evsel, 1554 struct thread *thread, 1555 struct addr_location *al, 1556 struct addr_location *addr_al, 1557 u64 *ip) 1558 { 1559 const char *name = NULL; 1560 1561 if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) { 1562 if (sample_addr_correlates_sym(&evsel->core.attr)) { 1563 if (!addr_al->thread) 1564 thread__resolve(thread, addr_al, sample); 1565 if (addr_al->sym) 1566 name = addr_al->sym->name; 1567 else 1568 *ip = sample->addr; 1569 } else { 1570 *ip = sample->addr; 1571 } 1572 } else if (sample->flags & (PERF_IP_FLAG_RETURN | PERF_IP_FLAG_TRACE_END)) { 1573 if (al->sym) 1574 name = al->sym->name; 1575 else 1576 *ip = sample->ip; 1577 } 1578 return name; 1579 } 1580 1581 static int perf_sample__fprintf_callindent(struct perf_sample *sample, 1582 struct evsel *evsel, 1583 struct thread *thread, 1584 struct addr_location *al, 1585 struct addr_location *addr_al, 1586 FILE *fp) 1587 { 1588 size_t depth = thread_stack__depth(thread, sample->cpu); 1589 const char *name = NULL; 1590 static int spacing; 1591 int len = 0; 1592 int dlen = 0; 1593 u64 ip = 0; 1594 1595 /* 1596 * The 'return' has already been popped off the stack so the depth has 1597 * to be adjusted to match the 'call'. 1598 */ 1599 if (thread__ts(thread) && sample->flags & PERF_IP_FLAG_RETURN) 1600 depth += 1; 1601 1602 name = resolve_branch_sym(sample, evsel, thread, al, addr_al, &ip); 1603 1604 if (PRINT_FIELD(DSO) && !(PRINT_FIELD(IP) || PRINT_FIELD(ADDR))) { 1605 dlen += fprintf(fp, "("); 1606 dlen += map__fprintf_dsoname(al->map, fp); 1607 dlen += fprintf(fp, ")\t"); 1608 } 1609 1610 if (name) 1611 len = fprintf(fp, "%*s%s", (int)depth * 4, "", name); 1612 else if (ip) 1613 len = fprintf(fp, "%*s%16" PRIx64, (int)depth * 4, "", ip); 1614 1615 if (len < 0) 1616 return len; 1617 1618 /* 1619 * Try to keep the output length from changing frequently so that the 1620 * output lines up more nicely. 1621 */ 1622 if (len > spacing || (len && len < spacing - 52)) 1623 spacing = round_up(len + 4, 32); 1624 1625 if (len < spacing) 1626 len += fprintf(fp, "%*s", spacing - len, ""); 1627 1628 return len + dlen; 1629 } 1630 1631 static int perf_sample__fprintf_insn(struct perf_sample *sample, 1632 struct evsel *evsel, 1633 struct perf_event_attr *attr, 1634 struct thread *thread, 1635 struct machine *machine, FILE *fp, 1636 struct addr_location *al) 1637 { 1638 int printed = 0; 1639 1640 perf_sample__fetch_insn(sample, thread, machine); 1641 1642 if (PRINT_FIELD(INSNLEN)) 1643 printed += fprintf(fp, " ilen: %d", sample->insn_len); 1644 if (PRINT_FIELD(INSN) && sample->insn_len) { 1645 printed += fprintf(fp, " insn: "); 1646 printed += sample__fprintf_insn_raw(sample, fp); 1647 } 1648 if (PRINT_FIELD(DISASM) && sample->insn_len) { 1649 printed += fprintf(fp, "\t\t"); 1650 printed += sample__fprintf_insn_asm(sample, thread, machine, fp, al); 1651 } 1652 if (PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN) || PRINT_FIELD(BRSTACKDISASM)) 1653 printed += perf_sample__fprintf_brstackinsn(sample, evsel, thread, attr, machine, fp); 1654 1655 return printed; 1656 } 1657 1658 static int perf_sample__fprintf_ipc(struct perf_sample *sample, 1659 struct evsel *evsel, FILE *fp) 1660 { 1661 unsigned int ipc; 1662 1663 if (!PRINT_FIELD(IPC) || !sample->cyc_cnt || !sample->insn_cnt) 1664 return 0; 1665 1666 ipc = (sample->insn_cnt * 100) / sample->cyc_cnt; 1667 1668 return fprintf(fp, " \t IPC: %u.%02u (%" PRIu64 "/%" PRIu64 ") ", 1669 ipc / 100, ipc % 100, sample->insn_cnt, sample->cyc_cnt); 1670 } 1671 1672 static int perf_sample__fprintf_bts(struct perf_sample *sample, 1673 struct evsel *evsel, 1674 struct thread *thread, 1675 struct addr_location *al, 1676 struct addr_location *addr_al, 1677 struct machine *machine, FILE *fp) 1678 { 1679 struct perf_event_attr *attr = &evsel->core.attr; 1680 unsigned int type = evsel__output_type(evsel); 1681 bool print_srcline_last = false; 1682 int printed = 0; 1683 1684 if (PRINT_FIELD(CALLINDENT)) 1685 printed += perf_sample__fprintf_callindent(sample, evsel, thread, al, addr_al, fp); 1686 1687 /* print branch_from information */ 1688 if (PRINT_FIELD(IP)) { 1689 unsigned int print_opts = output[type].print_ip_opts; 1690 struct callchain_cursor *cursor = NULL; 1691 1692 if (symbol_conf.use_callchain && sample->callchain) { 1693 cursor = get_tls_callchain_cursor(); 1694 if (thread__resolve_callchain(al->thread, cursor, 1695 sample, NULL, NULL, 1696 scripting_max_stack)) 1697 cursor = NULL; 1698 } 1699 if (cursor == NULL) { 1700 printed += fprintf(fp, " "); 1701 if (print_opts & EVSEL__PRINT_SRCLINE) { 1702 print_srcline_last = true; 1703 print_opts &= ~EVSEL__PRINT_SRCLINE; 1704 } 1705 } else 1706 printed += fprintf(fp, "\n"); 1707 1708 printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor, 1709 symbol_conf.bt_stop_list, fp); 1710 } 1711 1712 /* print branch_to information */ 1713 if (PRINT_FIELD(ADDR) || 1714 ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) && 1715 !output[type].user_set)) { 1716 printed += fprintf(fp, " => "); 1717 printed += perf_sample__fprintf_addr(sample, thread, evsel, fp); 1718 } 1719 1720 printed += perf_sample__fprintf_ipc(sample, evsel, fp); 1721 1722 if (print_srcline_last) 1723 printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp); 1724 1725 printed += perf_sample__fprintf_insn(sample, evsel, attr, thread, machine, fp, al); 1726 printed += fprintf(fp, "\n"); 1727 if (PRINT_FIELD(SRCCODE)) { 1728 int ret = map__fprintf_srccode(al->map, al->addr, stdout, 1729 thread__srccode_state(thread)); 1730 if (ret) { 1731 printed += ret; 1732 printed += printf("\n"); 1733 } 1734 } 1735 return printed; 1736 } 1737 1738 static int perf_sample__fprintf_flags(u32 flags, FILE *fp) 1739 { 1740 char str[SAMPLE_FLAGS_BUF_SIZE]; 1741 int ret; 1742 1743 ret = perf_sample__sprintf_flags(flags, str, sizeof(str)); 1744 if (ret < 0) 1745 return fprintf(fp, " raw flags:0x%-*x ", 1746 SAMPLE_FLAGS_STR_ALIGNED_SIZE - 12, flags); 1747 1748 return fprintf(fp, " %-*s ", SAMPLE_FLAGS_STR_ALIGNED_SIZE, str); 1749 } 1750 1751 struct printer_data { 1752 int line_no; 1753 bool hit_nul; 1754 bool is_printable; 1755 }; 1756 1757 static int sample__fprintf_bpf_output(enum binary_printer_ops op, 1758 unsigned int val, 1759 void *extra, FILE *fp) 1760 { 1761 unsigned char ch = (unsigned char)val; 1762 struct printer_data *printer_data = extra; 1763 int printed = 0; 1764 1765 switch (op) { 1766 case BINARY_PRINT_DATA_BEGIN: 1767 printed += fprintf(fp, "\n"); 1768 break; 1769 case BINARY_PRINT_LINE_BEGIN: 1770 printed += fprintf(fp, "%17s", !printer_data->line_no ? "BPF output:" : 1771 " "); 1772 break; 1773 case BINARY_PRINT_ADDR: 1774 printed += fprintf(fp, " %04x:", val); 1775 break; 1776 case BINARY_PRINT_NUM_DATA: 1777 printed += fprintf(fp, " %02x", val); 1778 break; 1779 case BINARY_PRINT_NUM_PAD: 1780 printed += fprintf(fp, " "); 1781 break; 1782 case BINARY_PRINT_SEP: 1783 printed += fprintf(fp, " "); 1784 break; 1785 case BINARY_PRINT_CHAR_DATA: 1786 if (printer_data->hit_nul && ch) 1787 printer_data->is_printable = false; 1788 1789 if (!isprint(ch)) { 1790 printed += fprintf(fp, "%c", '.'); 1791 1792 if (!printer_data->is_printable) 1793 break; 1794 1795 if (ch == '\0') 1796 printer_data->hit_nul = true; 1797 else 1798 printer_data->is_printable = false; 1799 } else { 1800 printed += fprintf(fp, "%c", ch); 1801 } 1802 break; 1803 case BINARY_PRINT_CHAR_PAD: 1804 printed += fprintf(fp, " "); 1805 break; 1806 case BINARY_PRINT_LINE_END: 1807 printed += fprintf(fp, "\n"); 1808 printer_data->line_no++; 1809 break; 1810 case BINARY_PRINT_DATA_END: 1811 default: 1812 break; 1813 } 1814 1815 return printed; 1816 } 1817 1818 static int perf_sample__fprintf_bpf_output(struct perf_sample *sample, FILE *fp) 1819 { 1820 unsigned int nr_bytes = sample->raw_size; 1821 struct printer_data printer_data = {0, false, true}; 1822 int printed = binary__fprintf(sample->raw_data, nr_bytes, 8, 1823 sample__fprintf_bpf_output, &printer_data, fp); 1824 1825 if (printer_data.is_printable && printer_data.hit_nul) 1826 printed += fprintf(fp, "%17s \"%s\"\n", "BPF string:", (char *)(sample->raw_data)); 1827 1828 return printed; 1829 } 1830 1831 static int perf_sample__fprintf_spacing(int len, int spacing, FILE *fp) 1832 { 1833 if (len > 0 && len < spacing) 1834 return fprintf(fp, "%*s", spacing - len, ""); 1835 1836 return 0; 1837 } 1838 1839 static int perf_sample__fprintf_pt_spacing(int len, FILE *fp) 1840 { 1841 return perf_sample__fprintf_spacing(len, 34, fp); 1842 } 1843 1844 /* If a value contains only printable ASCII characters padded with NULLs */ 1845 static bool ptw_is_prt(u64 val) 1846 { 1847 char c; 1848 u32 i; 1849 1850 for (i = 0; i < sizeof(val); i++) { 1851 c = ((char *)&val)[i]; 1852 if (!c) 1853 break; 1854 if (!isprint(c) || !isascii(c)) 1855 return false; 1856 } 1857 for (; i < sizeof(val); i++) { 1858 c = ((char *)&val)[i]; 1859 if (c) 1860 return false; 1861 } 1862 return true; 1863 } 1864 1865 static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp) 1866 { 1867 struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample); 1868 char str[sizeof(u64) + 1] = ""; 1869 int len; 1870 u64 val; 1871 1872 if (perf_sample__bad_synth_size(sample, *data)) 1873 return 0; 1874 1875 val = le64_to_cpu(data->payload); 1876 if (ptw_is_prt(val)) { 1877 memcpy(str, &val, sizeof(val)); 1878 str[sizeof(val)] = 0; 1879 } 1880 len = fprintf(fp, " IP: %u payload: %#" PRIx64 " %s ", 1881 data->ip, val, str); 1882 return len + perf_sample__fprintf_pt_spacing(len, fp); 1883 } 1884 1885 static int perf_sample__fprintf_synth_mwait(struct perf_sample *sample, FILE *fp) 1886 { 1887 struct perf_synth_intel_mwait *data = perf_sample__synth_ptr(sample); 1888 int len; 1889 1890 if (perf_sample__bad_synth_size(sample, *data)) 1891 return 0; 1892 1893 len = fprintf(fp, " hints: %#x extensions: %#x ", 1894 data->hints, data->extensions); 1895 return len + perf_sample__fprintf_pt_spacing(len, fp); 1896 } 1897 1898 static int perf_sample__fprintf_synth_pwre(struct perf_sample *sample, FILE *fp) 1899 { 1900 struct perf_synth_intel_pwre *data = perf_sample__synth_ptr(sample); 1901 int len; 1902 1903 if (perf_sample__bad_synth_size(sample, *data)) 1904 return 0; 1905 1906 len = fprintf(fp, " hw: %u cstate: %u sub-cstate: %u ", 1907 data->hw, data->cstate, data->subcstate); 1908 return len + perf_sample__fprintf_pt_spacing(len, fp); 1909 } 1910 1911 static int perf_sample__fprintf_synth_exstop(struct perf_sample *sample, FILE *fp) 1912 { 1913 struct perf_synth_intel_exstop *data = perf_sample__synth_ptr(sample); 1914 int len; 1915 1916 if (perf_sample__bad_synth_size(sample, *data)) 1917 return 0; 1918 1919 len = fprintf(fp, " IP: %u ", data->ip); 1920 return len + perf_sample__fprintf_pt_spacing(len, fp); 1921 } 1922 1923 static int perf_sample__fprintf_synth_pwrx(struct perf_sample *sample, FILE *fp) 1924 { 1925 struct perf_synth_intel_pwrx *data = perf_sample__synth_ptr(sample); 1926 int len; 1927 1928 if (perf_sample__bad_synth_size(sample, *data)) 1929 return 0; 1930 1931 len = fprintf(fp, " deepest cstate: %u last cstate: %u wake reason: %#x ", 1932 data->deepest_cstate, data->last_cstate, 1933 data->wake_reason); 1934 return len + perf_sample__fprintf_pt_spacing(len, fp); 1935 } 1936 1937 static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp) 1938 { 1939 struct perf_synth_intel_cbr *data = perf_sample__synth_ptr(sample); 1940 unsigned int percent, freq; 1941 int len; 1942 1943 if (perf_sample__bad_synth_size(sample, *data)) 1944 return 0; 1945 1946 freq = (le32_to_cpu(data->freq) + 500) / 1000; 1947 len = fprintf(fp, " cbr: %2u freq: %4u MHz ", data->cbr, freq); 1948 if (data->max_nonturbo) { 1949 percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10; 1950 len += fprintf(fp, "(%3u%%) ", percent); 1951 } 1952 return len + perf_sample__fprintf_pt_spacing(len, fp); 1953 } 1954 1955 static int perf_sample__fprintf_synth_psb(struct perf_sample *sample, FILE *fp) 1956 { 1957 struct perf_synth_intel_psb *data = perf_sample__synth_ptr(sample); 1958 int len; 1959 1960 if (perf_sample__bad_synth_size(sample, *data)) 1961 return 0; 1962 1963 len = fprintf(fp, " psb offs: %#" PRIx64, data->offset); 1964 return len + perf_sample__fprintf_pt_spacing(len, fp); 1965 } 1966 1967 /* Intel PT Event Trace */ 1968 static int perf_sample__fprintf_synth_evt(struct perf_sample *sample, FILE *fp) 1969 { 1970 struct perf_synth_intel_evt *data = perf_sample__synth_ptr(sample); 1971 const char *cfe[32] = {NULL, "INTR", "IRET", "SMI", "RSM", "SIPI", 1972 "INIT", "VMENTRY", "VMEXIT", "VMEXIT_INTR", 1973 "SHUTDOWN", NULL, "UINTR", "UIRET"}; 1974 const char *evd[64] = {"PFA", "VMXQ", "VMXR"}; 1975 const char *s; 1976 int len, i; 1977 1978 if (perf_sample__bad_synth_size(sample, *data)) 1979 return 0; 1980 1981 s = cfe[data->type]; 1982 if (s) { 1983 len = fprintf(fp, " cfe: %s IP: %d vector: %u", 1984 s, data->ip, data->vector); 1985 } else { 1986 len = fprintf(fp, " cfe: %u IP: %d vector: %u", 1987 data->type, data->ip, data->vector); 1988 } 1989 for (i = 0; i < data->evd_cnt; i++) { 1990 unsigned int et = data->evd[i].evd_type & 0x3f; 1991 1992 s = evd[et]; 1993 if (s) { 1994 len += fprintf(fp, " %s: %#" PRIx64, 1995 s, data->evd[i].payload); 1996 } else { 1997 len += fprintf(fp, " EVD_%u: %#" PRIx64, 1998 et, data->evd[i].payload); 1999 } 2000 } 2001 return len + perf_sample__fprintf_pt_spacing(len, fp); 2002 } 2003 2004 static int perf_sample__fprintf_synth_iflag_chg(struct perf_sample *sample, FILE *fp) 2005 { 2006 struct perf_synth_intel_iflag_chg *data = perf_sample__synth_ptr(sample); 2007 int len; 2008 2009 if (perf_sample__bad_synth_size(sample, *data)) 2010 return 0; 2011 2012 len = fprintf(fp, " IFLAG: %d->%d %s branch", !data->iflag, data->iflag, 2013 data->via_branch ? "via" : "non"); 2014 return len + perf_sample__fprintf_pt_spacing(len, fp); 2015 } 2016 2017 static int perf_sample__fprintf_synth_vpadtl(struct perf_sample *data, FILE *fp) 2018 { 2019 struct powerpc_vpadtl_entry *dtl = (struct powerpc_vpadtl_entry *)data->raw_data; 2020 int len; 2021 2022 len = fprintf(fp, "timebase: %" PRIu64 " dispatch_reason:%s, preempt_reason:%s,\n" 2023 "enqueue_to_dispatch_time:%d, ready_to_enqueue_time:%d," 2024 "waiting_to_ready_time:%d, processor_id: %d", 2025 get_unaligned_be64(&dtl->timebase), 2026 dispatch_reasons[dtl->dispatch_reason], 2027 preempt_reasons[dtl->preempt_reason], 2028 be32_to_cpu(dtl->enqueue_to_dispatch_time), 2029 be32_to_cpu(dtl->ready_to_enqueue_time), 2030 be32_to_cpu(dtl->waiting_to_ready_time), 2031 be16_to_cpu(dtl->processor_id)); 2032 2033 return len; 2034 } 2035 2036 static int perf_sample__fprintf_synth(struct perf_sample *sample, 2037 struct evsel *evsel, FILE *fp) 2038 { 2039 switch (evsel->core.attr.config) { 2040 case PERF_SYNTH_INTEL_PTWRITE: 2041 return perf_sample__fprintf_synth_ptwrite(sample, fp); 2042 case PERF_SYNTH_INTEL_MWAIT: 2043 return perf_sample__fprintf_synth_mwait(sample, fp); 2044 case PERF_SYNTH_INTEL_PWRE: 2045 return perf_sample__fprintf_synth_pwre(sample, fp); 2046 case PERF_SYNTH_INTEL_EXSTOP: 2047 return perf_sample__fprintf_synth_exstop(sample, fp); 2048 case PERF_SYNTH_INTEL_PWRX: 2049 return perf_sample__fprintf_synth_pwrx(sample, fp); 2050 case PERF_SYNTH_INTEL_CBR: 2051 return perf_sample__fprintf_synth_cbr(sample, fp); 2052 case PERF_SYNTH_INTEL_PSB: 2053 return perf_sample__fprintf_synth_psb(sample, fp); 2054 case PERF_SYNTH_INTEL_EVT: 2055 return perf_sample__fprintf_synth_evt(sample, fp); 2056 case PERF_SYNTH_INTEL_IFLAG_CHG: 2057 return perf_sample__fprintf_synth_iflag_chg(sample, fp); 2058 case PERF_SYNTH_POWERPC_VPA_DTL: 2059 return perf_sample__fprintf_synth_vpadtl(sample, fp); 2060 default: 2061 break; 2062 } 2063 2064 return 0; 2065 } 2066 2067 static int evlist__max_name_len(struct evlist *evlist) 2068 { 2069 struct evsel *evsel; 2070 int max = 0; 2071 2072 evlist__for_each_entry(evlist, evsel) { 2073 int len = strlen(evsel__name(evsel)); 2074 2075 max = MAX(len, max); 2076 } 2077 2078 return max; 2079 } 2080 2081 static int data_src__fprintf(u64 data_src, FILE *fp) 2082 { 2083 struct mem_info *mi = mem_info__new(); 2084 char decode[100]; 2085 char out[100]; 2086 static int maxlen; 2087 int len; 2088 2089 if (!mi) 2090 return -ENOMEM; 2091 2092 mem_info__data_src(mi)->val = data_src; 2093 perf_script__meminfo_scnprintf(decode, 100, mi); 2094 mem_info__put(mi); 2095 2096 len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode); 2097 if (maxlen < len) 2098 maxlen = len; 2099 2100 return fprintf(fp, "%-*s", maxlen, out); 2101 } 2102 2103 struct metric_ctx { 2104 struct perf_sample *sample; 2105 struct thread *thread; 2106 struct evsel *evsel; 2107 FILE *fp; 2108 }; 2109 2110 static void script_print_metric(struct perf_stat_config *config __maybe_unused, 2111 void *ctx, enum metric_threshold_classify thresh, 2112 const char *fmt, const char *unit, double val) 2113 { 2114 struct metric_ctx *mctx = ctx; 2115 const char *color = metric_threshold_classify__color(thresh); 2116 2117 if (!fmt) 2118 return; 2119 perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel, 2120 PERF_RECORD_SAMPLE, mctx->fp); 2121 fputs("\tmetric: ", mctx->fp); 2122 if (color) 2123 color_fprintf(mctx->fp, color, fmt, val); 2124 else 2125 printf(fmt, val); 2126 fprintf(mctx->fp, " %s\n", unit); 2127 } 2128 2129 static void script_new_line(struct perf_stat_config *config __maybe_unused, 2130 void *ctx) 2131 { 2132 struct metric_ctx *mctx = ctx; 2133 2134 perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel, 2135 PERF_RECORD_SAMPLE, mctx->fp); 2136 fputs("\tmetric: ", mctx->fp); 2137 } 2138 2139 struct script_find_metrics_args { 2140 struct evlist *evlist; 2141 bool system_wide; 2142 }; 2143 2144 static struct evsel *map_metric_evsel_to_script_evsel(struct evlist *script_evlist, 2145 struct evsel *metric_evsel) 2146 { 2147 struct evsel *script_evsel; 2148 2149 evlist__for_each_entry(script_evlist, script_evsel) { 2150 /* Skip if perf_event_attr differ. */ 2151 if (metric_evsel->core.attr.type != script_evsel->core.attr.type) 2152 continue; 2153 if (metric_evsel->core.attr.config != script_evsel->core.attr.config) 2154 continue; 2155 /* Skip if the script event has a metric_id that doesn't match. */ 2156 if (script_evsel->metric_id && 2157 strcmp(evsel__metric_id(metric_evsel), evsel__metric_id(script_evsel))) { 2158 pr_debug("Skipping matching evsel due to differing metric ids '%s' vs '%s'\n", 2159 evsel__metric_id(metric_evsel), evsel__metric_id(script_evsel)); 2160 continue; 2161 } 2162 return script_evsel; 2163 } 2164 return NULL; 2165 } 2166 2167 static int script_find_metrics(const struct pmu_metric *pm, 2168 const struct pmu_metrics_table *table __maybe_unused, 2169 void *data) 2170 { 2171 struct script_find_metrics_args *args = data; 2172 struct evlist *script_evlist = args->evlist; 2173 struct evlist *metric_evlist = evlist__new(); 2174 struct evsel *metric_evsel; 2175 int ret = metricgroup__parse_groups(metric_evlist, 2176 /*pmu=*/"all", 2177 pm->metric_name, 2178 /*metric_no_group=*/false, 2179 /*metric_no_merge=*/false, 2180 /*metric_no_threshold=*/true, 2181 /*user_requested_cpu_list=*/NULL, 2182 args->system_wide, 2183 /*hardware_aware_grouping=*/false); 2184 2185 if (ret) { 2186 /* Metric parsing failed but continue the search. */ 2187 goto out; 2188 } 2189 2190 /* 2191 * Check the script_evlist has an entry for each metric_evlist entry. If 2192 * the script evsel was already set up avoid changing data that may 2193 * break it. 2194 */ 2195 evlist__for_each_entry(metric_evlist, metric_evsel) { 2196 struct evsel *script_evsel = 2197 map_metric_evsel_to_script_evsel(script_evlist, metric_evsel); 2198 struct evsel *new_metric_leader; 2199 2200 if (!script_evsel) { 2201 pr_debug("Skipping metric '%s' as evsel '%s' / '%s' is missing\n", 2202 pm->metric_name, evsel__name(metric_evsel), 2203 evsel__metric_id(metric_evsel)); 2204 goto out; 2205 } 2206 2207 if (script_evsel->metric_leader == NULL) 2208 continue; 2209 2210 if (metric_evsel->metric_leader == metric_evsel) { 2211 new_metric_leader = script_evsel; 2212 } else { 2213 new_metric_leader = 2214 map_metric_evsel_to_script_evsel(script_evlist, 2215 metric_evsel->metric_leader); 2216 } 2217 /* Mismatching evsel leaders. */ 2218 if (script_evsel->metric_leader != new_metric_leader) { 2219 pr_debug("Skipping metric '%s' due to mismatching evsel metric leaders '%s' vs '%s'\n", 2220 pm->metric_name, evsel__metric_id(metric_evsel), 2221 evsel__metric_id(script_evsel)); 2222 goto out; 2223 } 2224 } 2225 /* 2226 * Metric events match those in the script evlist, copy metric evsel 2227 * data into the script evlist. 2228 */ 2229 evlist__for_each_entry(metric_evlist, metric_evsel) { 2230 struct evsel *script_evsel = 2231 map_metric_evsel_to_script_evsel(script_evlist, metric_evsel); 2232 struct metric_event *metric_me = metricgroup__lookup(&metric_evlist->metric_events, 2233 metric_evsel, 2234 /*create=*/false); 2235 2236 if (script_evsel->metric_id == NULL) { 2237 script_evsel->metric_id = metric_evsel->metric_id; 2238 metric_evsel->metric_id = NULL; 2239 } 2240 2241 if (script_evsel->metric_leader == NULL) { 2242 if (metric_evsel->metric_leader == metric_evsel) { 2243 script_evsel->metric_leader = script_evsel; 2244 } else { 2245 script_evsel->metric_leader = 2246 map_metric_evsel_to_script_evsel(script_evlist, 2247 metric_evsel->metric_leader); 2248 } 2249 } 2250 2251 if (metric_me) { 2252 struct metric_expr *expr; 2253 struct metric_event *script_me = 2254 metricgroup__lookup(&script_evlist->metric_events, 2255 script_evsel, 2256 /*create=*/true); 2257 2258 if (!script_me) { 2259 /* 2260 * As the metric_expr is created, the only 2261 * failure is a lack of memory. 2262 */ 2263 goto out; 2264 } 2265 list_splice_init(&metric_me->head, &script_me->head); 2266 list_for_each_entry(expr, &script_me->head, nd) { 2267 for (int i = 0; expr->metric_events[i]; i++) { 2268 expr->metric_events[i] = 2269 map_metric_evsel_to_script_evsel(script_evlist, 2270 expr->metric_events[i]); 2271 } 2272 } 2273 } 2274 } 2275 pr_debug("Found metric '%s' whose evsels match those of in the perf data\n", 2276 pm->metric_name); 2277 evlist__delete(metric_evlist); 2278 out: 2279 return 0; 2280 } 2281 2282 static struct aggr_cpu_id script_aggr_cpu_id_get(struct perf_stat_config *config __maybe_unused, 2283 struct perf_cpu cpu) 2284 { 2285 return aggr_cpu_id__global(cpu, /*data=*/NULL); 2286 } 2287 2288 static void perf_sample__fprint_metric(struct thread *thread, 2289 struct evsel *evsel, 2290 struct perf_sample *sample, 2291 FILE *fp) 2292 { 2293 static bool init_metrics; 2294 struct perf_stat_output_ctx ctx = { 2295 .print_metric = script_print_metric, 2296 .new_line = script_new_line, 2297 .ctx = &(struct metric_ctx) { 2298 .sample = sample, 2299 .thread = thread, 2300 .evsel = evsel, 2301 .fp = fp, 2302 }, 2303 .force_header = false, 2304 }; 2305 struct perf_counts_values *count, *old_count; 2306 int cpu_map_idx, thread_map_idx, aggr_idx; 2307 struct evsel *pos; 2308 2309 if (!init_metrics) { 2310 /* One time initialization of stat_config and metric data. */ 2311 struct script_find_metrics_args args = { 2312 .evlist = evsel->evlist, 2313 .system_wide = perf_thread_map__pid(evsel->core.threads, /*idx=*/0) == -1, 2314 2315 }; 2316 if (!stat_config.output) 2317 stat_config.output = stdout; 2318 2319 if (!stat_config.aggr_map) { 2320 /* TODO: currently only global aggregation is supported. */ 2321 assert(stat_config.aggr_mode == AGGR_GLOBAL); 2322 stat_config.aggr_get_id = script_aggr_cpu_id_get; 2323 stat_config.aggr_map = 2324 cpu_aggr_map__new(evsel->evlist->core.user_requested_cpus, 2325 aggr_cpu_id__global, /*data=*/NULL, 2326 /*needs_sort=*/false); 2327 } 2328 2329 metricgroup__for_each_metric(pmu_metrics_table__find(), script_find_metrics, &args); 2330 init_metrics = true; 2331 } 2332 2333 if (!evsel->stats) { 2334 if (evlist__alloc_stats(&stat_config, evsel->evlist, /*alloc_raw=*/true) < 0) 2335 return; 2336 } 2337 if (!evsel->stats->aggr) { 2338 if (evlist__alloc_aggr_stats(evsel->evlist, stat_config.aggr_map->nr) < 0) 2339 return; 2340 } 2341 2342 /* Update the evsel's count using the sample's data. */ 2343 cpu_map_idx = perf_cpu_map__idx(evsel->core.cpus, (struct perf_cpu){sample->cpu}); 2344 if (cpu_map_idx < 0) { 2345 /* Missing CPU, check for any CPU. */ 2346 if (perf_cpu_map__cpu(evsel->core.cpus, /*idx=*/0).cpu == -1 || 2347 sample->cpu == (u32)-1) { 2348 /* Place the counts in the which ever CPU is first in the map. */ 2349 cpu_map_idx = 0; 2350 } else { 2351 pr_info("Missing CPU map entry for CPU %d\n", sample->cpu); 2352 return; 2353 } 2354 } 2355 thread_map_idx = perf_thread_map__idx(evsel->core.threads, sample->tid); 2356 if (thread_map_idx < 0) { 2357 /* Missing thread, check for any thread. */ 2358 if (perf_thread_map__pid(evsel->core.threads, /*idx=*/0) == -1 || 2359 sample->tid == (u32)-1) { 2360 /* Place the counts in the which ever thread is first in the map. */ 2361 thread_map_idx = 0; 2362 } else { 2363 pr_info("Missing thread map entry for thread %d\n", sample->tid); 2364 return; 2365 } 2366 } 2367 count = perf_counts(evsel->counts, cpu_map_idx, thread_map_idx); 2368 old_count = perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread_map_idx); 2369 count->val = old_count->val + sample->period; 2370 count->run = old_count->run + 1; 2371 count->ena = old_count->ena + 1; 2372 2373 /* Update the aggregated stats. */ 2374 perf_stat_process_counter(&stat_config, evsel); 2375 2376 /* Display all metrics. */ 2377 evlist__for_each_entry(evsel->evlist, pos) { 2378 cpu_aggr_map__for_each_idx(aggr_idx, stat_config.aggr_map) { 2379 perf_stat__print_shadow_stats(&stat_config, pos, 2380 aggr_idx, 2381 &ctx); 2382 } 2383 } 2384 } 2385 2386 static bool show_event(struct perf_sample *sample, 2387 struct evsel *evsel, 2388 struct thread *thread, 2389 struct addr_location *al, 2390 struct addr_location *addr_al) 2391 { 2392 int depth = thread_stack__depth(thread, sample->cpu); 2393 2394 if (!symbol_conf.graph_function) 2395 return true; 2396 2397 if (thread__filter(thread)) { 2398 if (depth <= thread__filter_entry_depth(thread)) { 2399 thread__set_filter(thread, false); 2400 return false; 2401 } 2402 return true; 2403 } else { 2404 const char *s = symbol_conf.graph_function; 2405 u64 ip; 2406 const char *name = resolve_branch_sym(sample, evsel, thread, al, addr_al, 2407 &ip); 2408 unsigned nlen; 2409 2410 if (!name) 2411 return false; 2412 nlen = strlen(name); 2413 while (*s) { 2414 unsigned len = strcspn(s, ","); 2415 if (nlen == len && !strncmp(name, s, len)) { 2416 thread__set_filter(thread, true); 2417 thread__set_filter_entry_depth(thread, depth); 2418 return true; 2419 } 2420 s += len; 2421 if (*s == ',') 2422 s++; 2423 } 2424 return false; 2425 } 2426 } 2427 2428 static void process_event(struct perf_script *script, 2429 struct perf_sample *sample, 2430 struct addr_location *al, 2431 struct addr_location *addr_al, 2432 struct machine *machine) 2433 { 2434 struct thread *thread = al->thread; 2435 struct evsel *evsel = sample->evsel; 2436 struct perf_event_attr *attr = &evsel->core.attr; 2437 unsigned int type = evsel__output_type(evsel); 2438 struct evsel_script *es = evsel->priv; 2439 FILE *fp = es->fp; 2440 char str[PAGE_SIZE_NAME_LEN]; 2441 uint32_t e_flags; 2442 2443 if (output[type].fields == 0) 2444 return; 2445 2446 ++es->samples; 2447 2448 perf_sample__fprintf_start(script, sample, thread, evsel, 2449 PERF_RECORD_SAMPLE, fp); 2450 2451 if (PRINT_FIELD(PERIOD)) 2452 fprintf(fp, "%10" PRIu64 " ", sample->period); 2453 2454 if (PRINT_FIELD(EVNAME)) { 2455 const char *evname = evsel__name(evsel); 2456 2457 if (!script->name_width) 2458 script->name_width = evlist__max_name_len(script->session->evlist); 2459 2460 fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]"); 2461 } 2462 2463 if (print_flags) 2464 perf_sample__fprintf_flags(sample->flags, fp); 2465 2466 if (is_bts_event(attr)) { 2467 perf_sample__fprintf_bts(sample, evsel, thread, al, addr_al, machine, fp); 2468 return; 2469 } 2470 #ifdef HAVE_LIBTRACEEVENT 2471 if (PRINT_FIELD(TRACE) && sample->raw_data) { 2472 const struct tep_event *tp_format = evsel__tp_format(evsel); 2473 2474 if (tp_format) { 2475 event_format__fprintf(tp_format, sample->cpu, 2476 sample->raw_data, sample->raw_size, 2477 fp); 2478 } 2479 } 2480 #endif 2481 if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH)) 2482 perf_sample__fprintf_synth(sample, evsel, fp); 2483 2484 if (PRINT_FIELD(ADDR)) 2485 perf_sample__fprintf_addr(sample, thread, evsel, fp); 2486 2487 if (PRINT_FIELD(DATA_SRC)) 2488 data_src__fprintf(sample->data_src, fp); 2489 2490 if (PRINT_FIELD(WEIGHT)) 2491 fprintf(fp, "%16" PRIu64, sample->weight); 2492 2493 if (PRINT_FIELD(INS_LAT)) 2494 fprintf(fp, "%16" PRIu16, sample->ins_lat); 2495 2496 if (PRINT_FIELD(RETIRE_LAT)) 2497 fprintf(fp, "%16" PRIu16, sample->weight3); 2498 2499 if (PRINT_FIELD(CGROUP)) { 2500 const char *cgrp_name; 2501 struct cgroup *cgrp = cgroup__find(machine->env, 2502 sample->cgroup); 2503 if (cgrp != NULL) 2504 cgrp_name = cgrp->name; 2505 else 2506 cgrp_name = "unknown"; 2507 fprintf(fp, " %s", cgrp_name); 2508 } 2509 2510 if (PRINT_FIELD(IP)) { 2511 struct callchain_cursor *cursor = NULL; 2512 2513 if (script->stitch_lbr) 2514 thread__set_lbr_stitch_enable(al->thread, true); 2515 2516 if (symbol_conf.use_callchain && sample->callchain) { 2517 cursor = get_tls_callchain_cursor(); 2518 if (thread__resolve_callchain(al->thread, cursor, 2519 sample, NULL, NULL, 2520 scripting_max_stack)) 2521 cursor = NULL; 2522 } 2523 fputc(cursor ? '\n' : ' ', fp); 2524 sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, 2525 symbol_conf.bt_stop_list, fp); 2526 } 2527 2528 if (PRINT_FIELD(IREGS)) { 2529 perf_sample__fprintf_iregs(sample, attr, 2530 thread__e_machine(thread, machine, &e_flags), 2531 e_flags, 2532 fp); 2533 } 2534 2535 if (PRINT_FIELD(UREGS)) { 2536 perf_sample__fprintf_uregs(sample, attr, 2537 thread__e_machine(thread, machine, &e_flags), 2538 e_flags, 2539 fp); 2540 } 2541 2542 if (PRINT_FIELD(BRSTACK)) 2543 perf_sample__fprintf_brstack(sample, thread, evsel, fp); 2544 else if (PRINT_FIELD(BRSTACKSYM)) 2545 perf_sample__fprintf_brstacksym(sample, thread, evsel, fp); 2546 else if (PRINT_FIELD(BRSTACKOFF)) 2547 perf_sample__fprintf_brstackoff(sample, thread, evsel, fp); 2548 2549 if (evsel__is_bpf_output(evsel) && !evsel__is_offcpu_event(evsel) && PRINT_FIELD(BPF_OUTPUT)) 2550 perf_sample__fprintf_bpf_output(sample, fp); 2551 perf_sample__fprintf_insn(sample, evsel, attr, thread, machine, fp, al); 2552 2553 if (PRINT_FIELD(PHYS_ADDR)) 2554 fprintf(fp, "%16" PRIx64, sample->phys_addr); 2555 2556 if (PRINT_FIELD(DATA_PAGE_SIZE)) 2557 fprintf(fp, " %s", get_page_size_name(sample->data_page_size, str)); 2558 2559 if (PRINT_FIELD(CODE_PAGE_SIZE)) 2560 fprintf(fp, " %s", get_page_size_name(sample->code_page_size, str)); 2561 2562 perf_sample__fprintf_ipc(sample, evsel, fp); 2563 2564 fprintf(fp, "\n"); 2565 2566 if (PRINT_FIELD(SRCCODE)) { 2567 if (map__fprintf_srccode(al->map, al->addr, stdout, 2568 thread__srccode_state(thread))) 2569 printf("\n"); 2570 } 2571 2572 if (PRINT_FIELD(METRIC)) 2573 perf_sample__fprint_metric(thread, evsel, sample, fp); 2574 2575 if (verbose > 0) 2576 fflush(fp); 2577 } 2578 2579 static struct scripting_ops *scripting_ops; 2580 2581 static void __process_stat(struct evsel *counter, u64 tstamp) 2582 { 2583 int nthreads = perf_thread_map__nr(counter->core.threads); 2584 struct perf_cpu cpu; 2585 static int header_printed; 2586 2587 if (!header_printed) { 2588 printf("%3s %8s %15s %15s %15s %15s %s\n", 2589 "CPU", "THREAD", "VAL", "ENA", "RUN", "TIME", "EVENT"); 2590 header_printed = 1; 2591 } 2592 2593 for (int thread = 0; thread < nthreads; thread++) { 2594 unsigned int idx; 2595 2596 perf_cpu_map__for_each_cpu(cpu, idx, evsel__cpus(counter)) { 2597 struct perf_counts_values *counts; 2598 2599 counts = perf_counts(counter->counts, idx, thread); 2600 2601 printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n", 2602 cpu.cpu, 2603 perf_thread_map__pid(counter->core.threads, thread), 2604 counts->val, 2605 counts->ena, 2606 counts->run, 2607 tstamp, 2608 evsel__name(counter)); 2609 } 2610 } 2611 } 2612 2613 static void process_stat(struct evsel *counter, u64 tstamp) 2614 { 2615 if (scripting_ops && scripting_ops->process_stat) 2616 scripting_ops->process_stat(&stat_config, counter, tstamp); 2617 else 2618 __process_stat(counter, tstamp); 2619 } 2620 2621 static void process_stat_interval(u64 tstamp) 2622 { 2623 if (scripting_ops && scripting_ops->process_stat_interval) 2624 scripting_ops->process_stat_interval(tstamp); 2625 } 2626 2627 static void setup_scripting(void) 2628 { 2629 #ifdef HAVE_LIBTRACEEVENT 2630 setup_perl_scripting(); 2631 #endif 2632 setup_python_scripting(); 2633 } 2634 2635 static int flush_scripting(void) 2636 { 2637 return scripting_ops ? scripting_ops->flush_script() : 0; 2638 } 2639 2640 static int cleanup_scripting(void) 2641 { 2642 pr_debug("\nperf script stopped\n"); 2643 2644 return scripting_ops ? scripting_ops->stop_script() : 0; 2645 } 2646 2647 static bool filter_cpu(struct perf_sample *sample) 2648 { 2649 if (cpu_list && sample->cpu != (u32)-1 && sample->cpu < MAX_NR_CPUS) 2650 return !test_bit(sample->cpu, cpu_bitmap); 2651 return false; 2652 } 2653 2654 static int process_sample_event(const struct perf_tool *tool, 2655 union perf_event *event, 2656 struct perf_sample *sample, 2657 struct machine *machine) 2658 { 2659 struct perf_script *scr = container_of(tool, struct perf_script, tool); 2660 struct evsel *evsel = sample->evsel; 2661 struct addr_location al; 2662 struct addr_location addr_al; 2663 int ret = 0; 2664 2665 /* Set thread to NULL to indicate addr_al and al are not initialized */ 2666 addr_location__init(&al); 2667 addr_location__init(&addr_al); 2668 2669 ret = dlfilter__filter_event_early(dlfilter, event, sample, evsel, machine, &al, &addr_al); 2670 if (ret) { 2671 if (ret > 0) 2672 ret = 0; 2673 goto out_put; 2674 } 2675 2676 if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num, 2677 sample->time)) { 2678 goto out_put; 2679 } 2680 2681 if (debug_mode) { 2682 if (sample->time < last_timestamp) { 2683 pr_err("Samples misordered, previous: %" PRIu64 2684 " this: %" PRIu64 "\n", last_timestamp, 2685 sample->time); 2686 nr_unordered++; 2687 } 2688 last_timestamp = sample->time; 2689 goto out_put; 2690 } 2691 2692 if (filter_cpu(sample)) 2693 goto out_put; 2694 2695 if (!al.thread && machine__resolve(machine, &al, sample) < 0) { 2696 pr_err("problem processing %s (%u) event at offset %#" PRIx64 ", skipping it.\n", 2697 perf_event__name(event->header.type), event->header.type, 2698 sample->file_offset); 2699 ret = -1; 2700 goto out_put; 2701 } 2702 2703 if (al.filtered) 2704 goto out_put; 2705 2706 if (!show_event(sample, evsel, al.thread, &al, &addr_al)) 2707 goto out_put; 2708 2709 if (evswitch__discard(&scr->evswitch, evsel)) 2710 goto out_put; 2711 2712 ret = dlfilter__filter_event(dlfilter, event, sample, evsel, machine, &al, &addr_al); 2713 if (ret) { 2714 if (ret > 0) 2715 ret = 0; 2716 goto out_put; 2717 } 2718 2719 if (scripting_ops) { 2720 struct addr_location *addr_al_ptr = NULL; 2721 2722 if ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) && 2723 sample_addr_correlates_sym(&evsel->core.attr)) { 2724 if (!addr_al.thread) 2725 thread__resolve(al.thread, &addr_al, sample); 2726 addr_al_ptr = &addr_al; 2727 } 2728 scripting_ops->process_event(event, sample, &al, addr_al_ptr); 2729 } else { 2730 process_event(scr, sample, &al, &addr_al, machine); 2731 } 2732 2733 out_put: 2734 addr_location__exit(&addr_al); 2735 addr_location__exit(&al); 2736 return ret; 2737 } 2738 2739 static int process_deferred_sample_event(const struct perf_tool *tool, 2740 union perf_event *event, 2741 struct perf_sample *sample, 2742 struct machine *machine) 2743 { 2744 struct perf_script *scr = container_of(tool, struct perf_script, tool); 2745 struct evsel *evsel = sample->evsel; 2746 struct perf_event_attr *attr = &evsel->core.attr; 2747 struct evsel_script *es = evsel->priv; 2748 unsigned int type = output_type(attr->type); 2749 struct addr_location al; 2750 FILE *fp = es->fp; 2751 int ret = 0; 2752 2753 if (output[type].fields == 0) 2754 return 0; 2755 2756 /* Set thread to NULL to indicate addr_al and al are not initialized */ 2757 addr_location__init(&al); 2758 2759 if (perf_time__ranges_skip_sample(scr->ptime_range, scr->range_num, 2760 sample->time)) { 2761 goto out_put; 2762 } 2763 2764 if (debug_mode) { 2765 if (sample->time < last_timestamp) { 2766 pr_err("Samples misordered, previous: %" PRIu64 2767 " this: %" PRIu64 "\n", last_timestamp, 2768 sample->time); 2769 nr_unordered++; 2770 } 2771 last_timestamp = sample->time; 2772 goto out_put; 2773 } 2774 2775 if (filter_cpu(sample)) 2776 goto out_put; 2777 2778 if (machine__resolve(machine, &al, sample) < 0) { 2779 pr_err("problem processing %s (%u) event at offset %#" PRIx64 ", skipping it.\n", 2780 perf_event__name(event->header.type), event->header.type, 2781 sample->file_offset); 2782 ret = -1; 2783 goto out_put; 2784 } 2785 2786 if (al.filtered) 2787 goto out_put; 2788 2789 if (!show_event(sample, evsel, al.thread, &al, NULL)) 2790 goto out_put; 2791 2792 if (evswitch__discard(&scr->evswitch, evsel)) 2793 goto out_put; 2794 2795 perf_sample__fprintf_start(scr, sample, al.thread, evsel, 2796 PERF_RECORD_CALLCHAIN_DEFERRED, fp); 2797 fprintf(fp, "DEFERRED CALLCHAIN [cookie: %llx]", 2798 (unsigned long long)event->callchain_deferred.cookie); 2799 2800 if (PRINT_FIELD(IP)) { 2801 struct callchain_cursor *cursor = NULL; 2802 2803 if (symbol_conf.use_callchain && sample->callchain) { 2804 cursor = get_tls_callchain_cursor(); 2805 if (thread__resolve_callchain(al.thread, cursor, 2806 sample, NULL, NULL, 2807 scripting_max_stack)) { 2808 pr_info("cannot resolve deferred callchains\n"); 2809 cursor = NULL; 2810 } 2811 } 2812 2813 fputc(cursor ? '\n' : ' ', fp); 2814 sample__fprintf_sym(sample, &al, 0, output[type].print_ip_opts, 2815 cursor, symbol_conf.bt_stop_list, fp); 2816 } 2817 2818 fprintf(fp, "\n"); 2819 2820 if (verbose > 0) 2821 fflush(fp); 2822 2823 out_put: 2824 addr_location__exit(&al); 2825 return ret; 2826 } 2827 2828 // Used when scr->per_event_dump is not set 2829 static struct evsel_script es_stdout; 2830 2831 static int process_attr(const struct perf_tool *tool, union perf_event *event, 2832 struct evlist **pevlist) 2833 { 2834 struct perf_script *scr = container_of(tool, struct perf_script, tool); 2835 struct evlist *evlist; 2836 struct evsel *evsel, *pos; 2837 uint16_t e_machine; 2838 u64 sample_type; 2839 int err; 2840 2841 err = perf_event__process_attr(tool, event, pevlist); 2842 if (err) 2843 return err; 2844 2845 evlist = *pevlist; 2846 evsel = evlist__last(*pevlist); 2847 2848 if (!evsel->priv) { 2849 if (scr->per_event_dump) { 2850 evsel->priv = evsel_script__new(evsel, scr->session->data); 2851 if (!evsel->priv) 2852 return -ENOMEM; 2853 } else { // Replicate what is done in perf_script__setup_per_event_dump() 2854 es_stdout.fp = stdout; 2855 evsel->priv = &es_stdout; 2856 } 2857 } 2858 2859 if (evsel->core.attr.type >= PERF_TYPE_MAX && 2860 evsel->core.attr.type != PERF_TYPE_SYNTH) 2861 return 0; 2862 2863 evlist__for_each_entry(evlist, pos) { 2864 if (pos->core.attr.type == evsel->core.attr.type && pos != evsel) 2865 return 0; 2866 } 2867 2868 if (evsel->core.attr.sample_type) { 2869 err = evsel__check_attr(evsel, scr->session); 2870 if (err) 2871 return err; 2872 } 2873 2874 /* 2875 * Check if we need to enable callchains based 2876 * on events sample_type. 2877 */ 2878 sample_type = evlist__combined_sample_type(evlist); 2879 e_machine = perf_session__e_machine(evsel__session(evsel), /*e_flags=*/NULL); 2880 callchain_param_setup(sample_type, e_machine); 2881 2882 /* Enable fields for callchain entries */ 2883 if (symbol_conf.use_callchain && 2884 (sample_type & PERF_SAMPLE_CALLCHAIN || 2885 sample_type & PERF_SAMPLE_BRANCH_STACK || 2886 (sample_type & PERF_SAMPLE_REGS_USER && 2887 sample_type & PERF_SAMPLE_STACK_USER))) { 2888 int type = evsel__output_type(evsel); 2889 2890 if (!(output[type].user_unset_fields & PERF_OUTPUT_IP)) 2891 output[type].fields |= PERF_OUTPUT_IP; 2892 if (!(output[type].user_unset_fields & PERF_OUTPUT_SYM)) 2893 output[type].fields |= PERF_OUTPUT_SYM; 2894 } 2895 evsel__set_print_ip_opts(evsel); 2896 return 0; 2897 } 2898 2899 static int print_event_with_time(const struct perf_tool *tool, 2900 union perf_event *event, 2901 struct perf_sample *sample, 2902 struct machine *machine, 2903 pid_t pid, pid_t tid, u64 timestamp) 2904 { 2905 struct perf_script *script = container_of(tool, struct perf_script, tool); 2906 struct perf_session *session = script->session; 2907 struct evsel *evsel = sample->evsel; 2908 struct thread *thread = NULL; 2909 2910 if (!evsel) 2911 evsel = evlist__id2evsel(session->evlist, sample->id); 2912 2913 if (evsel && !evsel->core.attr.sample_id_all) { 2914 sample->cpu = 0; 2915 sample->time = timestamp; 2916 sample->pid = pid; 2917 sample->tid = tid; 2918 } 2919 2920 if (filter_cpu(sample)) 2921 return 0; 2922 2923 if (tid != -1) 2924 thread = machine__findnew_thread(machine, pid, tid); 2925 2926 if (evsel) { 2927 struct evsel *saved_evsel = sample->evsel; 2928 2929 sample->evsel = evsel; 2930 perf_sample__fprintf_start(script, sample, thread, evsel, 2931 event->header.type, stdout); 2932 sample->evsel = saved_evsel; 2933 } 2934 2935 perf_event__fprintf(event, machine, stdout); 2936 2937 thread__put(thread); 2938 2939 return 0; 2940 } 2941 2942 static int print_event(const struct perf_tool *tool, union perf_event *event, 2943 struct perf_sample *sample, struct machine *machine, 2944 pid_t pid, pid_t tid) 2945 { 2946 return print_event_with_time(tool, event, sample, machine, pid, tid, 0); 2947 } 2948 2949 static int process_comm_event(const struct perf_tool *tool, 2950 union perf_event *event, 2951 struct perf_sample *sample, 2952 struct machine *machine) 2953 { 2954 if (perf_event__process_comm(tool, event, sample, machine) < 0) 2955 return -1; 2956 2957 return print_event(tool, event, sample, machine, event->comm.pid, 2958 event->comm.tid); 2959 } 2960 2961 static int process_namespaces_event(const struct perf_tool *tool, 2962 union perf_event *event, 2963 struct perf_sample *sample, 2964 struct machine *machine) 2965 { 2966 if (perf_event__process_namespaces(tool, event, sample, machine) < 0) 2967 return -1; 2968 2969 return print_event(tool, event, sample, machine, event->namespaces.pid, 2970 event->namespaces.tid); 2971 } 2972 2973 static int process_cgroup_event(const struct perf_tool *tool, 2974 union perf_event *event, 2975 struct perf_sample *sample, 2976 struct machine *machine) 2977 { 2978 if (perf_event__process_cgroup(tool, event, sample, machine) < 0) 2979 return -1; 2980 2981 return print_event(tool, event, sample, machine, sample->pid, 2982 sample->tid); 2983 } 2984 2985 static int process_fork_event(const struct perf_tool *tool, 2986 union perf_event *event, 2987 struct perf_sample *sample, 2988 struct machine *machine) 2989 { 2990 if (perf_event__process_fork(tool, event, sample, machine) < 0) 2991 return -1; 2992 2993 return print_event_with_time(tool, event, sample, machine, 2994 event->fork.pid, event->fork.tid, 2995 event->fork.time); 2996 } 2997 static int process_exit_event(const struct perf_tool *tool, 2998 union perf_event *event, 2999 struct perf_sample *sample, 3000 struct machine *machine) 3001 { 3002 /* Print before 'exit' deletes anything */ 3003 if (print_event_with_time(tool, event, sample, machine, event->fork.pid, 3004 event->fork.tid, event->fork.time)) 3005 return -1; 3006 3007 return perf_event__process_exit(tool, event, sample, machine); 3008 } 3009 3010 static int process_mmap_event(const struct perf_tool *tool, 3011 union perf_event *event, 3012 struct perf_sample *sample, 3013 struct machine *machine) 3014 { 3015 if (perf_event__process_mmap(tool, event, sample, machine) < 0) 3016 return -1; 3017 3018 return print_event(tool, event, sample, machine, event->mmap.pid, 3019 event->mmap.tid); 3020 } 3021 3022 static int process_mmap2_event(const struct perf_tool *tool, 3023 union perf_event *event, 3024 struct perf_sample *sample, 3025 struct machine *machine) 3026 { 3027 if (perf_event__process_mmap2(tool, event, sample, machine) < 0) 3028 return -1; 3029 3030 return print_event(tool, event, sample, machine, event->mmap2.pid, 3031 event->mmap2.tid); 3032 } 3033 3034 static int process_switch_event(const struct perf_tool *tool, 3035 union perf_event *event, 3036 struct perf_sample *sample, 3037 struct machine *machine) 3038 { 3039 struct perf_script *script = container_of(tool, struct perf_script, tool); 3040 3041 if (perf_event__process_switch(tool, event, sample, machine) < 0) 3042 return -1; 3043 3044 if (scripting_ops && scripting_ops->process_switch && !filter_cpu(sample)) 3045 scripting_ops->process_switch(event, sample, machine); 3046 3047 if (!script->show_switch_events) 3048 return 0; 3049 3050 return print_event(tool, event, sample, machine, sample->pid, 3051 sample->tid); 3052 } 3053 3054 static int process_auxtrace_error(const struct perf_tool *tool, 3055 struct perf_session *session, 3056 union perf_event *event) 3057 { 3058 if (scripting_ops && scripting_ops->process_auxtrace_error) { 3059 scripting_ops->process_auxtrace_error(session, event); 3060 return 0; 3061 } 3062 3063 return perf_event__process_auxtrace_error(tool, session, event); 3064 } 3065 3066 static int 3067 process_lost_event(const struct perf_tool *tool, 3068 union perf_event *event, 3069 struct perf_sample *sample, 3070 struct machine *machine) 3071 { 3072 return print_event(tool, event, sample, machine, sample->pid, 3073 sample->tid); 3074 } 3075 3076 static int 3077 process_throttle_event(const struct perf_tool *tool __maybe_unused, 3078 union perf_event *event, 3079 struct perf_sample *sample, 3080 struct machine *machine) 3081 { 3082 if (scripting_ops && scripting_ops->process_throttle) 3083 scripting_ops->process_throttle(event, sample, machine); 3084 return 0; 3085 } 3086 3087 static int 3088 process_finished_round_event(const struct perf_tool *tool __maybe_unused, 3089 union perf_event *event, 3090 struct ordered_events *oe __maybe_unused) 3091 3092 { 3093 perf_event__fprintf(event, NULL, stdout); 3094 return 0; 3095 } 3096 3097 static int 3098 process_bpf_events(const struct perf_tool *tool __maybe_unused, 3099 union perf_event *event, 3100 struct perf_sample *sample, 3101 struct machine *machine) 3102 { 3103 if (machine__process_ksymbol(machine, event, sample) < 0) 3104 return -1; 3105 3106 return print_event(tool, event, sample, machine, sample->pid, 3107 sample->tid); 3108 } 3109 3110 static int 3111 process_bpf_metadata_event(const struct perf_tool *tool __maybe_unused, 3112 struct perf_session *session __maybe_unused, 3113 union perf_event *event) 3114 { 3115 perf_event__fprintf(event, NULL, stdout); 3116 return 0; 3117 } 3118 3119 static int process_text_poke_events(const struct perf_tool *tool, 3120 union perf_event *event, 3121 struct perf_sample *sample, 3122 struct machine *machine) 3123 { 3124 if (perf_event__process_text_poke(tool, event, sample, machine) < 0) 3125 return -1; 3126 3127 return print_event(tool, event, sample, machine, sample->pid, 3128 sample->tid); 3129 } 3130 3131 static void sig_handler(int sig __maybe_unused) 3132 { 3133 session_done = 1; 3134 } 3135 3136 static void perf_script__fclose_per_event_dump(struct perf_script *script) 3137 { 3138 struct evlist *evlist = script->session->evlist; 3139 struct evsel *evsel; 3140 3141 evlist__for_each_entry(evlist, evsel) { 3142 if (!evsel->priv) 3143 break; 3144 evsel_script__delete(evsel->priv); 3145 evsel->priv = NULL; 3146 } 3147 } 3148 3149 static int perf_script__fopen_per_event_dump(struct perf_script *script) 3150 { 3151 struct evsel *evsel; 3152 3153 evlist__for_each_entry(script->session->evlist, evsel) { 3154 /* 3155 * Already setup? I.e. we may be called twice in cases like 3156 * Intel PT, one for the intel_pt// and dummy events, then 3157 * for the evsels synthesized from the auxtrace info. 3158 * 3159 * Ses perf_script__process_auxtrace_info. 3160 */ 3161 if (evsel->priv != NULL) 3162 continue; 3163 3164 evsel->priv = evsel_script__new(evsel, script->session->data); 3165 if (evsel->priv == NULL) 3166 goto out_err_fclose; 3167 } 3168 3169 return 0; 3170 3171 out_err_fclose: 3172 perf_script__fclose_per_event_dump(script); 3173 return -1; 3174 } 3175 3176 static int perf_script__setup_per_event_dump(struct perf_script *script) 3177 { 3178 struct evsel *evsel; 3179 3180 if (script->per_event_dump) 3181 return perf_script__fopen_per_event_dump(script); 3182 3183 es_stdout.fp = stdout; 3184 3185 evlist__for_each_entry(script->session->evlist, evsel) 3186 evsel->priv = &es_stdout; 3187 3188 return 0; 3189 } 3190 3191 static void perf_script__exit_per_event_dump_stats(struct perf_script *script) 3192 { 3193 struct evsel *evsel; 3194 3195 evlist__for_each_entry(script->session->evlist, evsel) { 3196 struct evsel_script *es = evsel->priv; 3197 3198 evsel_script__fprintf(es, stdout); 3199 evsel_script__delete(es); 3200 evsel->priv = NULL; 3201 } 3202 } 3203 3204 static void perf_script__exit(struct perf_script *script) 3205 { 3206 perf_thread_map__put(script->threads); 3207 perf_cpu_map__put(script->cpus); 3208 } 3209 3210 static int __cmd_script(struct perf_script *script) 3211 { 3212 int ret; 3213 3214 signal(SIGINT, sig_handler); 3215 3216 /* override event processing functions */ 3217 if (script->show_task_events) { 3218 script->tool.comm = process_comm_event; 3219 script->tool.fork = process_fork_event; 3220 script->tool.exit = process_exit_event; 3221 } 3222 if (script->show_mmap_events) { 3223 script->tool.mmap = process_mmap_event; 3224 script->tool.mmap2 = process_mmap2_event; 3225 } 3226 if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch)) 3227 script->tool.context_switch = process_switch_event; 3228 if (scripting_ops && scripting_ops->process_auxtrace_error) 3229 script->tool.auxtrace_error = process_auxtrace_error; 3230 if (script->show_namespace_events) 3231 script->tool.namespaces = process_namespaces_event; 3232 if (script->show_cgroup_events) 3233 script->tool.cgroup = process_cgroup_event; 3234 if (script->show_lost_events) 3235 script->tool.lost = process_lost_event; 3236 if (script->show_round_events) { 3237 script->tool.ordered_events = false; 3238 script->tool.finished_round = process_finished_round_event; 3239 } 3240 if (script->show_bpf_events) { 3241 script->tool.ksymbol = process_bpf_events; 3242 script->tool.bpf = process_bpf_events; 3243 script->tool.bpf_metadata = process_bpf_metadata_event; 3244 } 3245 if (script->show_text_poke_events) { 3246 script->tool.ksymbol = process_bpf_events; 3247 script->tool.text_poke = process_text_poke_events; 3248 } 3249 3250 if (perf_script__setup_per_event_dump(script)) { 3251 pr_err("Couldn't create the per event dump files\n"); 3252 return -1; 3253 } 3254 3255 ret = perf_session__process_events(script->session); 3256 3257 if (script->per_event_dump) 3258 perf_script__exit_per_event_dump_stats(script); 3259 3260 if (debug_mode) 3261 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 3262 3263 return ret; 3264 } 3265 3266 static int list_available_languages_cb(struct scripting_ops *ops, const char *spec) 3267 { 3268 fprintf(stderr, " %-42s [%s]\n", spec, ops->name); 3269 return 0; 3270 } 3271 3272 static void list_available_languages(void) 3273 { 3274 fprintf(stderr, "\n"); 3275 fprintf(stderr, "Scripting language extensions (used in " 3276 "perf script -s [spec:]script.[spec]):\n\n"); 3277 script_spec__for_each(&list_available_languages_cb); 3278 fprintf(stderr, "\n"); 3279 } 3280 3281 /* Find script file relative to current directory or exec path */ 3282 static char *find_script(const char *script) 3283 { 3284 char path[PATH_MAX]; 3285 3286 if (!scripting_ops) { 3287 const char *ext = strrchr(script, '.'); 3288 3289 if (!ext) 3290 return NULL; 3291 3292 scripting_ops = script_spec__lookup(++ext); 3293 if (!scripting_ops) 3294 return NULL; 3295 } 3296 3297 if (access(script, R_OK)) { 3298 char *exec_path = get_argv_exec_path(); 3299 3300 if (!exec_path) 3301 return NULL; 3302 snprintf(path, sizeof(path), "%s/scripts/%s/%s", 3303 exec_path, scripting_ops->dirname, script); 3304 free(exec_path); 3305 script = path; 3306 if (access(script, R_OK)) 3307 return NULL; 3308 } 3309 return strdup(script); 3310 } 3311 3312 static int parse_scriptname(const struct option *opt __maybe_unused, 3313 const char *str, int unset __maybe_unused) 3314 { 3315 char spec[PATH_MAX]; 3316 const char *script, *ext; 3317 int len; 3318 3319 if (strcmp(str, "lang") == 0) { 3320 list_available_languages(); 3321 exit(0); 3322 } 3323 3324 script = strchr(str, ':'); 3325 if (script) { 3326 len = script - str; 3327 if (len >= PATH_MAX) { 3328 fprintf(stderr, "invalid language specifier"); 3329 return -1; 3330 } 3331 strncpy(spec, str, len); 3332 spec[len] = '\0'; 3333 scripting_ops = script_spec__lookup(spec); 3334 if (!scripting_ops) { 3335 fprintf(stderr, "invalid language specifier"); 3336 return -1; 3337 } 3338 script++; 3339 } else { 3340 script = str; 3341 ext = strrchr(script, '.'); 3342 if (!ext) { 3343 fprintf(stderr, "invalid script extension"); 3344 return -1; 3345 } 3346 scripting_ops = script_spec__lookup(++ext); 3347 if (!scripting_ops) { 3348 fprintf(stderr, "invalid script extension"); 3349 return -1; 3350 } 3351 } 3352 3353 script_name = find_script(script); 3354 if (!script_name) 3355 script_name = strdup(script); 3356 3357 return 0; 3358 } 3359 3360 static int parse_output_fields(const struct option *opt __maybe_unused, 3361 const char *arg, int unset __maybe_unused) 3362 { 3363 char *tok, *strtok_saveptr = NULL; 3364 int i, imax = ARRAY_SIZE(all_output_options); 3365 int j; 3366 int rc = 0; 3367 char *str = strdup(arg); 3368 int type = -1; 3369 enum { DEFAULT, SET, ADD, REMOVE } change = DEFAULT; 3370 3371 if (!str) 3372 return -ENOMEM; 3373 3374 /* first word can state for which event type the user is specifying 3375 * the fields. If no type exists, the specified fields apply to all 3376 * event types found in the file minus the invalid fields for a type. 3377 */ 3378 tok = strchr(str, ':'); 3379 if (tok) { 3380 *tok = '\0'; 3381 tok++; 3382 if (!strcmp(str, "hw")) 3383 type = PERF_TYPE_HARDWARE; 3384 else if (!strcmp(str, "sw")) 3385 type = PERF_TYPE_SOFTWARE; 3386 else if (!strcmp(str, "trace")) 3387 type = PERF_TYPE_TRACEPOINT; 3388 else if (!strcmp(str, "raw")) 3389 type = PERF_TYPE_RAW; 3390 else if (!strcmp(str, "break")) 3391 type = PERF_TYPE_BREAKPOINT; 3392 else if (!strcmp(str, "synth")) 3393 type = OUTPUT_TYPE_SYNTH; 3394 else { 3395 fprintf(stderr, "Invalid event type in field string.\n"); 3396 rc = -EINVAL; 3397 goto out; 3398 } 3399 3400 if (output[type].user_set) 3401 pr_warning("Overriding previous field request for %s events.\n", 3402 event_type(type)); 3403 3404 /* Don't override defaults for +- */ 3405 if (strchr(tok, '+') || strchr(tok, '-')) 3406 goto parse; 3407 3408 output[type].fields = 0; 3409 output[type].user_set = true; 3410 output[type].wildcard_set = false; 3411 3412 } else { 3413 tok = str; 3414 if (strlen(str) == 0) { 3415 fprintf(stderr, 3416 "Cannot set fields to 'none' for all event types.\n"); 3417 rc = -EINVAL; 3418 goto out; 3419 } 3420 3421 /* Don't override defaults for +- */ 3422 if (strchr(str, '+') || strchr(str, '-')) 3423 goto parse; 3424 3425 if (output_set_by_user()) 3426 pr_warning("Overriding previous field request for all events.\n"); 3427 3428 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) { 3429 output[j].fields = 0; 3430 output[j].user_set = true; 3431 output[j].wildcard_set = true; 3432 } 3433 } 3434 3435 parse: 3436 for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) { 3437 if (*tok == '+') { 3438 if (change == SET) 3439 goto out_badmix; 3440 change = ADD; 3441 tok++; 3442 } else if (*tok == '-') { 3443 if (change == SET) 3444 goto out_badmix; 3445 change = REMOVE; 3446 tok++; 3447 } else { 3448 if (change != SET && change != DEFAULT) 3449 goto out_badmix; 3450 change = SET; 3451 } 3452 3453 for (i = 0; i < imax; ++i) { 3454 if (strcmp(tok, all_output_options[i].str) == 0) 3455 break; 3456 } 3457 if (i == imax && strcmp(tok, "flags") == 0) { 3458 print_flags = change != REMOVE; 3459 continue; 3460 } 3461 if (i == imax) { 3462 fprintf(stderr, "Invalid field requested.\n"); 3463 rc = -EINVAL; 3464 goto out; 3465 } 3466 #ifndef HAVE_LIBCAPSTONE_SUPPORT 3467 if (change != REMOVE && strcmp(tok, "disasm") == 0) { 3468 fprintf(stderr, "Field \"disasm\" requires perf to be built with libcapstone support.\n"); 3469 rc = -EINVAL; 3470 goto out; 3471 } 3472 #endif 3473 3474 if (type == -1) { 3475 /* add user option to all events types for 3476 * which it is valid 3477 */ 3478 for (j = 0; j < OUTPUT_TYPE_MAX; ++j) { 3479 if (output[j].invalid_fields & all_output_options[i].field) { 3480 pr_warning("\'%s\' not valid for %s events. Ignoring.\n", 3481 all_output_options[i].str, event_type(j)); 3482 } else { 3483 if (change == REMOVE) { 3484 output[j].fields &= ~all_output_options[i].field; 3485 output[j].user_set_fields &= ~all_output_options[i].field; 3486 output[j].user_unset_fields |= all_output_options[i].field; 3487 } else { 3488 output[j].fields |= all_output_options[i].field; 3489 output[j].user_set_fields |= all_output_options[i].field; 3490 output[j].user_unset_fields &= ~all_output_options[i].field; 3491 } 3492 output[j].user_set = true; 3493 output[j].wildcard_set = true; 3494 } 3495 } 3496 } else { 3497 if (output[type].invalid_fields & all_output_options[i].field) { 3498 fprintf(stderr, "\'%s\' not valid for %s events.\n", 3499 all_output_options[i].str, event_type(type)); 3500 3501 rc = -EINVAL; 3502 goto out; 3503 } 3504 if (change == REMOVE) 3505 output[type].fields &= ~all_output_options[i].field; 3506 else 3507 output[type].fields |= all_output_options[i].field; 3508 output[type].user_set = true; 3509 output[type].wildcard_set = true; 3510 } 3511 } 3512 3513 if (type >= 0) { 3514 if (output[type].fields == 0) { 3515 pr_debug("No fields requested for %s type. " 3516 "Events will not be displayed.\n", event_type(type)); 3517 } 3518 } 3519 goto out; 3520 3521 out_badmix: 3522 fprintf(stderr, "Cannot mix +-field with overridden fields\n"); 3523 rc = -EINVAL; 3524 out: 3525 free(str); 3526 return rc; 3527 } 3528 3529 #define for_each_lang(scripts_path, scripts_dir, lang_dirent) \ 3530 while ((lang_dirent = readdir(scripts_dir)) != NULL) \ 3531 if ((lang_dirent->d_type == DT_DIR || \ 3532 (lang_dirent->d_type == DT_UNKNOWN && \ 3533 is_directory(scripts_path, lang_dirent))) && \ 3534 (strcmp(lang_dirent->d_name, ".")) && \ 3535 (strcmp(lang_dirent->d_name, ".."))) 3536 3537 #define for_each_script(lang_path, lang_dir, script_dirent) \ 3538 while ((script_dirent = readdir(lang_dir)) != NULL) \ 3539 if (script_dirent->d_type != DT_DIR && \ 3540 (script_dirent->d_type != DT_UNKNOWN || \ 3541 !is_directory(lang_path, script_dirent))) 3542 3543 3544 #define RECORD_SUFFIX "-record" 3545 #define REPORT_SUFFIX "-report" 3546 3547 struct script_desc { 3548 struct list_head node; 3549 char *name; 3550 char *half_liner; 3551 char *args; 3552 }; 3553 3554 static LIST_HEAD(script_descs); 3555 3556 static struct script_desc *script_desc__new(const char *name) 3557 { 3558 struct script_desc *s = zalloc(sizeof(*s)); 3559 3560 if (s != NULL && name) 3561 s->name = strdup(name); 3562 3563 return s; 3564 } 3565 3566 static void script_desc__delete(struct script_desc *s) 3567 { 3568 zfree(&s->name); 3569 zfree(&s->half_liner); 3570 zfree(&s->args); 3571 free(s); 3572 } 3573 3574 static void script_desc__add(struct script_desc *s) 3575 { 3576 list_add_tail(&s->node, &script_descs); 3577 } 3578 3579 static struct script_desc *script_desc__find(const char *name) 3580 { 3581 struct script_desc *s; 3582 3583 list_for_each_entry(s, &script_descs, node) 3584 if (strcasecmp(s->name, name) == 0) 3585 return s; 3586 return NULL; 3587 } 3588 3589 static struct script_desc *script_desc__findnew(const char *name) 3590 { 3591 struct script_desc *s = script_desc__find(name); 3592 3593 if (s) 3594 return s; 3595 3596 s = script_desc__new(name); 3597 if (!s) 3598 return NULL; 3599 3600 script_desc__add(s); 3601 3602 return s; 3603 } 3604 3605 static const char *ends_with(const char *str, const char *suffix) 3606 { 3607 size_t suffix_len = strlen(suffix); 3608 const char *p = str; 3609 3610 if (strlen(str) > suffix_len) { 3611 p = str + strlen(str) - suffix_len; 3612 if (!strncmp(p, suffix, suffix_len)) 3613 return p; 3614 } 3615 3616 return NULL; 3617 } 3618 3619 static int read_script_info(struct script_desc *desc, const char *filename) 3620 { 3621 char line[BUFSIZ], *p; 3622 FILE *fp; 3623 3624 fp = fopen(filename, "r"); 3625 if (!fp) 3626 return -1; 3627 3628 while (fgets(line, sizeof(line), fp)) { 3629 p = skip_spaces(line); 3630 if (strlen(p) == 0) 3631 continue; 3632 if (*p != '#') 3633 continue; 3634 p++; 3635 if (strlen(p) && *p == '!') 3636 continue; 3637 3638 p = skip_spaces(p); 3639 if (strlen(p) && p[strlen(p) - 1] == '\n') 3640 p[strlen(p) - 1] = '\0'; 3641 3642 if (!strncmp(p, "description:", strlen("description:"))) { 3643 p += strlen("description:"); 3644 desc->half_liner = strdup(skip_spaces(p)); 3645 continue; 3646 } 3647 3648 if (!strncmp(p, "args:", strlen("args:"))) { 3649 p += strlen("args:"); 3650 desc->args = strdup(skip_spaces(p)); 3651 continue; 3652 } 3653 } 3654 3655 fclose(fp); 3656 3657 return 0; 3658 } 3659 3660 static char *get_script_root(struct dirent *script_dirent, const char *suffix) 3661 { 3662 char *script_root, *str; 3663 3664 script_root = strdup(script_dirent->d_name); 3665 if (!script_root) 3666 return NULL; 3667 3668 str = (char *)ends_with(script_root, suffix); 3669 if (!str) { 3670 free(script_root); 3671 return NULL; 3672 } 3673 3674 *str = '\0'; 3675 return script_root; 3676 } 3677 3678 static int list_available_scripts(const struct option *opt __maybe_unused, 3679 const char *s __maybe_unused, 3680 int unset __maybe_unused) 3681 { 3682 struct dirent *script_dirent, *lang_dirent; 3683 char *buf, *scripts_path, *script_path, *lang_path, *first_half; 3684 DIR *scripts_dir, *lang_dir; 3685 struct script_desc *desc; 3686 char *script_root; 3687 3688 buf = malloc(3 * MAXPATHLEN + BUFSIZ); 3689 if (!buf) { 3690 pr_err("malloc failed\n"); 3691 exit(-1); 3692 } 3693 scripts_path = buf; 3694 script_path = buf + MAXPATHLEN; 3695 lang_path = buf + 2 * MAXPATHLEN; 3696 first_half = buf + 3 * MAXPATHLEN; 3697 3698 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); 3699 3700 scripts_dir = opendir(scripts_path); 3701 if (!scripts_dir) { 3702 fprintf(stdout, 3703 "open(%s) failed.\n" 3704 "Check \"PERF_EXEC_PATH\" env to set scripts dir.\n", 3705 scripts_path); 3706 free(buf); 3707 exit(-1); 3708 } 3709 3710 for_each_lang(scripts_path, scripts_dir, lang_dirent) { 3711 scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 3712 lang_dirent->d_name); 3713 lang_dir = opendir(lang_path); 3714 if (!lang_dir) 3715 continue; 3716 3717 for_each_script(lang_path, lang_dir, script_dirent) { 3718 script_root = get_script_root(script_dirent, REPORT_SUFFIX); 3719 if (script_root) { 3720 desc = script_desc__findnew(script_root); 3721 scnprintf(script_path, MAXPATHLEN, "%s/%s", 3722 lang_path, script_dirent->d_name); 3723 read_script_info(desc, script_path); 3724 free(script_root); 3725 } 3726 } 3727 } 3728 3729 fprintf(stdout, "List of available trace scripts:\n"); 3730 list_for_each_entry(desc, &script_descs, node) { 3731 sprintf(first_half, "%s %s", desc->name, 3732 desc->args ? desc->args : ""); 3733 fprintf(stdout, " %-36s %s\n", first_half, 3734 desc->half_liner ? desc->half_liner : ""); 3735 } 3736 3737 free(buf); 3738 exit(0); 3739 } 3740 3741 static int add_dlarg(const struct option *opt __maybe_unused, 3742 const char *s, int unset __maybe_unused) 3743 { 3744 char *arg = strdup(s); 3745 void *a; 3746 3747 if (!arg) 3748 return -1; 3749 3750 a = realloc(dlargv, sizeof(dlargv[0]) * (dlargc + 1)); 3751 if (!a) { 3752 free(arg); 3753 return -1; 3754 } 3755 3756 dlargv = a; 3757 dlargv[dlargc++] = arg; 3758 3759 return 0; 3760 } 3761 3762 static void free_dlarg(void) 3763 { 3764 while (dlargc--) 3765 free(dlargv[dlargc]); 3766 free(dlargv); 3767 } 3768 3769 static char *get_script_path(const char *script_root, const char *suffix) 3770 { 3771 struct dirent *script_dirent, *lang_dirent; 3772 char scripts_path[MAXPATHLEN]; 3773 char script_path[MAXPATHLEN]; 3774 DIR *scripts_dir, *lang_dir; 3775 char lang_path[MAXPATHLEN]; 3776 char *__script_root; 3777 3778 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); 3779 3780 scripts_dir = opendir(scripts_path); 3781 if (!scripts_dir) 3782 return NULL; 3783 3784 for_each_lang(scripts_path, scripts_dir, lang_dirent) { 3785 scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 3786 lang_dirent->d_name); 3787 lang_dir = opendir(lang_path); 3788 if (!lang_dir) 3789 continue; 3790 3791 for_each_script(lang_path, lang_dir, script_dirent) { 3792 __script_root = get_script_root(script_dirent, suffix); 3793 if (__script_root && !strcmp(script_root, __script_root)) { 3794 free(__script_root); 3795 closedir(scripts_dir); 3796 scnprintf(script_path, MAXPATHLEN, "%s/%s", 3797 lang_path, script_dirent->d_name); 3798 closedir(lang_dir); 3799 return strdup(script_path); 3800 } 3801 free(__script_root); 3802 } 3803 closedir(lang_dir); 3804 } 3805 closedir(scripts_dir); 3806 3807 return NULL; 3808 } 3809 3810 static bool is_top_script(const char *script_path) 3811 { 3812 return ends_with(script_path, "top") != NULL; 3813 } 3814 3815 static int has_required_arg(char *script_path) 3816 { 3817 struct script_desc *desc; 3818 int n_args = 0; 3819 char *p; 3820 3821 desc = script_desc__new(NULL); 3822 3823 if (read_script_info(desc, script_path)) 3824 goto out; 3825 3826 if (!desc->args) 3827 goto out; 3828 3829 for (p = desc->args; *p; p++) 3830 if (*p == '<') 3831 n_args++; 3832 out: 3833 script_desc__delete(desc); 3834 3835 return n_args; 3836 } 3837 3838 static int have_cmd(int argc, const char **argv) 3839 { 3840 char **__argv = calloc(argc, sizeof(const char *)); 3841 3842 if (!__argv) { 3843 pr_err("malloc failed\n"); 3844 return -1; 3845 } 3846 3847 memcpy(__argv, argv, sizeof(const char *) * argc); 3848 argc = parse_options(argc, (const char **)__argv, record_options, 3849 NULL, PARSE_OPT_STOP_AT_NON_OPTION); 3850 free(__argv); 3851 3852 system_wide = (argc == 0); 3853 3854 return 0; 3855 } 3856 3857 static void script__setup_sample_type(struct perf_script *script) 3858 { 3859 struct perf_session *session = script->session; 3860 u64 sample_type = evlist__combined_sample_type(session->evlist); 3861 3862 callchain_param_setup(sample_type, perf_session__e_machine(session, /*e_flags=*/NULL)); 3863 3864 if (script->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) { 3865 pr_warning("Can't find LBR callchain. Switch off --stitch-lbr.\n" 3866 "Please apply --call-graph lbr when recording.\n"); 3867 script->stitch_lbr = false; 3868 } 3869 } 3870 3871 static int process_stat_round_event(const struct perf_tool *tool __maybe_unused, 3872 struct perf_session *session, 3873 union perf_event *event) 3874 { 3875 struct perf_record_stat_round *round = &event->stat_round; 3876 struct evsel *counter; 3877 3878 evlist__for_each_entry(session->evlist, counter) { 3879 perf_stat_process_counter(&stat_config, counter); 3880 process_stat(counter, round->time); 3881 } 3882 3883 process_stat_interval(round->time); 3884 return 0; 3885 } 3886 3887 static int process_stat_config_event(const struct perf_tool *tool __maybe_unused, 3888 struct perf_session *session __maybe_unused, 3889 union perf_event *event) 3890 { 3891 perf_event__read_stat_config(&stat_config, &event->stat_config); 3892 3893 /* 3894 * Aggregation modes are not used since post-processing scripts are 3895 * supposed to take care of such requirements 3896 */ 3897 stat_config.aggr_mode = AGGR_NONE; 3898 3899 return 0; 3900 } 3901 3902 static int set_maps(struct perf_script *script) 3903 { 3904 struct evlist *evlist = script->session->evlist; 3905 3906 if (!script->cpus || !script->threads) 3907 return 0; 3908 3909 if (WARN_ONCE(script->allocated, "stats double allocation\n")) 3910 return -EINVAL; 3911 3912 perf_evlist__set_maps(&evlist->core, script->cpus, script->threads); 3913 3914 if (evlist__alloc_stats(&stat_config, evlist, /*alloc_raw=*/true)) 3915 return -ENOMEM; 3916 3917 script->allocated = true; 3918 return 0; 3919 } 3920 3921 static 3922 int process_thread_map_event(const struct perf_tool *tool, 3923 struct perf_session *session __maybe_unused, 3924 union perf_event *event) 3925 { 3926 struct perf_script *script = container_of(tool, struct perf_script, tool); 3927 3928 if (dump_trace) 3929 perf_event__fprintf_thread_map(event, stdout); 3930 3931 if (script->threads) { 3932 pr_warning("Extra thread map event, ignoring.\n"); 3933 return 0; 3934 } 3935 3936 script->threads = thread_map__new_event(&event->thread_map); 3937 if (!script->threads) 3938 return -ENOMEM; 3939 3940 return set_maps(script); 3941 } 3942 3943 static 3944 int process_cpu_map_event(const struct perf_tool *tool, 3945 struct perf_session *session __maybe_unused, 3946 union perf_event *event) 3947 { 3948 struct perf_script *script = container_of(tool, struct perf_script, tool); 3949 3950 if (dump_trace) 3951 perf_event__fprintf_cpu_map(event, stdout); 3952 3953 if (script->cpus) { 3954 pr_warning("Extra cpu map event, ignoring.\n"); 3955 return 0; 3956 } 3957 3958 script->cpus = cpu_map__new_data(&event->cpu_map.data); 3959 if (!script->cpus) 3960 return -ENOMEM; 3961 3962 return set_maps(script); 3963 } 3964 3965 static int perf_script__process_auxtrace_info(const struct perf_tool *tool, 3966 struct perf_session *session, 3967 union perf_event *event) 3968 { 3969 int ret = perf_event__process_auxtrace_info(tool, session, event); 3970 3971 if (ret == 0) { 3972 struct perf_script *script = container_of(tool, struct perf_script, tool); 3973 3974 ret = perf_script__setup_per_event_dump(script); 3975 } 3976 3977 return ret; 3978 } 3979 3980 static int parse_insn_trace(const struct option *opt __maybe_unused, 3981 const char *str, int unset __maybe_unused) 3982 { 3983 const char *fields = "+insn,-event,-period"; 3984 int ret; 3985 3986 if (str) { 3987 if (strcmp(str, "disasm") == 0) 3988 fields = "+disasm,-event,-period"; 3989 else if (strlen(str) != 0 && strcmp(str, "raw") != 0) { 3990 fprintf(stderr, "Only accept raw|disasm\n"); 3991 return -EINVAL; 3992 } 3993 } 3994 3995 ret = parse_output_fields(NULL, fields, 0); 3996 if (ret < 0) 3997 return ret; 3998 3999 itrace_parse_synth_opts(opt, "i0nse", 0); 4000 symbol_conf.nanosecs = true; 4001 return 0; 4002 } 4003 4004 static int parse_xed(const struct option *opt __maybe_unused, 4005 const char *str __maybe_unused, 4006 int unset __maybe_unused) 4007 { 4008 if (isatty(1)) 4009 force_pager("xed -F insn: -A -64 | less"); 4010 else 4011 force_pager("xed -F insn: -A -64"); 4012 return 0; 4013 } 4014 4015 static int parse_call_trace(const struct option *opt __maybe_unused, 4016 const char *str __maybe_unused, 4017 int unset __maybe_unused) 4018 { 4019 parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent", 0); 4020 itrace_parse_synth_opts(opt, "cewp", 0); 4021 symbol_conf.nanosecs = true; 4022 symbol_conf.pad_output_len_dso = 50; 4023 return 0; 4024 } 4025 4026 static int parse_callret_trace(const struct option *opt __maybe_unused, 4027 const char *str __maybe_unused, 4028 int unset __maybe_unused) 4029 { 4030 parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent,+flags", 0); 4031 itrace_parse_synth_opts(opt, "crewp", 0); 4032 symbol_conf.nanosecs = true; 4033 return 0; 4034 } 4035 4036 int cmd_script(int argc, const char **argv) 4037 { 4038 bool show_full_info = false; 4039 bool header = false; 4040 bool header_only = false; 4041 bool script_started = false; 4042 bool unsorted_dump = false; 4043 bool merge_deferred_callchains = true; 4044 char *rec_script_path = NULL; 4045 char *rep_script_path = NULL; 4046 struct perf_session *session; 4047 struct itrace_synth_opts itrace_synth_opts = { 4048 .set = false, 4049 .default_no_sample = true, 4050 }; 4051 char *script_path = NULL; 4052 const char *dlfilter_file = NULL; 4053 const char **__argv; 4054 int i, j, err = 0; 4055 struct perf_script script = {}; 4056 struct perf_data data = { 4057 .mode = PERF_DATA_MODE_READ, 4058 }; 4059 const struct option options[] = { 4060 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 4061 "dump raw trace in ASCII"), 4062 OPT_BOOLEAN(0, "dump-unsorted-raw-trace", &unsorted_dump, 4063 "dump unsorted raw trace in ASCII"), 4064 OPT_INCR('v', "verbose", &verbose, 4065 "be more verbose (show symbol address, etc)"), 4066 OPT_BOOLEAN('L', "Latency", &latency_format, 4067 "show latency attributes (irqs/preemption disabled, etc)"), 4068 OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts", 4069 list_available_scripts), 4070 OPT_CALLBACK_NOOPT(0, "list-dlfilters", NULL, NULL, "list available dlfilters", 4071 list_available_dlfilters), 4072 OPT_CALLBACK('s', "script", NULL, "name", 4073 "script file name (lang:script name, script name, or *)", 4074 parse_scriptname), 4075 OPT_STRING('g', "gen-script", &generate_script_lang, "lang", 4076 "generate perf-script.xx script in specified language"), 4077 OPT_STRING(0, "dlfilter", &dlfilter_file, "file", "filter .so file name"), 4078 OPT_CALLBACK(0, "dlarg", NULL, "argument", "filter argument", 4079 add_dlarg), 4080 OPT_STRING('i', "input", &input_name, "file", "input file name"), 4081 OPT_BOOLEAN('d', "debug-mode", &debug_mode, 4082 "do various checks like samples ordering and lost events"), 4083 OPT_BOOLEAN(0, "header", &header, "Show data header."), 4084 OPT_BOOLEAN(0, "header-only", &header_only, "Show only data header."), 4085 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 4086 "file", "vmlinux pathname"), 4087 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, 4088 "file", "kallsyms pathname"), 4089 OPT_BOOLEAN('G', "hide-call-graph", &no_callchain, 4090 "When printing symbols do not display call chain"), 4091 OPT_CALLBACK(0, "symfs", NULL, "directory[,layout]", SYMFS_HELP, 4092 symbol__config_symfs), 4093 OPT_CALLBACK('F', "fields", NULL, "str", 4094 "comma separated output fields prepend with 'type:'. " 4095 "+field to add and -field to remove." 4096 "Valid types: hw,sw,trace,raw,synth. " 4097 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,dsoff," 4098 "addr,symoff,srcline,period,iregs,uregs,brstack," 4099 "brstacksym,flags,data_src,weight,bpf-output,brstackinsn," 4100 "brstackinsnlen,brstackdisasm,brstackoff,callindent,insn,disasm,insnlen,synth," 4101 "phys_addr,metric,misc,srccode,ipc,tod,data_page_size," 4102 "code_page_size,ins_lat,machine_pid,vcpu,cgroup,retire_lat," 4103 "brcntr", 4104 parse_output_fields), 4105 OPT_BOOLEAN('a', "all-cpus", &system_wide, 4106 "system-wide collection from all CPUs"), 4107 OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", 4108 "only consider symbols in these DSOs"), 4109 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", 4110 "only consider these symbols"), 4111 OPT_INTEGER(0, "addr-range", &symbol_conf.addr_range, 4112 "Use with -S to list traced records within address range"), 4113 OPT_CALLBACK_OPTARG(0, "insn-trace", &itrace_synth_opts, NULL, "raw|disasm", 4114 "Decode instructions from itrace", parse_insn_trace), 4115 OPT_CALLBACK_OPTARG(0, "xed", NULL, NULL, NULL, 4116 "Run xed disassembler on output", parse_xed), 4117 OPT_CALLBACK_OPTARG(0, "call-trace", &itrace_synth_opts, NULL, NULL, 4118 "Decode calls from itrace", parse_call_trace), 4119 OPT_CALLBACK_OPTARG(0, "call-ret-trace", &itrace_synth_opts, NULL, NULL, 4120 "Decode calls and returns from itrace", parse_callret_trace), 4121 OPT_STRING(0, "graph-function", &symbol_conf.graph_function, "symbol[,symbol...]", 4122 "Only print symbols and callees with --call-trace/--call-ret-trace"), 4123 OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]", 4124 "Stop display of callgraph at these symbols"), 4125 OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 4126 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", 4127 "only display events for these comms"), 4128 OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]", 4129 "only consider symbols in these pids"), 4130 OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]", 4131 "only consider symbols in these tids"), 4132 OPT_UINTEGER(0, "max-stack", &scripting_max_stack, 4133 "Set the maximum stack depth when parsing the callchain, " 4134 "anything beyond the specified depth will be ignored. " 4135 "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)), 4136 OPT_BOOLEAN(0, "reltime", &reltime, "Show time stamps relative to start"), 4137 OPT_BOOLEAN(0, "deltatime", &deltatime, "Show time stamps relative to previous event"), 4138 OPT_BOOLEAN('I', "show-info", &show_full_info, 4139 "display extended information from perf.data file"), 4140 OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path, 4141 "Show the path of [kernel.kallsyms]"), 4142 OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events, 4143 "Show the fork/comm/exit events"), 4144 OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events, 4145 "Show the mmap events"), 4146 OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events, 4147 "Show context switch events (if recorded)"), 4148 OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events, 4149 "Show namespace events (if recorded)"), 4150 OPT_BOOLEAN('\0', "show-cgroup-events", &script.show_cgroup_events, 4151 "Show cgroup events (if recorded)"), 4152 OPT_BOOLEAN('\0', "show-lost-events", &script.show_lost_events, 4153 "Show lost events (if recorded)"), 4154 OPT_BOOLEAN('\0', "show-round-events", &script.show_round_events, 4155 "Show round events (if recorded)"), 4156 OPT_BOOLEAN('\0', "show-bpf-events", &script.show_bpf_events, 4157 "Show bpf related events (if recorded)"), 4158 OPT_BOOLEAN('\0', "show-text-poke-events", &script.show_text_poke_events, 4159 "Show text poke related events (if recorded)"), 4160 OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump, 4161 "Dump trace output to files named by the monitored events"), 4162 OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), 4163 OPT_INTEGER(0, "max-blocks", &max_blocks, 4164 "Maximum number of code blocks to dump with brstackinsn"), 4165 OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs, 4166 "Use 9 decimal places when displaying time"), 4167 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", 4168 "Instruction Tracing options\n" ITRACE_HELP, 4169 itrace_parse_synth_opts), 4170 OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename, 4171 "Show full source file name path for source lines"), 4172 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, 4173 "Enable symbol demangling"), 4174 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, 4175 "Enable kernel symbol demangling"), 4176 OPT_CALLBACK(0, "unwind-style", NULL, "unwind style", 4177 "unwind styles (libdw,libunwind)", 4178 unwind__option), 4179 OPT_STRING(0, "addr2line", &symbol_conf.addr2line_path, "path", 4180 "addr2line binary to use for line numbers"), 4181 OPT_STRING(0, "time", &script.time_str, "str", 4182 "Time span of interest (start,stop)"), 4183 OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name, 4184 "Show inline function"), 4185 OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory", 4186 "guest mount directory under which every guest os" 4187 " instance has a subdir"), 4188 OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name, 4189 "file", "file saving guest os vmlinux"), 4190 OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms, 4191 "file", "file saving guest os /proc/kallsyms"), 4192 OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules, 4193 "file", "file saving guest os /proc/modules"), 4194 OPT_BOOLEAN(0, "guest-code", &symbol_conf.guest_code, 4195 "Guest code can be found in hypervisor process"), 4196 OPT_BOOLEAN('\0', "stitch-lbr", &script.stitch_lbr, 4197 "Enable LBR callgraph stitching approach"), 4198 OPT_BOOLEAN('\0', "merge-callchains", &merge_deferred_callchains, 4199 "Enable merge deferred user callchains"), 4200 OPTS_EVSWITCH(&script.evswitch), 4201 OPT_END() 4202 }; 4203 const char * const script_subcommands[] = { "record", "report", NULL }; 4204 const char *script_usage[] = { 4205 "perf script [<options>]", 4206 "perf script [<options>] record <script> [<record-options>] <command>", 4207 "perf script [<options>] report <script> [script-args]", 4208 "perf script [<options>] <script> [<record-options>] <command>", 4209 "perf script [<options>] <top-script> [script-args]", 4210 NULL 4211 }; 4212 struct perf_env *env; 4213 4214 perf_set_singlethreaded(); 4215 4216 setup_scripting(); 4217 4218 argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage, 4219 PARSE_OPT_STOP_AT_NON_OPTION); 4220 4221 if (symbol_conf.guestmount || 4222 symbol_conf.default_guest_vmlinux_name || 4223 symbol_conf.default_guest_kallsyms || 4224 symbol_conf.default_guest_modules || 4225 symbol_conf.guest_code) { 4226 /* 4227 * Enable guest sample processing. 4228 */ 4229 perf_guest = true; 4230 } 4231 4232 data.path = input_name; 4233 data.force = symbol_conf.force; 4234 4235 if (unsorted_dump) 4236 dump_trace = true; 4237 4238 if (symbol__validate_sym_arguments()) 4239 return -1; 4240 4241 if (argc > 1 && strlen(argv[0]) > 2 && strstarts("record", argv[0])) { 4242 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); 4243 if (!rec_script_path) 4244 return cmd_record(argc, argv); 4245 } 4246 4247 if (argc > 1 && strlen(argv[0]) > 2 && strstarts("report", argv[0])) { 4248 rep_script_path = get_script_path(argv[1], REPORT_SUFFIX); 4249 if (!rep_script_path) { 4250 fprintf(stderr, 4251 "Please specify a valid report script" 4252 "(see 'perf script -l' for listing)\n"); 4253 return -1; 4254 } 4255 } 4256 4257 if (reltime && deltatime) { 4258 fprintf(stderr, 4259 "reltime and deltatime - the two don't get along well. " 4260 "Please limit to --reltime or --deltatime.\n"); 4261 return -1; 4262 } 4263 4264 if ((itrace_synth_opts.callchain || itrace_synth_opts.add_callchain) && 4265 itrace_synth_opts.callchain_sz > scripting_max_stack) 4266 scripting_max_stack = itrace_synth_opts.callchain_sz; 4267 4268 /* make sure PERF_EXEC_PATH is set for scripts */ 4269 set_argv_exec_path(get_argv_exec_path()); 4270 4271 if (argc && !script_name && !rec_script_path && !rep_script_path) { 4272 int live_pipe[2]; 4273 int rep_args; 4274 pid_t pid; 4275 4276 rec_script_path = get_script_path(argv[0], RECORD_SUFFIX); 4277 rep_script_path = get_script_path(argv[0], REPORT_SUFFIX); 4278 4279 if (!rec_script_path && !rep_script_path) { 4280 script_name = find_script(argv[0]); 4281 if (script_name) { 4282 argc -= 1; 4283 argv += 1; 4284 goto script_found; 4285 } 4286 usage_with_options_msg(script_usage, options, 4287 "Couldn't find script `%s'\n\n See perf" 4288 " script -l for available scripts.\n", argv[0]); 4289 } 4290 4291 if (is_top_script(argv[0])) { 4292 rep_args = argc - 1; 4293 } else { 4294 int rec_args; 4295 4296 rep_args = has_required_arg(rep_script_path); 4297 rec_args = (argc - 1) - rep_args; 4298 if (rec_args < 0) { 4299 usage_with_options_msg(script_usage, options, 4300 "`%s' script requires options." 4301 "\n\n See perf script -l for available " 4302 "scripts and options.\n", argv[0]); 4303 } 4304 } 4305 4306 if (pipe(live_pipe) < 0) { 4307 perror("failed to create pipe"); 4308 return -1; 4309 } 4310 4311 pid = fork(); 4312 if (pid < 0) { 4313 perror("failed to fork"); 4314 return -1; 4315 } 4316 4317 if (!pid) { 4318 j = 0; 4319 4320 dup2(live_pipe[1], 1); 4321 close(live_pipe[0]); 4322 4323 if (is_top_script(argv[0])) { 4324 system_wide = true; 4325 } else if (!system_wide) { 4326 if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) { 4327 err = -1; 4328 goto out; 4329 } 4330 } 4331 4332 __argv = calloc(argc + 6, sizeof(const char *)); 4333 if (!__argv) { 4334 pr_err("malloc failed\n"); 4335 err = -ENOMEM; 4336 goto out; 4337 } 4338 4339 __argv[j++] = "/bin/sh"; 4340 __argv[j++] = rec_script_path; 4341 if (system_wide) 4342 __argv[j++] = "-a"; 4343 __argv[j++] = "-q"; 4344 __argv[j++] = "-o"; 4345 __argv[j++] = "-"; 4346 for (i = rep_args + 1; i < argc; i++) 4347 __argv[j++] = argv[i]; 4348 __argv[j++] = NULL; 4349 4350 execvp("/bin/sh", (char **)__argv); 4351 free(__argv); 4352 exit(-1); 4353 } 4354 4355 dup2(live_pipe[0], 0); 4356 close(live_pipe[1]); 4357 4358 __argv = calloc(argc + 4, sizeof(const char *)); 4359 if (!__argv) { 4360 pr_err("malloc failed\n"); 4361 err = -ENOMEM; 4362 goto out; 4363 } 4364 4365 j = 0; 4366 __argv[j++] = "/bin/sh"; 4367 __argv[j++] = rep_script_path; 4368 for (i = 1; i < rep_args + 1; i++) 4369 __argv[j++] = argv[i]; 4370 __argv[j++] = "-i"; 4371 __argv[j++] = "-"; 4372 __argv[j++] = NULL; 4373 4374 execvp("/bin/sh", (char **)__argv); 4375 free(__argv); 4376 exit(-1); 4377 } 4378 script_found: 4379 if (rec_script_path) 4380 script_path = rec_script_path; 4381 if (rep_script_path) 4382 script_path = rep_script_path; 4383 4384 if (script_path) { 4385 j = 0; 4386 4387 if (!rec_script_path) 4388 system_wide = false; 4389 else if (!system_wide) { 4390 if (have_cmd(argc - 1, &argv[1]) != 0) { 4391 err = -1; 4392 goto out; 4393 } 4394 } 4395 4396 __argv = calloc(argc + 2, sizeof(const char *)); 4397 if (!__argv) { 4398 pr_err("malloc failed\n"); 4399 err = -ENOMEM; 4400 goto out; 4401 } 4402 4403 __argv[j++] = "/bin/sh"; 4404 __argv[j++] = script_path; 4405 if (system_wide) 4406 __argv[j++] = "-a"; 4407 for (i = 2; i < argc; i++) 4408 __argv[j++] = argv[i]; 4409 __argv[j++] = NULL; 4410 4411 execvp("/bin/sh", (char **)__argv); 4412 free(__argv); 4413 exit(-1); 4414 } 4415 4416 if (dlfilter_file) { 4417 dlfilter = dlfilter__new(dlfilter_file, dlargc, dlargv); 4418 if (!dlfilter) 4419 return -1; 4420 } 4421 4422 if (!script_name) { 4423 setup_pager(); 4424 use_browser = 0; 4425 } 4426 4427 perf_tool__init(&script.tool, !unsorted_dump); 4428 script.tool.sample = process_sample_event; 4429 script.tool.callchain_deferred = process_deferred_sample_event; 4430 script.tool.mmap = perf_event__process_mmap; 4431 script.tool.mmap2 = perf_event__process_mmap2; 4432 script.tool.comm = perf_event__process_comm; 4433 script.tool.namespaces = perf_event__process_namespaces; 4434 script.tool.cgroup = perf_event__process_cgroup; 4435 script.tool.exit = perf_event__process_exit; 4436 script.tool.fork = perf_event__process_fork; 4437 script.tool.attr = process_attr; 4438 script.tool.event_update = perf_event__process_event_update; 4439 #ifdef HAVE_LIBTRACEEVENT 4440 script.tool.tracing_data = perf_event__process_tracing_data; 4441 #endif 4442 script.tool.feature = perf_event__process_feature; 4443 script.tool.build_id = perf_event__process_build_id; 4444 script.tool.id_index = perf_event__process_id_index; 4445 script.tool.auxtrace_info = perf_script__process_auxtrace_info; 4446 script.tool.auxtrace = perf_event__process_auxtrace; 4447 script.tool.auxtrace_error = perf_event__process_auxtrace_error; 4448 script.tool.stat = perf_event__process_stat_event; 4449 script.tool.stat_round = process_stat_round_event; 4450 script.tool.stat_config = process_stat_config_event; 4451 script.tool.thread_map = process_thread_map_event; 4452 script.tool.cpu_map = process_cpu_map_event; 4453 script.tool.throttle = process_throttle_event; 4454 script.tool.unthrottle = process_throttle_event; 4455 script.tool.ordering_requires_timestamps = true; 4456 script.tool.merge_deferred_callchains = merge_deferred_callchains; 4457 session = perf_session__new(&data, &script.tool); 4458 if (IS_ERR(session)) 4459 return PTR_ERR(session); 4460 4461 env = perf_session__env(session); 4462 if (header || header_only) { 4463 script.tool.show_feat_hdr = SHOW_FEAT_HEADER; 4464 perf_session__fprintf_info(session, stdout, show_full_info); 4465 if (header_only) 4466 goto out_delete; 4467 } 4468 if (show_full_info) 4469 script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO; 4470 4471 if (symbol__init(env) < 0) 4472 goto out_delete; 4473 4474 script.session = session; 4475 script__setup_sample_type(&script); 4476 4477 if ((output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT) || 4478 symbol_conf.graph_function) 4479 itrace_synth_opts.thread_stack = true; 4480 4481 session->itrace_synth_opts = &itrace_synth_opts; 4482 4483 if (cpu_list) { 4484 err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap); 4485 if (err < 0) 4486 goto out_delete; 4487 itrace_synth_opts.cpu_bitmap = cpu_bitmap; 4488 } 4489 4490 if (!no_callchain) 4491 symbol_conf.use_callchain = true; 4492 else 4493 symbol_conf.use_callchain = false; 4494 4495 #ifdef HAVE_LIBTRACEEVENT 4496 if (session->tevent.pevent && 4497 tep_set_function_resolver(session->tevent.pevent, 4498 machine__resolve_kernel_addr, 4499 &session->machines.host) < 0) { 4500 pr_err("%s: failed to set libtraceevent function resolver\n", __func__); 4501 err = -1; 4502 goto out_delete; 4503 } 4504 #endif 4505 if (generate_script_lang) { 4506 struct stat perf_stat; 4507 int input; 4508 char *filename = strdup("perf-script"); 4509 4510 if (output_set_by_user()) { 4511 fprintf(stderr, 4512 "custom fields not supported for generated scripts"); 4513 err = -EINVAL; 4514 goto out_delete; 4515 } 4516 4517 input = open(data.path, O_RDONLY); /* input_name */ 4518 if (input < 0) { 4519 err = -errno; 4520 perror("failed to open file"); 4521 goto out_delete; 4522 } 4523 4524 err = fstat(input, &perf_stat); 4525 if (err < 0) { 4526 perror("failed to stat file"); 4527 goto out_delete; 4528 } 4529 4530 if (!perf_stat.st_size) { 4531 fprintf(stderr, "zero-sized file, nothing to do!\n"); 4532 goto out_delete; 4533 } 4534 4535 scripting_ops = script_spec__lookup(generate_script_lang); 4536 if (!scripting_ops && ends_with(generate_script_lang, ".py")) { 4537 scripting_ops = script_spec__lookup("python"); 4538 free(filename); 4539 filename = strdup(generate_script_lang); 4540 filename[strlen(filename) - 3] = '\0'; 4541 } else if (!scripting_ops && ends_with(generate_script_lang, ".pl")) { 4542 scripting_ops = script_spec__lookup("perl"); 4543 free(filename); 4544 filename = strdup(generate_script_lang); 4545 filename[strlen(filename) - 3] = '\0'; 4546 } 4547 if (!scripting_ops) { 4548 fprintf(stderr, "invalid language specifier '%s'\n", generate_script_lang); 4549 err = -ENOENT; 4550 goto out_delete; 4551 } 4552 if (!filename) { 4553 err = -ENOMEM; 4554 goto out_delete; 4555 } 4556 #ifdef HAVE_LIBTRACEEVENT 4557 err = scripting_ops->generate_script(session->tevent.pevent, filename); 4558 #else 4559 err = scripting_ops->generate_script(NULL, filename); 4560 #endif 4561 free(filename); 4562 goto out_delete; 4563 } 4564 4565 err = dlfilter__start(dlfilter, session); 4566 if (err) 4567 goto out_delete; 4568 4569 if (script_name) { 4570 err = scripting_ops->start_script(script_name, argc, argv, session); 4571 if (err) 4572 goto out_delete; 4573 pr_debug("perf script started with script %s\n\n", script_name); 4574 script_started = true; 4575 } 4576 4577 4578 err = perf_session__check_output_opt(session); 4579 if (err < 0) 4580 goto out_delete; 4581 4582 if (script.time_str) { 4583 err = perf_time__parse_for_ranges_reltime(script.time_str, session, 4584 &script.ptime_range, 4585 &script.range_size, 4586 &script.range_num, 4587 reltime); 4588 if (err < 0) 4589 goto out_delete; 4590 4591 itrace_synth_opts__set_time_range(&itrace_synth_opts, 4592 script.ptime_range, 4593 script.range_num); 4594 } 4595 4596 err = evswitch__init(&script.evswitch, session->evlist, stderr); 4597 if (err) 4598 goto out_delete; 4599 4600 if (zstd_init(&(session->zstd_data), 0) < 0) 4601 pr_warning("Decompression initialization failed. Reported data may be incomplete.\n"); 4602 4603 err = __cmd_script(&script); 4604 4605 flush_scripting(); 4606 4607 if (verbose > 2 || debug_kmaps) 4608 perf_session__dump_kmaps(session); 4609 4610 out_delete: 4611 if (script.ptime_range) { 4612 itrace_synth_opts__clear_time_range(&itrace_synth_opts); 4613 zfree(&script.ptime_range); 4614 } 4615 4616 zstd_fini(&(session->zstd_data)); 4617 evlist__free_stats(session->evlist); 4618 perf_session__delete(session); 4619 perf_script__exit(&script); 4620 4621 if (script_started) 4622 cleanup_scripting(); 4623 dlfilter__cleanup(dlfilter); 4624 free_dlarg(); 4625 out: 4626 return err; 4627 } 4628