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