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