aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 13:28:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 13:28:49 -0400
commit7e92daaefa68e5ef1e1732e45231e73adbb724e7 (patch)
tree8e7f8ac9d82654df4c65939c6682f95510e22977 /tools/perf/builtin-script.c
parent7a68294278ae714ce2632a54f0f46916dca64f56 (diff)
parent1d787d37c8ff6612b8151c6dff15bfa7347bcbdf (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf update from Ingo Molnar: "Lots of changes in this cycle as well, with hundreds of commits from over 30 contributors. Most of the activity was on the tooling side. Higher level changes: - New 'perf kvm' analysis tool, from Xiao Guangrong. - New 'perf trace' system-wide tracing tool - uprobes fixes + cleanups from Oleg Nesterov. - Lots of patches to make perf build on Android out of box, from Irina Tirdea - Extend ftrace function tracing utility to be more dynamic for its users. It allows for data passing to the callback functions, as well as reading regs as if a breakpoint were to trigger at function entry. The main goal of this patch series was to allow kprobes to use ftrace as an optimized probe point when a probe is placed on an ftrace nop. With lots of help from Masami Hiramatsu, and going through lots of iterations, we finally came up with a good solution. - Add cpumask for uncore pmu, use it in 'stat', from Yan, Zheng. - Various tracing updates from Steve Rostedt - Clean up and improve 'perf sched' performance by elliminating lots of needless calls to libtraceevent. - Event group parsing support, from Jiri Olsa - UI/gtk refactorings and improvements from Namhyung Kim - Add support for non-tracepoint events in perf script python, from Feng Tang - Add --symbols to 'script', similar to the one in 'report', from Feng Tang. Infrastructure enhancements and fixes: - Convert the trace builtins to use the growing evsel/evlist tracepoint infrastructure, removing several open coded constructs like switch like series of strcmp to dispatch events, etc. Basically what had already been showcased in 'perf sched'. - Add evsel constructor for tracepoints, that uses libtraceevent just to parse the /format events file, use it in a new 'perf test' to make sure the libtraceevent format parsing regressions can be more readily caught. - Some strange errors were happening in some builds, but not on the next, reported by several people, problem was some parser related files, generated during the build, didn't had proper make deps, fix from Eric Sandeen. - Introduce struct and cache information about the environment where a perf.data file was captured, from Namhyung Kim. - Fix handling of unresolved samples when --symbols is used in 'report', from Feng Tang. - Add union member access support to 'probe', from Hyeoncheol Lee. - Fixups to die() removal, from Namhyung Kim. - Render fixes for the TUI, from Namhyung Kim. - Don't enable annotation in non symbolic view, from Namhyung Kim. - Fix pipe mode in 'report', from Namhyung Kim. - Move related stats code from stat to util/, will be used by the 'stat' kvm tool, from Xiao Guangrong. - Remove die()/exit() calls from several tools. - Resolve vdso callchains, from Jiri Olsa - Don't pass const char pointers to basename, so that we can unconditionally use libgen.h and thus avoid ifdef BIONIC lines, from David Ahern - Refactor hist formatting so that it can be reused with the GTK browser, From Namhyung Kim - Fix build for another rbtree.c change, from Adrian Hunter. - Make 'perf diff' command work with evsel hists, from Jiri Olsa. - Use the only field_sep var that is set up: symbol_conf.field_sep, fix from Jiri Olsa. - .gitignore compiled python binaries, from Namhyung Kim. - Get rid of die() in more libtraceevent places, from Namhyung Kim. - Rename libtraceevent 'private' struct member to 'priv' so that it works in C++, from Steven Rostedt - Remove lots of exit()/die() calls from tools so that the main perf exit routine can take place, from David Ahern - Fix x86 build on x86-64, from David Ahern. - {int,str,rb}list fixes from Suzuki K Poulose - perf.data header fixes from Namhyung Kim - Allow user to indicate objdump path, needed in cross environments, from Maciek Borzecki - Fix hardware cache event name generation, fix from Jiri Olsa - Add round trip test for sw, hw and cache event names, catching the problem Jiri fixed, after Jiri's patch, the test passes successfully. - Clean target should do clean for lib/traceevent too, fix from David Ahern - Check the right variable for allocation failure, fix from Namhyung Kim - Set up evsel->tp_format regardless of evsel->name being set already, fix from Namhyung Kim - Oprofile fixes from Robert Richter. - Remove perf_event_attr needless version inflation, from Jiri Olsa - Introduce libtraceevent strerror like error reporting facility, from Namhyung Kim - Add pmu mappings to perf.data header and use event names from cmd line, from Robert Richter - Fix include order for bison/flex-generated C files, from Ben Hutchings - Build fixes and documentation corrections from David Ahern - Assorted cleanups from Robert Richter - Let O= makes handle relative paths, from Steven Rostedt - perf script python fixes, from Feng Tang. - Initial bash completion support, from Frederic Weisbecker - Allow building without libelf, from Namhyung Kim. - Support DWARF CFI based unwind to have callchains when %bp based unwinding is not possible, from Jiri Olsa. - Symbol resolution fixes, while fixing support PPC64 files with an .opt ELF section was the end goal, several fixes for code that handles all architectures and cleanups are included, from Cody Schafer. - Assorted fixes for Documentation and build in 32 bit, from Robert Richter - Cache the libtraceevent event_format associated to each evsel early, so that we avoid relookups, i.e. calling pevent_find_event repeatedly when processing tracepoint events. [ This is to reduce the surface contact with libtraceevents and make clear what is that the perf tools needs from that lib: so far parsing the common and per event fields. ] - Don't stop the build if the audit libraries are not installed, fix from Namhyung Kim. - Fix bfd.h/libbfd detection with recent binutils, from Markus Trippelsdorf. - Improve warning message when libunwind devel packages not present, from Jiri Olsa" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (282 commits) perf trace: Add aliases for some syscalls perf probe: Print an enum type variable in "enum variable-name" format when showing accessible variables perf tools: Check libaudit availability for perf-trace builtin perf hists: Add missing period_* fields when collapsing a hist entry perf trace: New tool perf evsel: Export the event_format constructor perf evsel: Introduce rawptr() method perf tools: Use perf_evsel__newtp in the event parser perf evsel: The tracepoint constructor should store sys:name perf evlist: Introduce set_filter() method perf evlist: Renane set_filters method to apply_filters perf test: Add test to check we correctly parse and match syscall open parms perf evsel: Handle endianity in intval method perf evsel: Know if byte swap is needed perf tools: Allow handling a NULL cpu_map as meaning "all cpus" perf evsel: Improve tracepoint constructor setup tools lib traceevent: Fix error path on pevent_parse_event perf test: Fix build failure trace: Move trace event enable from fs_initcall to core_initcall tracing: Add an option for disabling markers ...
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c229
1 files changed, 140 insertions, 89 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 1e60ab70b2b1..1be843aa1546 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -14,6 +14,7 @@
14#include "util/util.h" 14#include "util/util.h"
15#include "util/evlist.h" 15#include "util/evlist.h"
16#include "util/evsel.h" 16#include "util/evsel.h"
17#include "util/sort.h"
17#include <linux/bitmap.h> 18#include <linux/bitmap.h>
18 19
19static char const *script_name; 20static char const *script_name;
@@ -28,11 +29,6 @@ static bool system_wide;
28static const char *cpu_list; 29static const char *cpu_list;
29static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 30static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
30 31
31struct perf_script {
32 struct perf_tool tool;
33 struct perf_session *session;
34};
35
36enum perf_output_field { 32enum perf_output_field {
37 PERF_OUTPUT_COMM = 1U << 0, 33 PERF_OUTPUT_COMM = 1U << 0,
38 PERF_OUTPUT_TID = 1U << 1, 34 PERF_OUTPUT_TID = 1U << 1,
@@ -262,14 +258,11 @@ static int perf_session__check_output_opt(struct perf_session *session)
262 return 0; 258 return 0;
263} 259}
264 260
265static void print_sample_start(struct pevent *pevent, 261static void print_sample_start(struct perf_sample *sample,
266 struct perf_sample *sample,
267 struct thread *thread, 262 struct thread *thread,
268 struct perf_evsel *evsel) 263 struct perf_evsel *evsel)
269{ 264{
270 int type;
271 struct perf_event_attr *attr = &evsel->attr; 265 struct perf_event_attr *attr = &evsel->attr;
272 struct event_format *event;
273 const char *evname = NULL; 266 const char *evname = NULL;
274 unsigned long secs; 267 unsigned long secs;
275 unsigned long usecs; 268 unsigned long usecs;
@@ -307,20 +300,7 @@ static void print_sample_start(struct pevent *pevent,
307 } 300 }
308 301
309 if (PRINT_FIELD(EVNAME)) { 302 if (PRINT_FIELD(EVNAME)) {
310 if (attr->type == PERF_TYPE_TRACEPOINT) { 303 evname = perf_evsel__name(evsel);
311 /*
312 * XXX Do we really need this here?
313 * perf_evlist__set_tracepoint_names should have done
314 * this already
315 */
316 type = trace_parse_common_type(pevent,
317 sample->raw_data);
318 event = pevent_find_event(pevent, type);
319 if (event)
320 evname = event->name;
321 } else
322 evname = perf_evsel__name(evsel);
323
324 printf("%s: ", evname ? evname : "[unknown]"); 304 printf("%s: ", evname ? evname : "[unknown]");
325 } 305 }
326} 306}
@@ -401,7 +381,7 @@ static void print_sample_bts(union perf_event *event,
401 printf(" "); 381 printf(" ");
402 else 382 else
403 printf("\n"); 383 printf("\n");
404 perf_event__print_ip(event, sample, machine, 384 perf_evsel__print_ip(evsel, event, sample, machine,
405 PRINT_FIELD(SYM), PRINT_FIELD(DSO), 385 PRINT_FIELD(SYM), PRINT_FIELD(DSO),
406 PRINT_FIELD(SYMOFFSET)); 386 PRINT_FIELD(SYMOFFSET));
407 } 387 }
@@ -415,19 +395,17 @@ static void print_sample_bts(union perf_event *event,
415 printf("\n"); 395 printf("\n");
416} 396}
417 397
418static void process_event(union perf_event *event __unused, 398static void process_event(union perf_event *event, struct perf_sample *sample,
419 struct pevent *pevent, 399 struct perf_evsel *evsel, struct machine *machine,
420 struct perf_sample *sample, 400 struct addr_location *al)
421 struct perf_evsel *evsel,
422 struct machine *machine,
423 struct thread *thread)
424{ 401{
425 struct perf_event_attr *attr = &evsel->attr; 402 struct perf_event_attr *attr = &evsel->attr;
403 struct thread *thread = al->thread;
426 404
427 if (output[attr->type].fields == 0) 405 if (output[attr->type].fields == 0)
428 return; 406 return;
429 407
430 print_sample_start(pevent, sample, thread, evsel); 408 print_sample_start(sample, thread, evsel);
431 409
432 if (is_bts_event(attr)) { 410 if (is_bts_event(attr)) {
433 print_sample_bts(event, sample, evsel, machine, thread); 411 print_sample_bts(event, sample, evsel, machine, thread);
@@ -435,9 +413,8 @@ static void process_event(union perf_event *event __unused,
435 } 413 }
436 414
437 if (PRINT_FIELD(TRACE)) 415 if (PRINT_FIELD(TRACE))
438 print_trace_event(pevent, sample->cpu, sample->raw_data, 416 event_format__print(evsel->tp_format, sample->cpu,
439 sample->raw_size); 417 sample->raw_data, sample->raw_size);
440
441 if (PRINT_FIELD(ADDR)) 418 if (PRINT_FIELD(ADDR))
442 print_sample_addr(event, sample, machine, thread, attr); 419 print_sample_addr(event, sample, machine, thread, attr);
443 420
@@ -446,7 +423,7 @@ static void process_event(union perf_event *event __unused,
446 printf(" "); 423 printf(" ");
447 else 424 else
448 printf("\n"); 425 printf("\n");
449 perf_event__print_ip(event, sample, machine, 426 perf_evsel__print_ip(evsel, event, sample, machine,
450 PRINT_FIELD(SYM), PRINT_FIELD(DSO), 427 PRINT_FIELD(SYM), PRINT_FIELD(DSO),
451 PRINT_FIELD(SYMOFFSET)); 428 PRINT_FIELD(SYMOFFSET));
452 } 429 }
@@ -454,9 +431,9 @@ static void process_event(union perf_event *event __unused,
454 printf("\n"); 431 printf("\n");
455} 432}
456 433
457static int default_start_script(const char *script __unused, 434static int default_start_script(const char *script __maybe_unused,
458 int argc __unused, 435 int argc __maybe_unused,
459 const char **argv __unused) 436 const char **argv __maybe_unused)
460{ 437{
461 return 0; 438 return 0;
462} 439}
@@ -466,8 +443,8 @@ static int default_stop_script(void)
466 return 0; 443 return 0;
467} 444}
468 445
469static int default_generate_script(struct pevent *pevent __unused, 446static int default_generate_script(struct pevent *pevent __maybe_unused,
470 const char *outfile __unused) 447 const char *outfile __maybe_unused)
471{ 448{
472 return 0; 449 return 0;
473} 450}
@@ -498,14 +475,13 @@ static int cleanup_scripting(void)
498 475
499static const char *input_name; 476static const char *input_name;
500 477
501static int process_sample_event(struct perf_tool *tool __used, 478static int process_sample_event(struct perf_tool *tool __maybe_unused,
502 union perf_event *event, 479 union perf_event *event,
503 struct perf_sample *sample, 480 struct perf_sample *sample,
504 struct perf_evsel *evsel, 481 struct perf_evsel *evsel,
505 struct machine *machine) 482 struct machine *machine)
506{ 483{
507 struct addr_location al; 484 struct addr_location al;
508 struct perf_script *scr = container_of(tool, struct perf_script, tool);
509 struct thread *thread = machine__findnew_thread(machine, event->ip.tid); 485 struct thread *thread = machine__findnew_thread(machine, event->ip.tid);
510 486
511 if (thread == NULL) { 487 if (thread == NULL) {
@@ -537,32 +513,29 @@ static int process_sample_event(struct perf_tool *tool __used,
537 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) 513 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
538 return 0; 514 return 0;
539 515
540 scripting_ops->process_event(event, scr->session->pevent, 516 scripting_ops->process_event(event, sample, evsel, machine, &al);
541 sample, evsel, machine, thread);
542 517
543 evsel->hists.stats.total_period += sample->period; 518 evsel->hists.stats.total_period += sample->period;
544 return 0; 519 return 0;
545} 520}
546 521
547static struct perf_script perf_script = { 522static struct perf_tool perf_script = {
548 .tool = { 523 .sample = process_sample_event,
549 .sample = process_sample_event, 524 .mmap = perf_event__process_mmap,
550 .mmap = perf_event__process_mmap, 525 .comm = perf_event__process_comm,
551 .comm = perf_event__process_comm, 526 .exit = perf_event__process_task,
552 .exit = perf_event__process_task, 527 .fork = perf_event__process_task,
553 .fork = perf_event__process_task, 528 .attr = perf_event__process_attr,
554 .attr = perf_event__process_attr, 529 .event_type = perf_event__process_event_type,
555 .event_type = perf_event__process_event_type, 530 .tracing_data = perf_event__process_tracing_data,
556 .tracing_data = perf_event__process_tracing_data, 531 .build_id = perf_event__process_build_id,
557 .build_id = perf_event__process_build_id, 532 .ordered_samples = true,
558 .ordered_samples = true, 533 .ordering_requires_timestamps = true,
559 .ordering_requires_timestamps = true,
560 },
561}; 534};
562 535
563extern volatile int session_done; 536extern volatile int session_done;
564 537
565static void sig_handler(int sig __unused) 538static void sig_handler(int sig __maybe_unused)
566{ 539{
567 session_done = 1; 540 session_done = 1;
568} 541}
@@ -573,7 +546,7 @@ static int __cmd_script(struct perf_session *session)
573 546
574 signal(SIGINT, sig_handler); 547 signal(SIGINT, sig_handler);
575 548
576 ret = perf_session__process_events(session, &perf_script.tool); 549 ret = perf_session__process_events(session, &perf_script);
577 550
578 if (debug_mode) 551 if (debug_mode)
579 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 552 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
@@ -672,8 +645,8 @@ static void list_available_languages(void)
672 fprintf(stderr, "\n"); 645 fprintf(stderr, "\n");
673} 646}
674 647
675static int parse_scriptname(const struct option *opt __used, 648static int parse_scriptname(const struct option *opt __maybe_unused,
676 const char *str, int unset __used) 649 const char *str, int unset __maybe_unused)
677{ 650{
678 char spec[PATH_MAX]; 651 char spec[PATH_MAX];
679 const char *script, *ext; 652 const char *script, *ext;
@@ -718,8 +691,8 @@ static int parse_scriptname(const struct option *opt __used,
718 return 0; 691 return 0;
719} 692}
720 693
721static int parse_output_fields(const struct option *opt __used, 694static int parse_output_fields(const struct option *opt __maybe_unused,
722 const char *arg, int unset __used) 695 const char *arg, int unset __maybe_unused)
723{ 696{
724 char *tok; 697 char *tok;
725 int i, imax = sizeof(all_output_options) / sizeof(struct output_option); 698 int i, imax = sizeof(all_output_options) / sizeof(struct output_option);
@@ -1010,8 +983,9 @@ static char *get_script_root(struct dirent *script_dirent, const char *suffix)
1010 return script_root; 983 return script_root;
1011} 984}
1012 985
1013static int list_available_scripts(const struct option *opt __used, 986static int list_available_scripts(const struct option *opt __maybe_unused,
1014 const char *s __used, int unset __used) 987 const char *s __maybe_unused,
988 int unset __maybe_unused)
1015{ 989{
1016 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 990 struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
1017 char scripts_path[MAXPATHLEN]; 991 char scripts_path[MAXPATHLEN];
@@ -1058,6 +1032,61 @@ static int list_available_scripts(const struct option *opt __used,
1058 exit(0); 1032 exit(0);
1059} 1033}
1060 1034
1035/*
1036 * Return -1 if none is found, otherwise the actual scripts number.
1037 *
1038 * Currently the only user of this function is the script browser, which
1039 * will list all statically runnable scripts, select one, execute it and
1040 * show the output in a perf browser.
1041 */
1042int find_scripts(char **scripts_array, char **scripts_path_array)
1043{
1044 struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
1045 char scripts_path[MAXPATHLEN];
1046 DIR *scripts_dir, *lang_dir;
1047 char lang_path[MAXPATHLEN];
1048 char *temp;
1049 int i = 0;
1050
1051 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
1052
1053 scripts_dir = opendir(scripts_path);
1054 if (!scripts_dir)
1055 return -1;
1056
1057 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
1058 snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
1059 lang_dirent.d_name);
1060#ifdef NO_LIBPERL
1061 if (strstr(lang_path, "perl"))
1062 continue;
1063#endif
1064#ifdef NO_LIBPYTHON
1065 if (strstr(lang_path, "python"))
1066 continue;
1067#endif
1068
1069 lang_dir = opendir(lang_path);
1070 if (!lang_dir)
1071 continue;
1072
1073 for_each_script(lang_path, lang_dir, script_dirent, script_next) {
1074 /* Skip those real time scripts: xxxtop.p[yl] */
1075 if (strstr(script_dirent.d_name, "top."))
1076 continue;
1077 sprintf(scripts_path_array[i], "%s/%s", lang_path,
1078 script_dirent.d_name);
1079 temp = strchr(script_dirent.d_name, '.');
1080 snprintf(scripts_array[i],
1081 (temp - script_dirent.d_name) + 1,
1082 "%s", script_dirent.d_name);
1083 i++;
1084 }
1085 }
1086
1087 return i;
1088}
1089
1061static char *get_script_path(const char *script_root, const char *suffix) 1090static char *get_script_path(const char *script_root, const char *suffix)
1062{ 1091{
1063 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 1092 struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
@@ -1170,6 +1199,8 @@ static const struct option options[] = {
1170 parse_output_fields), 1199 parse_output_fields),
1171 OPT_BOOLEAN('a', "all-cpus", &system_wide, 1200 OPT_BOOLEAN('a', "all-cpus", &system_wide,
1172 "system-wide collection from all CPUs"), 1201 "system-wide collection from all CPUs"),
1202 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
1203 "only consider these symbols"),
1173 OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 1204 OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
1174 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", 1205 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
1175 "only display events for these comms"), 1206 "only display events for these comms"),
@@ -1181,21 +1212,26 @@ static const struct option options[] = {
1181 OPT_END() 1212 OPT_END()
1182}; 1213};
1183 1214
1184static bool have_cmd(int argc, const char **argv) 1215static int have_cmd(int argc, const char **argv)
1185{ 1216{
1186 char **__argv = malloc(sizeof(const char *) * argc); 1217 char **__argv = malloc(sizeof(const char *) * argc);
1187 1218
1188 if (!__argv) 1219 if (!__argv) {
1189 die("malloc"); 1220 pr_err("malloc failed\n");
1221 return -1;
1222 }
1223
1190 memcpy(__argv, argv, sizeof(const char *) * argc); 1224 memcpy(__argv, argv, sizeof(const char *) * argc);
1191 argc = parse_options(argc, (const char **)__argv, record_options, 1225 argc = parse_options(argc, (const char **)__argv, record_options,
1192 NULL, PARSE_OPT_STOP_AT_NON_OPTION); 1226 NULL, PARSE_OPT_STOP_AT_NON_OPTION);
1193 free(__argv); 1227 free(__argv);
1194 1228
1195 return argc != 0; 1229 system_wide = (argc == 0);
1230
1231 return 0;
1196} 1232}
1197 1233
1198int cmd_script(int argc, const char **argv, const char *prefix __used) 1234int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1199{ 1235{
1200 char *rec_script_path = NULL; 1236 char *rec_script_path = NULL;
1201 char *rep_script_path = NULL; 1237 char *rep_script_path = NULL;
@@ -1259,13 +1295,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1259 1295
1260 if (pipe(live_pipe) < 0) { 1296 if (pipe(live_pipe) < 0) {
1261 perror("failed to create pipe"); 1297 perror("failed to create pipe");
1262 exit(-1); 1298 return -1;
1263 } 1299 }
1264 1300
1265 pid = fork(); 1301 pid = fork();
1266 if (pid < 0) { 1302 if (pid < 0) {
1267 perror("failed to fork"); 1303 perror("failed to fork");
1268 exit(-1); 1304 return -1;
1269 } 1305 }
1270 1306
1271 if (!pid) { 1307 if (!pid) {
@@ -1277,13 +1313,18 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1277 if (is_top_script(argv[0])) { 1313 if (is_top_script(argv[0])) {
1278 system_wide = true; 1314 system_wide = true;
1279 } else if (!system_wide) { 1315 } else if (!system_wide) {
1280 system_wide = !have_cmd(argc - rep_args, 1316 if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
1281 &argv[rep_args]); 1317 err = -1;
1318 goto out;
1319 }
1282 } 1320 }
1283 1321
1284 __argv = malloc((argc + 6) * sizeof(const char *)); 1322 __argv = malloc((argc + 6) * sizeof(const char *));
1285 if (!__argv) 1323 if (!__argv) {
1286 die("malloc"); 1324 pr_err("malloc failed\n");
1325 err = -ENOMEM;
1326 goto out;
1327 }
1287 1328
1288 __argv[j++] = "/bin/sh"; 1329 __argv[j++] = "/bin/sh";
1289 __argv[j++] = rec_script_path; 1330 __argv[j++] = rec_script_path;
@@ -1305,8 +1346,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1305 close(live_pipe[1]); 1346 close(live_pipe[1]);
1306 1347
1307 __argv = malloc((argc + 4) * sizeof(const char *)); 1348 __argv = malloc((argc + 4) * sizeof(const char *));
1308 if (!__argv) 1349 if (!__argv) {
1309 die("malloc"); 1350 pr_err("malloc failed\n");
1351 err = -ENOMEM;
1352 goto out;
1353 }
1354
1310 j = 0; 1355 j = 0;
1311 __argv[j++] = "/bin/sh"; 1356 __argv[j++] = "/bin/sh";
1312 __argv[j++] = rep_script_path; 1357 __argv[j++] = rep_script_path;
@@ -1331,12 +1376,20 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1331 1376
1332 if (!rec_script_path) 1377 if (!rec_script_path)
1333 system_wide = false; 1378 system_wide = false;
1334 else if (!system_wide) 1379 else if (!system_wide) {
1335 system_wide = !have_cmd(argc - 1, &argv[1]); 1380 if (have_cmd(argc - 1, &argv[1]) != 0) {
1381 err = -1;
1382 goto out;
1383 }
1384 }
1336 1385
1337 __argv = malloc((argc + 2) * sizeof(const char *)); 1386 __argv = malloc((argc + 2) * sizeof(const char *));
1338 if (!__argv) 1387 if (!__argv) {
1339 die("malloc"); 1388 pr_err("malloc failed\n");
1389 err = -ENOMEM;
1390 goto out;
1391 }
1392
1340 __argv[j++] = "/bin/sh"; 1393 __argv[j++] = "/bin/sh";
1341 __argv[j++] = script_path; 1394 __argv[j++] = script_path;
1342 if (system_wide) 1395 if (system_wide)
@@ -1356,12 +1409,10 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1356 setup_pager(); 1409 setup_pager();
1357 1410
1358 session = perf_session__new(input_name, O_RDONLY, 0, false, 1411 session = perf_session__new(input_name, O_RDONLY, 0, false,
1359 &perf_script.tool); 1412 &perf_script);
1360 if (session == NULL) 1413 if (session == NULL)
1361 return -ENOMEM; 1414 return -ENOMEM;
1362 1415
1363 perf_script.session = session;
1364
1365 if (cpu_list) { 1416 if (cpu_list) {
1366 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) 1417 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
1367 return -1; 1418 return -1;
@@ -1387,18 +1438,18 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1387 input = open(session->filename, O_RDONLY); /* input_name */ 1438 input = open(session->filename, O_RDONLY); /* input_name */
1388 if (input < 0) { 1439 if (input < 0) {
1389 perror("failed to open file"); 1440 perror("failed to open file");
1390 exit(-1); 1441 return -1;
1391 } 1442 }
1392 1443
1393 err = fstat(input, &perf_stat); 1444 err = fstat(input, &perf_stat);
1394 if (err < 0) { 1445 if (err < 0) {
1395 perror("failed to stat file"); 1446 perror("failed to stat file");
1396 exit(-1); 1447 return -1;
1397 } 1448 }
1398 1449
1399 if (!perf_stat.st_size) { 1450 if (!perf_stat.st_size) {
1400 fprintf(stderr, "zero-sized file, nothing to do!\n"); 1451 fprintf(stderr, "zero-sized file, nothing to do!\n");
1401 exit(0); 1452 return 0;
1402 } 1453 }
1403 1454
1404 scripting_ops = script_spec__lookup(generate_script_lang); 1455 scripting_ops = script_spec__lookup(generate_script_lang);