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