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