18 #include <linux/bitmap.h>
20 static char const *script_name;
21 static char const *generate_script_lang;
23 static u64 last_timestamp;
24 static u64 nr_unordered;
26 static bool no_callchain;
27 static bool system_wide;
28 static const char *cpu_list;
114 static bool output_set_by_user(
void)
127 const char *
str =
"";
129 for (i = 0; i < imax; ++
i) {
138 #define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x)
140 static int perf_evsel__check_stype(
struct perf_evsel *evsel,
153 pr_err(
"Samples for '%s' event do not have %s attribute set. "
154 "Cannot print '%s' field.\n",
155 evname, sample_msg, output_field2str(field));
162 pr_debug(
"Samples for '%s' event do not have %s attribute set. "
163 "Skipping '%s' field.\n",
164 evname, sample_msg, output_field2str(field));
169 static int perf_evsel__check_attr(
struct perf_evsel *evsel,
194 pr_err(
"Display of symbols requested but neither sample IP nor "
195 "sample address\nis selected. Hence, no addresses to convert "
200 pr_err(
"Display of offsets requested but symbol is not"
205 pr_err(
"Display of DSO requested but neither sample IP nor "
206 "sample address\nis selected. Hence, no addresses to convert "
233 static int perf_session__check_output_opt(
struct perf_session *session)
246 pr_err(
"%s events do not exist. "
247 "Remove corresponding -f option to proceed.\n",
252 if (evsel && output[j].
fields &&
253 perf_evsel__check_attr(evsel, session))
265 const char *evname =
NULL;
268 unsigned long long nsecs;
294 nsecs = sample->
time;
298 printf(
"%5lu.%06lu: ", secs, usecs);
303 printf(
"%s: ", evname ? evname :
"[unknown]");
322 if (is_bts_event(attr))
331 struct thread *thread,
339 if (!sample_addr_correlates_sym(attr))
348 al.cpu = sample->
cpu;
369 static void print_sample_bts(
union perf_event *event,
372 struct machine *machine,
373 struct thread *thread)
392 print_sample_addr(event, sample, machine, thread, attr);
398 struct perf_evsel *evsel,
struct machine *machine,
402 struct thread *thread = al->
thread;
404 if (output[attr->
type].fields == 0)
407 print_sample_start(sample, thread, evsel);
409 if (is_bts_event(attr)) {
410 print_sample_bts(event, sample, evsel, machine, thread);
418 print_sample_addr(event, sample, machine, thread, attr);
434 int argc __maybe_unused,
435 const char **argv __maybe_unused)
440 static int default_stop_script(
void)
446 const char *outfile __maybe_unused)
452 .start_script = default_start_script,
453 .stop_script = default_stop_script,
455 .generate_script = default_generate_script,
460 static void setup_scripting(
void)
465 scripting_ops = &default_scripting_ops;
468 static int cleanup_scripting(
void)
470 pr_debug(
"\nperf script stopped\n");
479 struct machine *machine)
484 if (thread ==
NULL) {
485 pr_debug(
"problem processing %d event, skipping it.\n",
491 if (sample->
time < last_timestamp) {
493 " this: %" PRIu64 "\n", last_timestamp,
497 last_timestamp = sample->
time;
502 pr_err(
"problem processing %d event, skipping it.\n",
510 if (cpu_list && !
test_bit(sample->
cpu, cpu_bitmap))
513 scripting_ops->
process_event(event, sample, evsel, machine, &al);
520 .sample = process_sample_event,
529 .ordered_samples =
true,
530 .ordering_requires_timestamps =
true,
549 pr_err(
"Misordered timestamps: %" PRIu64 "\n", nr_unordered);
556 struct scripting_ops *
ops;
563 struct scripting_ops *
ops)
575 static void script_spec__add(
struct script_spec *s)
580 static struct script_spec *script_spec__find(
const char *spec)
591 struct scripting_ops *ops)
598 s = script_spec__new(spec, ops);
611 s = script_spec__find(spec);
615 s = script_spec__findnew(spec, ops);
622 static struct scripting_ops *script_spec__lookup(
const char *spec)
631 static void list_available_languages(
void)
636 fprintf(stderr,
"Scripting language extensions (used in "
637 "perf script -s [spec:]script.[spec]):\n\n");
640 fprintf(stderr, " %-42s [%s]\
n", s->spec, s->ops->
name);
646 const char *str,
int unset __maybe_unused)
652 if (
strcmp(str,
"lang") == 0) {
653 list_available_languages();
657 script =
strchr(str,
':');
661 fprintf(stderr,
"invalid language specifier");
666 scripting_ops = script_spec__lookup(spec);
667 if (!scripting_ops) {
668 fprintf(stderr,
"invalid language specifier");
676 fprintf(stderr,
"invalid script extension");
679 scripting_ops = script_spec__lookup(++ext);
680 if (!scripting_ops) {
681 fprintf(stderr,
"invalid script extension");
686 script_name = strdup(script);
691 static int parse_output_fields(
const struct option *
opt __maybe_unused,
692 const char *
arg,
int unset __maybe_unused)
698 char *str = strdup(arg);
714 else if (!
strcmp(str,
"sw"))
716 else if (!
strcmp(str,
"trace"))
718 else if (!
strcmp(str,
"raw"))
721 fprintf(stderr,
"Invalid event type in field string.\n");
727 pr_warning(
"Overriding previous field request for %s events.\n",
738 "Cannot set fields to 'none' for all event types.\n");
743 if (output_set_by_user())
744 pr_warning(
"Overriding previous field request for all events.\n");
753 tok = strtok(tok,
",");
755 for (i = 0; i < imax; ++
i) {
760 fprintf(stderr,
"Invalid field requested.\n");
771 pr_warning(
"\'%s\' not valid for %s events. Ignoring.\n",
778 fprintf(stderr,
"\'%s\' not valid for %s events.\n",
787 tok = strtok(NULL,
",");
791 if (output[type].
fields == 0) {
792 pr_debug(
"No fields requested for %s type. "
793 "Events will not be displayed.\n",
event_type(type));
803 static int is_directory(
const char *base_path,
const struct dirent *dent)
808 sprintf(path,
"%s/%s", base_path, dent->d_name);
815 #define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\
816 while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \
818 if ((lang_dirent.d_type == DT_DIR || \
819 (lang_dirent.d_type == DT_UNKNOWN && \
820 is_directory(scripts_path, &lang_dirent))) && \
821 (strcmp(lang_dirent.d_name, ".")) && \
822 (strcmp(lang_dirent.d_name, "..")))
824 #define for_each_script(lang_path, lang_dir, script_dirent, script_next)\
825 while (!readdir_r(lang_dir, &script_dirent, &script_next) && \
827 if (script_dirent.d_type != DT_DIR && \
828 (script_dirent.d_type != DT_UNKNOWN || \
829 !is_directory(lang_path, &script_dirent)))
832 #define RECORD_SUFFIX "-record"
833 #define REPORT_SUFFIX "-report"
844 static struct script_desc *script_desc__new(
const char *name)
848 if (s != NULL && name)
849 s->
name = strdup(name);
854 static void script_desc__delete(
struct script_desc *s)
862 static void script_desc__add(
struct script_desc *s)
867 static struct script_desc *script_desc__find(
const char *name)
884 s = script_desc__new(name);
886 goto out_delete_desc;
893 script_desc__delete(s);
898 static const char *ends_with(
const char *str,
const char *suffix)
900 size_t suffix_len =
strlen(suffix);
903 if (
strlen(str) > suffix_len) {
904 p = str +
strlen(str) - suffix_len;
905 if (!
strncmp(p, suffix, suffix_len))
912 static char *ltrim(
char *str)
926 char line[BUFSIZ], *
p;
929 fp = fopen(filename,
"r");
933 while (fgets(line,
sizeof(line), fp)) {
940 if (
strlen(p) && *p ==
'!')
948 p +=
strlen(
"description:");
955 desc->
args = strdup(ltrim(p));
965 static char *get_script_root(
struct dirent *script_dirent,
const char *suffix)
967 char *script_root, *
str;
969 script_root = strdup(script_dirent->d_name);
973 str = (
char *)ends_with(script_root, suffix);
983 static int list_available_scripts(
const struct option *
opt __maybe_unused,
984 const char *s __maybe_unused,
985 int unset __maybe_unused)
987 struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
989 DIR *scripts_dir, *lang_dir;
993 char first_half[BUFSIZ];
998 scripts_dir = opendir(scripts_path);
1002 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
1004 lang_dirent.d_name);
1005 lang_dir = opendir(lang_path);
1010 script_root = get_script_root(&script_dirent,
REPORT_SUFFIX);
1012 desc = script_desc__findnew(script_root);
1014 lang_path, script_dirent.d_name);
1015 read_script_info(desc, script_path);
1021 fprintf(stdout,
"List of available trace scripts:\n");
1025 fprintf(stdout,
" %-36s %s\n", first_half,
1041 struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
1043 DIR *scripts_dir, *lang_dir;
1050 scripts_dir = opendir(scripts_path);
1054 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
1056 lang_dirent.d_name);
1058 if (
strstr(lang_path,
"perl"))
1062 if (
strstr(lang_path,
"python"))
1066 lang_dir = opendir(lang_path);
1072 if (
strstr(script_dirent.d_name,
"top."))
1074 sprintf(scripts_path_array[i],
"%s/%s", lang_path,
1075 script_dirent.d_name);
1076 temp =
strchr(script_dirent.d_name,
'.');
1078 (temp - script_dirent.d_name) + 1,
1079 "%s", script_dirent.d_name);
1087 static char *get_script_path(
const char *script_root,
const char *suffix)
1089 struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
1092 DIR *scripts_dir, *lang_dir;
1094 char *__script_root;
1098 scripts_dir = opendir(scripts_path);
1102 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
1104 lang_dirent.d_name);
1105 lang_dir = opendir(lang_path);
1110 __script_root = get_script_root(&script_dirent, suffix);
1111 if (__script_root && !
strcmp(script_root, __script_root)) {
1112 free(__script_root);
1114 closedir(scripts_dir);
1116 lang_path, script_dirent.d_name);
1117 return strdup(script_path);
1119 free(__script_root);
1123 closedir(scripts_dir);
1128 static bool is_top_script(
const char *script_path)
1130 return ends_with(script_path,
"top") == NULL ?
false :
true;
1133 static int has_required_arg(
char *script_path)
1139 desc = script_desc__new(NULL);
1141 if (read_script_info(desc, script_path))
1147 for (p = desc->
args; *p; p++)
1151 script_desc__delete(desc);
1156 static int have_cmd(
int argc,
const char **argv)
1158 char **__argv =
malloc(
sizeof(
const char *) * argc);
1161 pr_err(
"malloc failed\n");
1165 memcpy(__argv, argv,
sizeof(
const char *) * argc);
1170 system_wide = (argc == 0);
1177 bool show_full_info =
false;
1178 const char *input_name =
NULL;
1179 char *rec_script_path =
NULL;
1180 char *rep_script_path =
NULL;
1182 char *script_path =
NULL;
1183 const char **__argv;
1185 const struct option options[] = {
1187 "dump raw trace in ASCII"),
1189 "be more verbose (show symbol address, etc)"),
1191 "show latency attributes (irqs/preemption disabled, etc)"),
1193 list_available_scripts),
1195 "script file name (lang:script name, script name, or *)",
1197 OPT_STRING(
'g',
"gen-script", &generate_script_lang,
"lang",
1198 "generate perf-script.xx script in specified language"),
1199 OPT_STRING(
'i',
"input", &input_name,
"file",
"input file name"),
1201 "do various checks like samples ordering and lost events"),
1203 "file",
"vmlinux pathname"),
1205 "file",
"kallsyms pathname"),
1206 OPT_BOOLEAN(
'G',
"hide-call-graph", &no_callchain,
1207 "When printing symbols do not display call chain"),
1209 "Look for files with symbols relative to this directory"),
1211 "comma separated output fields prepend with 'type:'. "
1212 "Valid types: hw,sw,trace,raw. "
1213 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
1214 "addr,symoff", parse_output_fields),
1216 "system-wide collection from all CPUs"),
1218 "only consider these symbols"),
1219 OPT_STRING(
'C',
"cpu", &cpu_list,
"cpu",
"list of cpus to profile"),
1221 "only display events for these comms"),
1223 "display extended information from perf.data file"),
1225 "Show the path of [kernel.kallsyms]"),
1228 const char *
const script_usage[] = {
1229 "perf script [<options>]",
1230 "perf script [<options>] record <script> [<record-options>] <command>",
1231 "perf script [<options>] report <script> [script-args]",
1232 "perf script [<options>] <script> [<record-options>] <command>",
1233 "perf script [<options>] <top-script> [script-args]",
1244 if (!rec_script_path)
1250 if (!rep_script_path) {
1252 "Please specify a valid report script"
1253 "(see 'perf script -l' for listing)\n");
1261 if (argc && !script_name && !rec_script_path && !rep_script_path) {
1269 if (!rec_script_path && !rep_script_path) {
1270 fprintf(stderr,
" Couldn't find script %s\n\n See perf"
1271 " script -l for available scripts.\n", argv[0]);
1275 if (is_top_script(argv[0])) {
1276 rep_args = argc - 1;
1280 rep_args = has_required_arg(rep_script_path);
1281 rec_args = (argc - 1) - rep_args;
1283 fprintf(stderr,
" %s script requires options."
1284 "\n\n See perf script -l for available "
1285 "scripts and options.\n", argv[0]);
1290 if (
pipe(live_pipe) < 0) {
1291 perror(
"failed to create pipe");
1297 perror(
"failed to fork");
1304 dup2(live_pipe[1], 1);
1305 close(live_pipe[0]);
1307 if (is_top_script(argv[0])) {
1309 }
else if (!system_wide) {
1310 if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
1316 __argv =
malloc((argc + 6) *
sizeof(
const char *));
1318 pr_err(
"malloc failed\n");
1323 __argv[j++] =
"/bin/sh";
1324 __argv[j++] = rec_script_path;
1330 for (i = rep_args + 1; i <
argc; i++)
1331 __argv[j++] = argv[i];
1334 execvp(
"/bin/sh", (
char **)__argv);
1339 dup2(live_pipe[0], 0);
1340 close(live_pipe[1]);
1342 __argv =
malloc((argc + 4) *
sizeof(
const char *));
1344 pr_err(
"malloc failed\n");
1350 __argv[j++] =
"/bin/sh";
1351 __argv[j++] = rep_script_path;
1352 for (i = 1; i < rep_args + 1; i++)
1353 __argv[j++] = argv[i];
1358 execvp(
"/bin/sh", (
char **)__argv);
1363 if (rec_script_path)
1364 script_path = rec_script_path;
1365 if (rep_script_path)
1366 script_path = rep_script_path;
1371 if (!rec_script_path)
1372 system_wide =
false;
1373 else if (!system_wide) {
1374 if (have_cmd(argc - 1, &argv[1]) != 0) {
1380 __argv =
malloc((argc + 2) *
sizeof(
const char *));
1382 pr_err(
"malloc failed\n");
1387 __argv[j++] =
"/bin/sh";
1388 __argv[j++] = script_path;
1391 for (i = 2; i <
argc; i++)
1392 __argv[j++] = argv[i];
1395 execvp(
"/bin/sh", (
char **)__argv);
1407 if (session == NULL)
1422 if (generate_script_lang) {
1423 struct stat perf_stat;
1426 if (output_set_by_user()) {
1428 "custom fields not supported for generated scripts");
1434 perror(
"failed to open file");
1438 err = fstat(input, &perf_stat);
1440 perror(
"failed to stat file");
1445 fprintf(stderr,
"zero-sized file, nothing to do!\n");
1449 scripting_ops = script_spec__lookup(generate_script_lang);
1450 if (!scripting_ops) {
1451 fprintf(stderr,
"invalid language specifier");
1461 err = scripting_ops->
start_script(script_name, argc, argv);
1464 pr_debug(
"perf script started with script %s\n\n", script_name);
1468 err = perf_session__check_output_opt(session);
1472 err = __cmd_script(session);
1475 cleanup_scripting();