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