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