4
#include "util/cache.h"
5
#include "util/debug.h"
6
#include "util/exec_cmd.h"
7
#include "util/header.h"
8
#include "util/parse-options.h"
9
#include "util/session.h"
10
#include "util/symbol.h"
11
#include "util/thread.h"
12
#include "util/trace-event.h"
13
#include "util/util.h"
14
#include "util/evlist.h"
15
#include "util/evsel.h"
16
#include <linux/bitmap.h>
18
static char const *script_name;
19
static char const *generate_script_lang;
20
static bool debug_mode;
21
static u64 last_timestamp;
22
static u64 nr_unordered;
23
extern const struct option record_options[];
24
static bool no_callchain;
25
static bool show_full_info;
26
static const char *cpu_list;
27
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
29
enum perf_output_field {
30
PERF_OUTPUT_COMM = 1U << 0,
31
PERF_OUTPUT_TID = 1U << 1,
32
PERF_OUTPUT_PID = 1U << 2,
33
PERF_OUTPUT_TIME = 1U << 3,
34
PERF_OUTPUT_CPU = 1U << 4,
35
PERF_OUTPUT_EVNAME = 1U << 5,
36
PERF_OUTPUT_TRACE = 1U << 6,
37
PERF_OUTPUT_IP = 1U << 7,
38
PERF_OUTPUT_SYM = 1U << 8,
39
PERF_OUTPUT_DSO = 1U << 9,
40
PERF_OUTPUT_ADDR = 1U << 10,
43
struct output_option {
45
enum perf_output_field field;
46
} all_output_options[] = {
47
{.str = "comm", .field = PERF_OUTPUT_COMM},
48
{.str = "tid", .field = PERF_OUTPUT_TID},
49
{.str = "pid", .field = PERF_OUTPUT_PID},
50
{.str = "time", .field = PERF_OUTPUT_TIME},
51
{.str = "cpu", .field = PERF_OUTPUT_CPU},
52
{.str = "event", .field = PERF_OUTPUT_EVNAME},
53
{.str = "trace", .field = PERF_OUTPUT_TRACE},
54
{.str = "ip", .field = PERF_OUTPUT_IP},
55
{.str = "sym", .field = PERF_OUTPUT_SYM},
56
{.str = "dso", .field = PERF_OUTPUT_DSO},
57
{.str = "addr", .field = PERF_OUTPUT_ADDR},
60
/* default set to maintain compatibility with current format */
66
} output[PERF_TYPE_MAX] = {
68
[PERF_TYPE_HARDWARE] = {
71
.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
72
PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
73
PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
74
PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
76
.invalid_fields = PERF_OUTPUT_TRACE,
79
[PERF_TYPE_SOFTWARE] = {
82
.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
83
PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
84
PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
85
PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
87
.invalid_fields = PERF_OUTPUT_TRACE,
90
[PERF_TYPE_TRACEPOINT] = {
93
.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
94
PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
95
PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE,
101
.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
102
PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
103
PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
104
PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
106
.invalid_fields = PERF_OUTPUT_TRACE,
110
static bool output_set_by_user(void)
113
for (j = 0; j < PERF_TYPE_MAX; ++j) {
114
if (output[j].user_set)
120
static const char *output_field2str(enum perf_output_field field)
122
int i, imax = ARRAY_SIZE(all_output_options);
123
const char *str = "";
125
for (i = 0; i < imax; ++i) {
126
if (all_output_options[i].field == field) {
127
str = all_output_options[i].str;
134
#define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x)
136
static int perf_event_attr__check_stype(struct perf_event_attr *attr,
137
u64 sample_type, const char *sample_msg,
138
enum perf_output_field field)
140
int type = attr->type;
143
if (attr->sample_type & sample_type)
146
if (output[type].user_set) {
147
evname = __event_name(attr->type, attr->config);
148
pr_err("Samples for '%s' event do not have %s attribute set. "
149
"Cannot print '%s' field.\n",
150
evname, sample_msg, output_field2str(field));
154
/* user did not ask for it explicitly so remove from the default list */
155
output[type].fields &= ~field;
156
evname = __event_name(attr->type, attr->config);
157
pr_debug("Samples for '%s' event do not have %s attribute set. "
158
"Skipping '%s' field.\n",
159
evname, sample_msg, output_field2str(field));
164
static int perf_evsel__check_attr(struct perf_evsel *evsel,
165
struct perf_session *session)
167
struct perf_event_attr *attr = &evsel->attr;
169
if (PRINT_FIELD(TRACE) &&
170
!perf_session__has_traces(session, "record -R"))
173
if (PRINT_FIELD(IP)) {
174
if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP",
179
!(attr->sample_type & PERF_SAMPLE_CALLCHAIN))
180
symbol_conf.use_callchain = false;
183
if (PRINT_FIELD(ADDR) &&
184
perf_event_attr__check_stype(attr, PERF_SAMPLE_ADDR, "ADDR",
188
if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
189
pr_err("Display of symbols requested but neither sample IP nor "
190
"sample address\nis selected. Hence, no addresses to convert "
194
if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
195
pr_err("Display of DSO requested but neither sample IP nor "
196
"sample address\nis selected. Hence, no addresses to convert "
201
if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
202
perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID",
203
PERF_OUTPUT_TID|PERF_OUTPUT_PID))
206
if (PRINT_FIELD(TIME) &&
207
perf_event_attr__check_stype(attr, PERF_SAMPLE_TIME, "TIME",
211
if (PRINT_FIELD(CPU) &&
212
perf_event_attr__check_stype(attr, PERF_SAMPLE_CPU, "CPU",
220
* verify all user requested events exist and the samples
221
* have the expected data
223
static int perf_session__check_output_opt(struct perf_session *session)
226
struct perf_evsel *evsel;
228
for (j = 0; j < PERF_TYPE_MAX; ++j) {
229
evsel = perf_session__find_first_evtype(session, j);
232
* even if fields is set to 0 (ie., show nothing) event must
233
* exist if user explicitly includes it on the command line
235
if (!evsel && output[j].user_set && !output[j].wildcard_set) {
236
pr_err("%s events do not exist. "
237
"Remove corresponding -f option to proceed.\n",
242
if (evsel && output[j].fields &&
243
perf_evsel__check_attr(evsel, session))
250
static void print_sample_start(struct perf_sample *sample,
251
struct thread *thread,
252
struct perf_event_attr *attr)
256
const char *evname = NULL;
259
unsigned long long nsecs;
261
if (PRINT_FIELD(COMM)) {
263
printf("%8.8s ", thread->comm);
264
else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
265
printf("%s ", thread->comm);
267
printf("%16s ", thread->comm);
270
if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
271
printf("%5d/%-5d ", sample->pid, sample->tid);
272
else if (PRINT_FIELD(PID))
273
printf("%5d ", sample->pid);
274
else if (PRINT_FIELD(TID))
275
printf("%5d ", sample->tid);
277
if (PRINT_FIELD(CPU)) {
279
printf("%3d ", sample->cpu);
281
printf("[%03d] ", sample->cpu);
284
if (PRINT_FIELD(TIME)) {
285
nsecs = sample->time;
286
secs = nsecs / NSECS_PER_SEC;
287
nsecs -= secs * NSECS_PER_SEC;
288
usecs = nsecs / NSECS_PER_USEC;
289
printf("%5lu.%06lu: ", secs, usecs);
292
if (PRINT_FIELD(EVNAME)) {
293
if (attr->type == PERF_TYPE_TRACEPOINT) {
294
type = trace_parse_common_type(sample->raw_data);
295
event = trace_find_event(type);
297
evname = event->name;
299
evname = __event_name(attr->type, attr->config);
301
printf("%s: ", evname ? evname : "(unknown)");
305
static bool sample_addr_correlates_sym(struct perf_event_attr *attr)
307
if ((attr->type == PERF_TYPE_SOFTWARE) &&
308
((attr->config == PERF_COUNT_SW_PAGE_FAULTS) ||
309
(attr->config == PERF_COUNT_SW_PAGE_FAULTS_MIN) ||
310
(attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)))
316
static void print_sample_addr(union perf_event *event,
317
struct perf_sample *sample,
318
struct perf_session *session,
319
struct thread *thread,
320
struct perf_event_attr *attr)
322
struct addr_location al;
323
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
324
const char *symname, *dsoname;
326
printf("%16" PRIx64, sample->addr);
328
if (!sample_addr_correlates_sym(attr))
331
thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
332
event->ip.pid, sample->addr, &al);
334
thread__find_addr_map(thread, session, cpumode, MAP__VARIABLE,
335
event->ip.pid, sample->addr, &al);
337
al.cpu = sample->cpu;
341
al.sym = map__find_symbol(al.map, al.addr, NULL);
343
if (PRINT_FIELD(SYM)) {
344
if (al.sym && al.sym->name)
345
symname = al.sym->name;
349
printf(" %16s", symname);
352
if (PRINT_FIELD(DSO)) {
353
if (al.map && al.map->dso && al.map->dso->name)
354
dsoname = al.map->dso->name;
358
printf(" (%s)", dsoname);
362
static void process_event(union perf_event *event __unused,
363
struct perf_sample *sample,
364
struct perf_evsel *evsel,
365
struct perf_session *session,
366
struct thread *thread)
368
struct perf_event_attr *attr = &evsel->attr;
370
if (output[attr->type].fields == 0)
373
print_sample_start(sample, thread, attr);
375
if (PRINT_FIELD(TRACE))
376
print_trace_event(sample->cpu, sample->raw_data,
379
if (PRINT_FIELD(ADDR))
380
print_sample_addr(event, sample, session, thread, attr);
382
if (PRINT_FIELD(IP)) {
383
if (!symbol_conf.use_callchain)
387
perf_session__print_ip(event, sample, session,
388
PRINT_FIELD(SYM), PRINT_FIELD(DSO));
394
static int default_start_script(const char *script __unused,
396
const char **argv __unused)
401
static int default_stop_script(void)
406
static int default_generate_script(const char *outfile __unused)
411
static struct scripting_ops default_scripting_ops = {
412
.start_script = default_start_script,
413
.stop_script = default_stop_script,
414
.process_event = process_event,
415
.generate_script = default_generate_script,
418
static struct scripting_ops *scripting_ops;
420
static void setup_scripting(void)
422
setup_perl_scripting();
423
setup_python_scripting();
425
scripting_ops = &default_scripting_ops;
428
static int cleanup_scripting(void)
430
pr_debug("\nperf script stopped\n");
432
return scripting_ops->stop_script();
435
static char const *input_name = "perf.data";
437
static int process_sample_event(union perf_event *event,
438
struct perf_sample *sample,
439
struct perf_evsel *evsel,
440
struct perf_session *session)
442
struct thread *thread = perf_session__findnew(session, event->ip.pid);
444
if (thread == NULL) {
445
pr_debug("problem processing %d event, skipping it.\n",
451
if (sample->time < last_timestamp) {
452
pr_err("Samples misordered, previous: %" PRIu64
453
" this: %" PRIu64 "\n", last_timestamp,
457
last_timestamp = sample->time;
461
if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
464
scripting_ops->process_event(event, sample, evsel, session, thread);
466
session->hists.stats.total_period += sample->period;
470
static struct perf_event_ops event_ops = {
471
.sample = process_sample_event,
472
.mmap = perf_event__process_mmap,
473
.comm = perf_event__process_comm,
474
.exit = perf_event__process_task,
475
.fork = perf_event__process_task,
476
.attr = perf_event__process_attr,
477
.event_type = perf_event__process_event_type,
478
.tracing_data = perf_event__process_tracing_data,
479
.build_id = perf_event__process_build_id,
480
.ordered_samples = true,
481
.ordering_requires_timestamps = true,
484
extern volatile int session_done;
486
static void sig_handler(int sig __unused)
491
static int __cmd_script(struct perf_session *session)
495
signal(SIGINT, sig_handler);
497
ret = perf_session__process_events(session, &event_ops);
500
pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
506
struct list_head node;
507
struct scripting_ops *ops;
511
static LIST_HEAD(script_specs);
513
static struct script_spec *script_spec__new(const char *spec,
514
struct scripting_ops *ops)
516
struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
519
strcpy(s->spec, spec);
526
static void script_spec__delete(struct script_spec *s)
532
static void script_spec__add(struct script_spec *s)
534
list_add_tail(&s->node, &script_specs);
537
static struct script_spec *script_spec__find(const char *spec)
539
struct script_spec *s;
541
list_for_each_entry(s, &script_specs, node)
542
if (strcasecmp(s->spec, spec) == 0)
547
static struct script_spec *script_spec__findnew(const char *spec,
548
struct scripting_ops *ops)
550
struct script_spec *s = script_spec__find(spec);
555
s = script_spec__new(spec, ops);
557
goto out_delete_spec;
564
script_spec__delete(s);
569
int script_spec_register(const char *spec, struct scripting_ops *ops)
571
struct script_spec *s;
573
s = script_spec__find(spec);
577
s = script_spec__findnew(spec, ops);
584
static struct scripting_ops *script_spec__lookup(const char *spec)
586
struct script_spec *s = script_spec__find(spec);
593
static void list_available_languages(void)
595
struct script_spec *s;
597
fprintf(stderr, "\n");
598
fprintf(stderr, "Scripting language extensions (used in "
599
"perf script -s [spec:]script.[spec]):\n\n");
601
list_for_each_entry(s, &script_specs, node)
602
fprintf(stderr, " %-42s [%s]\n", s->spec, s->ops->name);
604
fprintf(stderr, "\n");
607
static int parse_scriptname(const struct option *opt __used,
608
const char *str, int unset __used)
611
const char *script, *ext;
614
if (strcmp(str, "lang") == 0) {
615
list_available_languages();
619
script = strchr(str, ':');
622
if (len >= PATH_MAX) {
623
fprintf(stderr, "invalid language specifier");
626
strncpy(spec, str, len);
628
scripting_ops = script_spec__lookup(spec);
629
if (!scripting_ops) {
630
fprintf(stderr, "invalid language specifier");
636
ext = strrchr(script, '.');
638
fprintf(stderr, "invalid script extension");
641
scripting_ops = script_spec__lookup(++ext);
642
if (!scripting_ops) {
643
fprintf(stderr, "invalid script extension");
648
script_name = strdup(script);
653
static int parse_output_fields(const struct option *opt __used,
654
const char *arg, int unset __used)
657
int i, imax = sizeof(all_output_options) / sizeof(struct output_option);
660
char *str = strdup(arg);
666
/* first word can state for which event type the user is specifying
667
* the fields. If no type exists, the specified fields apply to all
668
* event types found in the file minus the invalid fields for a type.
670
tok = strchr(str, ':');
674
if (!strcmp(str, "hw"))
675
type = PERF_TYPE_HARDWARE;
676
else if (!strcmp(str, "sw"))
677
type = PERF_TYPE_SOFTWARE;
678
else if (!strcmp(str, "trace"))
679
type = PERF_TYPE_TRACEPOINT;
680
else if (!strcmp(str, "raw"))
681
type = PERF_TYPE_RAW;
683
fprintf(stderr, "Invalid event type in field string.\n");
687
if (output[type].user_set)
688
pr_warning("Overriding previous field request for %s events.\n",
691
output[type].fields = 0;
692
output[type].user_set = true;
693
output[type].wildcard_set = false;
697
if (strlen(str) == 0) {
699
"Cannot set fields to 'none' for all event types.\n");
704
if (output_set_by_user())
705
pr_warning("Overriding previous field request for all events.\n");
707
for (j = 0; j < PERF_TYPE_MAX; ++j) {
708
output[j].fields = 0;
709
output[j].user_set = true;
710
output[j].wildcard_set = true;
714
tok = strtok(tok, ",");
716
for (i = 0; i < imax; ++i) {
717
if (strcmp(tok, all_output_options[i].str) == 0)
721
fprintf(stderr, "Invalid field requested.\n");
727
/* add user option to all events types for
730
for (j = 0; j < PERF_TYPE_MAX; ++j) {
731
if (output[j].invalid_fields & all_output_options[i].field) {
732
pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
733
all_output_options[i].str, event_type(j));
735
output[j].fields |= all_output_options[i].field;
738
if (output[type].invalid_fields & all_output_options[i].field) {
739
fprintf(stderr, "\'%s\' not valid for %s events.\n",
740
all_output_options[i].str, event_type(type));
745
output[type].fields |= all_output_options[i].field;
748
tok = strtok(NULL, ",");
752
if (output[type].fields == 0) {
753
pr_debug("No fields requested for %s type. "
754
"Events will not be displayed.\n", event_type(type));
763
/* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */
764
static int is_directory(const char *base_path, const struct dirent *dent)
769
sprintf(path, "%s/%s", base_path, dent->d_name);
773
return S_ISDIR(st.st_mode);
776
#define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\
777
while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \
779
if ((lang_dirent.d_type == DT_DIR || \
780
(lang_dirent.d_type == DT_UNKNOWN && \
781
is_directory(scripts_path, &lang_dirent))) && \
782
(strcmp(lang_dirent.d_name, ".")) && \
783
(strcmp(lang_dirent.d_name, "..")))
785
#define for_each_script(lang_path, lang_dir, script_dirent, script_next)\
786
while (!readdir_r(lang_dir, &script_dirent, &script_next) && \
788
if (script_dirent.d_type != DT_DIR && \
789
(script_dirent.d_type != DT_UNKNOWN || \
790
!is_directory(lang_path, &script_dirent)))
793
#define RECORD_SUFFIX "-record"
794
#define REPORT_SUFFIX "-report"
797
struct list_head node;
803
static LIST_HEAD(script_descs);
805
static struct script_desc *script_desc__new(const char *name)
807
struct script_desc *s = zalloc(sizeof(*s));
809
if (s != NULL && name)
810
s->name = strdup(name);
815
static void script_desc__delete(struct script_desc *s)
823
static void script_desc__add(struct script_desc *s)
825
list_add_tail(&s->node, &script_descs);
828
static struct script_desc *script_desc__find(const char *name)
830
struct script_desc *s;
832
list_for_each_entry(s, &script_descs, node)
833
if (strcasecmp(s->name, name) == 0)
838
static struct script_desc *script_desc__findnew(const char *name)
840
struct script_desc *s = script_desc__find(name);
845
s = script_desc__new(name);
847
goto out_delete_desc;
854
script_desc__delete(s);
859
static const char *ends_with(const char *str, const char *suffix)
861
size_t suffix_len = strlen(suffix);
864
if (strlen(str) > suffix_len) {
865
p = str + strlen(str) - suffix_len;
866
if (!strncmp(p, suffix, suffix_len))
873
static char *ltrim(char *str)
875
int len = strlen(str);
877
while (len && isspace(*str)) {
885
static int read_script_info(struct script_desc *desc, const char *filename)
887
char line[BUFSIZ], *p;
890
fp = fopen(filename, "r");
894
while (fgets(line, sizeof(line), fp)) {
901
if (strlen(p) && *p == '!')
905
if (strlen(p) && p[strlen(p) - 1] == '\n')
906
p[strlen(p) - 1] = '\0';
908
if (!strncmp(p, "description:", strlen("description:"))) {
909
p += strlen("description:");
910
desc->half_liner = strdup(ltrim(p));
914
if (!strncmp(p, "args:", strlen("args:"))) {
915
p += strlen("args:");
916
desc->args = strdup(ltrim(p));
926
static int list_available_scripts(const struct option *opt __used,
927
const char *s __used, int unset __used)
929
struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
930
char scripts_path[MAXPATHLEN];
931
DIR *scripts_dir, *lang_dir;
932
char script_path[MAXPATHLEN];
933
char lang_path[MAXPATHLEN];
934
struct script_desc *desc;
935
char first_half[BUFSIZ];
939
snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
941
scripts_dir = opendir(scripts_path);
945
for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
946
snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
948
lang_dir = opendir(lang_path);
952
for_each_script(lang_path, lang_dir, script_dirent, script_next) {
953
script_root = strdup(script_dirent.d_name);
954
str = (char *)ends_with(script_root, REPORT_SUFFIX);
957
desc = script_desc__findnew(script_root);
958
snprintf(script_path, MAXPATHLEN, "%s/%s",
959
lang_path, script_dirent.d_name);
960
read_script_info(desc, script_path);
966
fprintf(stdout, "List of available trace scripts:\n");
967
list_for_each_entry(desc, &script_descs, node) {
968
sprintf(first_half, "%s %s", desc->name,
969
desc->args ? desc->args : "");
970
fprintf(stdout, " %-36s %s\n", first_half,
971
desc->half_liner ? desc->half_liner : "");
977
static char *get_script_path(const char *script_root, const char *suffix)
979
struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
980
char scripts_path[MAXPATHLEN];
981
char script_path[MAXPATHLEN];
982
DIR *scripts_dir, *lang_dir;
983
char lang_path[MAXPATHLEN];
984
char *str, *__script_root;
987
snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
989
scripts_dir = opendir(scripts_path);
993
for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
994
snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
996
lang_dir = opendir(lang_path);
1000
for_each_script(lang_path, lang_dir, script_dirent, script_next) {
1001
__script_root = strdup(script_dirent.d_name);
1002
str = (char *)ends_with(__script_root, suffix);
1005
if (strcmp(__script_root, script_root))
1007
snprintf(script_path, MAXPATHLEN, "%s/%s",
1008
lang_path, script_dirent.d_name);
1009
path = strdup(script_path);
1010
free(__script_root);
1013
free(__script_root);
1020
static bool is_top_script(const char *script_path)
1022
return ends_with(script_path, "top") == NULL ? false : true;
1025
static int has_required_arg(char *script_path)
1027
struct script_desc *desc;
1031
desc = script_desc__new(NULL);
1033
if (read_script_info(desc, script_path))
1039
for (p = desc->args; *p; p++)
1043
script_desc__delete(desc);
1048
static const char * const script_usage[] = {
1049
"perf script [<options>]",
1050
"perf script [<options>] record <script> [<record-options>] <command>",
1051
"perf script [<options>] report <script> [script-args]",
1052
"perf script [<options>] <script> [<record-options>] <command>",
1053
"perf script [<options>] <top-script> [script-args]",
1057
static const struct option options[] = {
1058
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1059
"dump raw trace in ASCII"),
1060
OPT_INCR('v', "verbose", &verbose,
1061
"be more verbose (show symbol address, etc)"),
1062
OPT_BOOLEAN('L', "Latency", &latency_format,
1063
"show latency attributes (irqs/preemption disabled, etc)"),
1064
OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
1065
list_available_scripts),
1066
OPT_CALLBACK('s', "script", NULL, "name",
1067
"script file name (lang:script name, script name, or *)",
1069
OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
1070
"generate perf-script.xx script in specified language"),
1071
OPT_STRING('i', "input", &input_name, "file",
1073
OPT_BOOLEAN('d', "debug-mode", &debug_mode,
1074
"do various checks like samples ordering and lost events"),
1075
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
1076
"file", "vmlinux pathname"),
1077
OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
1078
"file", "kallsyms pathname"),
1079
OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
1080
"When printing symbols do not display call chain"),
1081
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
1082
"Look for files with symbols relative to this directory"),
1083
OPT_CALLBACK('f', "fields", NULL, "str",
1084
"comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr",
1085
parse_output_fields),
1086
OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
1087
OPT_BOOLEAN('I', "show-info", &show_full_info,
1088
"display extended information from perf.data file"),
1092
static bool have_cmd(int argc, const char **argv)
1094
char **__argv = malloc(sizeof(const char *) * argc);
1098
memcpy(__argv, argv, sizeof(const char *) * argc);
1099
argc = parse_options(argc, (const char **)__argv, record_options,
1100
NULL, PARSE_OPT_STOP_AT_NON_OPTION);
1106
int cmd_script(int argc, const char **argv, const char *prefix __used)
1108
char *rec_script_path = NULL;
1109
char *rep_script_path = NULL;
1110
struct perf_session *session;
1111
char *script_path = NULL;
1112
const char **__argv;
1118
argc = parse_options(argc, argv, options, script_usage,
1119
PARSE_OPT_STOP_AT_NON_OPTION);
1121
if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
1122
rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
1123
if (!rec_script_path)
1124
return cmd_record(argc, argv, NULL);
1127
if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
1128
rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
1129
if (!rep_script_path) {
1131
"Please specify a valid report script"
1132
"(see 'perf script -l' for listing)\n");
1137
/* make sure PERF_EXEC_PATH is set for scripts */
1138
perf_set_argv_exec_path(perf_exec_path());
1140
if (argc && !script_name && !rec_script_path && !rep_script_path) {
1145
rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);
1146
rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
1148
if (!rec_script_path && !rep_script_path) {
1149
fprintf(stderr, " Couldn't find script %s\n\n See perf"
1150
" script -l for available scripts.\n", argv[0]);
1151
usage_with_options(script_usage, options);
1154
if (is_top_script(argv[0])) {
1155
rep_args = argc - 1;
1159
rep_args = has_required_arg(rep_script_path);
1160
rec_args = (argc - 1) - rep_args;
1162
fprintf(stderr, " %s script requires options."
1163
"\n\n See perf script -l for available "
1164
"scripts and options.\n", argv[0]);
1165
usage_with_options(script_usage, options);
1169
if (pipe(live_pipe) < 0) {
1170
perror("failed to create pipe");
1176
perror("failed to fork");
1184
dup2(live_pipe[1], 1);
1185
close(live_pipe[0]);
1187
if (!is_top_script(argv[0]))
1188
system_wide = !have_cmd(argc - rep_args,
1191
__argv = malloc((argc + 6) * sizeof(const char *));
1195
__argv[j++] = "/bin/sh";
1196
__argv[j++] = rec_script_path;
1202
for (i = rep_args + 1; i < argc; i++)
1203
__argv[j++] = argv[i];
1206
execvp("/bin/sh", (char **)__argv);
1211
dup2(live_pipe[0], 0);
1212
close(live_pipe[1]);
1214
__argv = malloc((argc + 4) * sizeof(const char *));
1218
__argv[j++] = "/bin/sh";
1219
__argv[j++] = rep_script_path;
1220
for (i = 1; i < rep_args + 1; i++)
1221
__argv[j++] = argv[i];
1226
execvp("/bin/sh", (char **)__argv);
1231
if (rec_script_path)
1232
script_path = rec_script_path;
1233
if (rep_script_path)
1234
script_path = rep_script_path;
1237
system_wide = false;
1240
if (rec_script_path)
1241
system_wide = !have_cmd(argc - 1, &argv[1]);
1243
__argv = malloc((argc + 2) * sizeof(const char *));
1246
__argv[j++] = "/bin/sh";
1247
__argv[j++] = script_path;
1250
for (i = 2; i < argc; i++)
1251
__argv[j++] = argv[i];
1254
execvp("/bin/sh", (char **)__argv);
1259
if (symbol__init() < 0)
1264
session = perf_session__new(input_name, O_RDONLY, 0, false, &event_ops);
1265
if (session == NULL)
1269
if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
1273
perf_session__fprintf_info(session, stdout, show_full_info);
1276
symbol_conf.use_callchain = true;
1278
symbol_conf.use_callchain = false;
1280
if (generate_script_lang) {
1281
struct stat perf_stat;
1284
if (output_set_by_user()) {
1286
"custom fields not supported for generated scripts");
1290
input = open(input_name, O_RDONLY);
1292
perror("failed to open file");
1296
err = fstat(input, &perf_stat);
1298
perror("failed to stat file");
1302
if (!perf_stat.st_size) {
1303
fprintf(stderr, "zero-sized file, nothing to do!\n");
1307
scripting_ops = script_spec__lookup(generate_script_lang);
1308
if (!scripting_ops) {
1309
fprintf(stderr, "invalid language specifier");
1313
err = scripting_ops->generate_script("perf-script");
1318
err = scripting_ops->start_script(script_name, argc, argv);
1321
pr_debug("perf script started with script %s\n\n", script_name);
1325
err = perf_session__check_output_opt(session);
1329
err = __cmd_script(session);
1331
perf_session__delete(session);
1332
cleanup_scripting();