aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c130
1 files changed, 74 insertions, 56 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 2f62a295226..fd1909afcfd 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -7,6 +7,7 @@
7#include "util/header.h" 7#include "util/header.h"
8#include "util/parse-options.h" 8#include "util/parse-options.h"
9#include "util/session.h" 9#include "util/session.h"
10#include "util/tool.h"
10#include "util/symbol.h" 11#include "util/symbol.h"
11#include "util/thread.h" 12#include "util/thread.h"
12#include "util/trace-event.h" 13#include "util/trace-event.h"
@@ -23,6 +24,7 @@ static u64 nr_unordered;
23extern const struct option record_options[]; 24extern const struct option record_options[];
24static bool no_callchain; 25static bool no_callchain;
25static bool show_full_info; 26static bool show_full_info;
27static bool system_wide;
26static const char *cpu_list; 28static const char *cpu_list;
27static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 29static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
28 30
@@ -315,7 +317,7 @@ static bool sample_addr_correlates_sym(struct perf_event_attr *attr)
315 317
316static void print_sample_addr(union perf_event *event, 318static void print_sample_addr(union perf_event *event,
317 struct perf_sample *sample, 319 struct perf_sample *sample,
318 struct perf_session *session, 320 struct machine *machine,
319 struct thread *thread, 321 struct thread *thread,
320 struct perf_event_attr *attr) 322 struct perf_event_attr *attr)
321{ 323{
@@ -328,11 +330,11 @@ static void print_sample_addr(union perf_event *event,
328 if (!sample_addr_correlates_sym(attr)) 330 if (!sample_addr_correlates_sym(attr))
329 return; 331 return;
330 332
331 thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, 333 thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
332 event->ip.pid, sample->addr, &al); 334 sample->addr, &al);
333 if (!al.map) 335 if (!al.map)
334 thread__find_addr_map(thread, session, cpumode, MAP__VARIABLE, 336 thread__find_addr_map(thread, machine, cpumode, MAP__VARIABLE,
335 event->ip.pid, sample->addr, &al); 337 sample->addr, &al);
336 338
337 al.cpu = sample->cpu; 339 al.cpu = sample->cpu;
338 al.sym = NULL; 340 al.sym = NULL;
@@ -362,7 +364,7 @@ static void print_sample_addr(union perf_event *event,
362static void process_event(union perf_event *event __unused, 364static void process_event(union perf_event *event __unused,
363 struct perf_sample *sample, 365 struct perf_sample *sample,
364 struct perf_evsel *evsel, 366 struct perf_evsel *evsel,
365 struct perf_session *session, 367 struct machine *machine,
366 struct thread *thread) 368 struct thread *thread)
367{ 369{
368 struct perf_event_attr *attr = &evsel->attr; 370 struct perf_event_attr *attr = &evsel->attr;
@@ -377,15 +379,15 @@ static void process_event(union perf_event *event __unused,
377 sample->raw_size); 379 sample->raw_size);
378 380
379 if (PRINT_FIELD(ADDR)) 381 if (PRINT_FIELD(ADDR))
380 print_sample_addr(event, sample, session, thread, attr); 382 print_sample_addr(event, sample, machine, thread, attr);
381 383
382 if (PRINT_FIELD(IP)) { 384 if (PRINT_FIELD(IP)) {
383 if (!symbol_conf.use_callchain) 385 if (!symbol_conf.use_callchain)
384 printf(" "); 386 printf(" ");
385 else 387 else
386 printf("\n"); 388 printf("\n");
387 perf_session__print_ip(event, sample, session, 389 perf_event__print_ip(event, sample, machine, evsel,
388 PRINT_FIELD(SYM), PRINT_FIELD(DSO)); 390 PRINT_FIELD(SYM), PRINT_FIELD(DSO));
389 } 391 }
390 392
391 printf("\n"); 393 printf("\n");
@@ -432,14 +434,16 @@ static int cleanup_scripting(void)
432 return scripting_ops->stop_script(); 434 return scripting_ops->stop_script();
433} 435}
434 436
435static char const *input_name = "perf.data"; 437static const char *input_name;
436 438
437static int process_sample_event(union perf_event *event, 439static int process_sample_event(struct perf_tool *tool __used,
440 union perf_event *event,
438 struct perf_sample *sample, 441 struct perf_sample *sample,
439 struct perf_evsel *evsel, 442 struct perf_evsel *evsel,
440 struct perf_session *session) 443 struct machine *machine)
441{ 444{
442 struct thread *thread = perf_session__findnew(session, event->ip.pid); 445 struct addr_location al;
446 struct thread *thread = machine__findnew_thread(machine, event->ip.tid);
443 447
444 if (thread == NULL) { 448 if (thread == NULL) {
445 pr_debug("problem processing %d event, skipping it.\n", 449 pr_debug("problem processing %d event, skipping it.\n",
@@ -458,16 +462,25 @@ static int process_sample_event(union perf_event *event,
458 return 0; 462 return 0;
459 } 463 }
460 464
465 if (perf_event__preprocess_sample(event, machine, &al, sample, 0) < 0) {
466 pr_err("problem processing %d event, skipping it.\n",
467 event->header.type);
468 return -1;
469 }
470
471 if (al.filtered)
472 return 0;
473
461 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) 474 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
462 return 0; 475 return 0;
463 476
464 scripting_ops->process_event(event, sample, evsel, session, thread); 477 scripting_ops->process_event(event, sample, evsel, machine, thread);
465 478
466 session->hists.stats.total_period += sample->period; 479 evsel->hists.stats.total_period += sample->period;
467 return 0; 480 return 0;
468} 481}
469 482
470static struct perf_event_ops event_ops = { 483static struct perf_tool perf_script = {
471 .sample = process_sample_event, 484 .sample = process_sample_event,
472 .mmap = perf_event__process_mmap, 485 .mmap = perf_event__process_mmap,
473 .comm = perf_event__process_comm, 486 .comm = perf_event__process_comm,
@@ -494,7 +507,7 @@ static int __cmd_script(struct perf_session *session)
494 507
495 signal(SIGINT, sig_handler); 508 signal(SIGINT, sig_handler);
496 509
497 ret = perf_session__process_events(session, &event_ops); 510 ret = perf_session__process_events(session, &perf_script);
498 511
499 if (debug_mode) 512 if (debug_mode)
500 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 513 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
@@ -523,12 +536,6 @@ static struct script_spec *script_spec__new(const char *spec,
523 return s; 536 return s;
524} 537}
525 538
526static void script_spec__delete(struct script_spec *s)
527{
528 free(s->spec);
529 free(s);
530}
531
532static void script_spec__add(struct script_spec *s) 539static void script_spec__add(struct script_spec *s)
533{ 540{
534 list_add_tail(&s->node, &script_specs); 541 list_add_tail(&s->node, &script_specs);
@@ -554,16 +561,11 @@ static struct script_spec *script_spec__findnew(const char *spec,
554 561
555 s = script_spec__new(spec, ops); 562 s = script_spec__new(spec, ops);
556 if (!s) 563 if (!s)
557 goto out_delete_spec; 564 return NULL;
558 565
559 script_spec__add(s); 566 script_spec__add(s);
560 567
561 return s; 568 return s;
562
563out_delete_spec:
564 script_spec__delete(s);
565
566 return NULL;
567} 569}
568 570
569int script_spec_register(const char *spec, struct scripting_ops *ops) 571int script_spec_register(const char *spec, struct scripting_ops *ops)
@@ -681,7 +683,8 @@ static int parse_output_fields(const struct option *opt __used,
681 type = PERF_TYPE_RAW; 683 type = PERF_TYPE_RAW;
682 else { 684 else {
683 fprintf(stderr, "Invalid event type in field string.\n"); 685 fprintf(stderr, "Invalid event type in field string.\n");
684 return -EINVAL; 686 rc = -EINVAL;
687 goto out;
685 } 688 }
686 689
687 if (output[type].user_set) 690 if (output[type].user_set)
@@ -923,6 +926,24 @@ static int read_script_info(struct script_desc *desc, const char *filename)
923 return 0; 926 return 0;
924} 927}
925 928
929static char *get_script_root(struct dirent *script_dirent, const char *suffix)
930{
931 char *script_root, *str;
932
933 script_root = strdup(script_dirent->d_name);
934 if (!script_root)
935 return NULL;
936
937 str = (char *)ends_with(script_root, suffix);
938 if (!str) {
939 free(script_root);
940 return NULL;
941 }
942
943 *str = '\0';
944 return script_root;
945}
946
926static int list_available_scripts(const struct option *opt __used, 947static int list_available_scripts(const struct option *opt __used,
927 const char *s __used, int unset __used) 948 const char *s __used, int unset __used)
928{ 949{
@@ -934,7 +955,6 @@ static int list_available_scripts(const struct option *opt __used,
934 struct script_desc *desc; 955 struct script_desc *desc;
935 char first_half[BUFSIZ]; 956 char first_half[BUFSIZ];
936 char *script_root; 957 char *script_root;
937 char *str;
938 958
939 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); 959 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
940 960
@@ -950,16 +970,14 @@ static int list_available_scripts(const struct option *opt __used,
950 continue; 970 continue;
951 971
952 for_each_script(lang_path, lang_dir, script_dirent, script_next) { 972 for_each_script(lang_path, lang_dir, script_dirent, script_next) {
953 script_root = strdup(script_dirent.d_name); 973 script_root = get_script_root(&script_dirent, REPORT_SUFFIX);
954 str = (char *)ends_with(script_root, REPORT_SUFFIX); 974 if (script_root) {
955 if (str) {
956 *str = '\0';
957 desc = script_desc__findnew(script_root); 975 desc = script_desc__findnew(script_root);
958 snprintf(script_path, MAXPATHLEN, "%s/%s", 976 snprintf(script_path, MAXPATHLEN, "%s/%s",
959 lang_path, script_dirent.d_name); 977 lang_path, script_dirent.d_name);
960 read_script_info(desc, script_path); 978 read_script_info(desc, script_path);
979 free(script_root);
961 } 980 }
962 free(script_root);
963 } 981 }
964 } 982 }
965 983
@@ -981,8 +999,7 @@ static char *get_script_path(const char *script_root, const char *suffix)
981 char script_path[MAXPATHLEN]; 999 char script_path[MAXPATHLEN];
982 DIR *scripts_dir, *lang_dir; 1000 DIR *scripts_dir, *lang_dir;
983 char lang_path[MAXPATHLEN]; 1001 char lang_path[MAXPATHLEN];
984 char *str, *__script_root; 1002 char *__script_root;
985 char *path = NULL;
986 1003
987 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); 1004 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
988 1005
@@ -998,23 +1015,18 @@ static char *get_script_path(const char *script_root, const char *suffix)
998 continue; 1015 continue;
999 1016
1000 for_each_script(lang_path, lang_dir, script_dirent, script_next) { 1017 for_each_script(lang_path, lang_dir, script_dirent, script_next) {
1001 __script_root = strdup(script_dirent.d_name); 1018 __script_root = get_script_root(&script_dirent, suffix);
1002 str = (char *)ends_with(__script_root, suffix); 1019 if (__script_root && !strcmp(script_root, __script_root)) {
1003 if (str) { 1020 free(__script_root);
1004 *str = '\0';
1005 if (strcmp(__script_root, script_root))
1006 continue;
1007 snprintf(script_path, MAXPATHLEN, "%s/%s", 1021 snprintf(script_path, MAXPATHLEN, "%s/%s",
1008 lang_path, script_dirent.d_name); 1022 lang_path, script_dirent.d_name);
1009 path = strdup(script_path); 1023 return strdup(script_path);
1010 free(__script_root);
1011 break;
1012 } 1024 }
1013 free(__script_root); 1025 free(__script_root);
1014 } 1026 }
1015 } 1027 }
1016 1028
1017 return path; 1029 return NULL;
1018} 1030}
1019 1031
1020static bool is_top_script(const char *script_path) 1032static bool is_top_script(const char *script_path)
@@ -1083,7 +1095,11 @@ static const struct option options[] = {
1083 OPT_CALLBACK('f', "fields", NULL, "str", 1095 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", 1096 "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), 1097 parse_output_fields),
1086 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 1098 OPT_BOOLEAN('a', "all-cpus", &system_wide,
1099 "system-wide collection from all CPUs"),
1100 OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
1101 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
1102 "only display events for these comms"),
1087 OPT_BOOLEAN('I', "show-info", &show_full_info, 1103 OPT_BOOLEAN('I', "show-info", &show_full_info,
1088 "display extended information from perf.data file"), 1104 "display extended information from perf.data file"),
1089 OPT_END() 1105 OPT_END()
@@ -1110,7 +1126,6 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1110 struct perf_session *session; 1126 struct perf_session *session;
1111 char *script_path = NULL; 1127 char *script_path = NULL;
1112 const char **__argv; 1128 const char **__argv;
1113 bool system_wide;
1114 int i, j, err; 1129 int i, j, err;
1115 1130
1116 setup_scripting(); 1131 setup_scripting();
@@ -1178,15 +1193,17 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1178 } 1193 }
1179 1194
1180 if (!pid) { 1195 if (!pid) {
1181 system_wide = true;
1182 j = 0; 1196 j = 0;
1183 1197
1184 dup2(live_pipe[1], 1); 1198 dup2(live_pipe[1], 1);
1185 close(live_pipe[0]); 1199 close(live_pipe[0]);
1186 1200
1187 if (!is_top_script(argv[0])) 1201 if (is_top_script(argv[0])) {
1202 system_wide = true;
1203 } else if (!system_wide) {
1188 system_wide = !have_cmd(argc - rep_args, 1204 system_wide = !have_cmd(argc - rep_args,
1189 &argv[rep_args]); 1205 &argv[rep_args]);
1206 }
1190 1207
1191 __argv = malloc((argc + 6) * sizeof(const char *)); 1208 __argv = malloc((argc + 6) * sizeof(const char *));
1192 if (!__argv) 1209 if (!__argv)
@@ -1234,10 +1251,11 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1234 script_path = rep_script_path; 1251 script_path = rep_script_path;
1235 1252
1236 if (script_path) { 1253 if (script_path) {
1237 system_wide = false;
1238 j = 0; 1254 j = 0;
1239 1255
1240 if (rec_script_path) 1256 if (!rec_script_path)
1257 system_wide = false;
1258 else if (!system_wide)
1241 system_wide = !have_cmd(argc - 1, &argv[1]); 1259 system_wide = !have_cmd(argc - 1, &argv[1]);
1242 1260
1243 __argv = malloc((argc + 2) * sizeof(const char *)); 1261 __argv = malloc((argc + 2) * sizeof(const char *));
@@ -1261,7 +1279,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1261 if (!script_name) 1279 if (!script_name)
1262 setup_pager(); 1280 setup_pager();
1263 1281
1264 session = perf_session__new(input_name, O_RDONLY, 0, false, &event_ops); 1282 session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_script);
1265 if (session == NULL) 1283 if (session == NULL)
1266 return -ENOMEM; 1284 return -ENOMEM;
1267 1285
@@ -1287,7 +1305,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1287 return -1; 1305 return -1;
1288 } 1306 }
1289 1307
1290 input = open(input_name, O_RDONLY); 1308 input = open(session->filename, O_RDONLY); /* input_name */
1291 if (input < 0) { 1309 if (input < 0) {
1292 perror("failed to open file"); 1310 perror("failed to open file");
1293 exit(-1); 1311 exit(-1);