perf script: Move printing of 'common' data from print_event and rename
[linux-2.6.git] / tools / perf / builtin-script.c
1 #include "builtin.h"
2
3 #include "perf.h"
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/parse-options.h"
14 #include "util/util.h"
15
16 static char const               *script_name;
17 static char const               *generate_script_lang;
18 static bool                     debug_mode;
19 static u64                      last_timestamp;
20 static u64                      nr_unordered;
21 extern const struct option      record_options[];
22
23 static void print_sample_start(struct perf_sample *sample,
24                                struct thread *thread)
25 {
26         int type;
27         struct event *event;
28         const char *evname = NULL;
29         unsigned long secs;
30         unsigned long usecs;
31         unsigned long long nsecs = sample->time;
32
33         if (latency_format)
34                 printf("%8.8s-%-5d %3d", thread->comm, sample->tid, sample->cpu);
35         else
36                 printf("%16s-%-5d [%03d]", thread->comm, sample->tid, sample->cpu);
37
38         secs = nsecs / NSECS_PER_SEC;
39         nsecs -= secs * NSECS_PER_SEC;
40         usecs = nsecs / NSECS_PER_USEC;
41         printf(" %5lu.%06lu: ", secs, usecs);
42
43         type = trace_parse_common_type(sample->raw_data);
44         event = trace_find_event(type);
45         if (event)
46                 evname = event->name;
47
48         printf("%s: ", evname ? evname : "(unknown)");
49 }
50
51 static void process_event(union perf_event *event __unused,
52                           struct perf_sample *sample,
53                           struct perf_session *session __unused,
54                           struct thread *thread)
55 {
56         print_sample_start(sample, thread);
57         print_trace_event(sample->cpu, sample->raw_data, sample->raw_size);
58         printf("\n");
59 }
60
61 static int default_start_script(const char *script __unused,
62                                 int argc __unused,
63                                 const char **argv __unused)
64 {
65         return 0;
66 }
67
68 static int default_stop_script(void)
69 {
70         return 0;
71 }
72
73 static int default_generate_script(const char *outfile __unused)
74 {
75         return 0;
76 }
77
78 static struct scripting_ops default_scripting_ops = {
79         .start_script           = default_start_script,
80         .stop_script            = default_stop_script,
81         .process_event          = process_event,
82         .generate_script        = default_generate_script,
83 };
84
85 static struct scripting_ops     *scripting_ops;
86
87 static void setup_scripting(void)
88 {
89         setup_perl_scripting();
90         setup_python_scripting();
91
92         scripting_ops = &default_scripting_ops;
93 }
94
95 static int cleanup_scripting(void)
96 {
97         pr_debug("\nperf script stopped\n");
98
99         return scripting_ops->stop_script();
100 }
101
102 static char const               *input_name = "perf.data";
103
104 static int process_sample_event(union perf_event *event,
105                                 struct perf_sample *sample,
106                                 struct perf_session *session)
107 {
108         struct thread *thread = perf_session__findnew(session, event->ip.pid);
109
110         if (thread == NULL) {
111                 pr_debug("problem processing %d event, skipping it.\n",
112                          event->header.type);
113                 return -1;
114         }
115
116         if (session->sample_type & PERF_SAMPLE_RAW) {
117                 if (debug_mode) {
118                         if (sample->time < last_timestamp) {
119                                 pr_err("Samples misordered, previous: %" PRIu64
120                                         " this: %" PRIu64 "\n", last_timestamp,
121                                         sample->time);
122                                 nr_unordered++;
123                         }
124                         last_timestamp = sample->time;
125                         return 0;
126                 }
127                 scripting_ops->process_event(event, sample, session, thread);
128         }
129
130         session->hists.stats.total_period += sample->period;
131         return 0;
132 }
133
134 static struct perf_event_ops event_ops = {
135         .sample          = process_sample_event,
136         .comm            = perf_event__process_comm,
137         .attr            = perf_event__process_attr,
138         .event_type      = perf_event__process_event_type,
139         .tracing_data    = perf_event__process_tracing_data,
140         .build_id        = perf_event__process_build_id,
141         .ordered_samples = true,
142         .ordering_requires_timestamps = true,
143 };
144
145 extern volatile int session_done;
146
147 static void sig_handler(int sig __unused)
148 {
149         session_done = 1;
150 }
151
152 static int __cmd_script(struct perf_session *session)
153 {
154         int ret;
155
156         signal(SIGINT, sig_handler);
157
158         ret = perf_session__process_events(session, &event_ops);
159
160         if (debug_mode)
161                 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
162
163         return ret;
164 }
165
166 struct script_spec {
167         struct list_head        node;
168         struct scripting_ops    *ops;
169         char                    spec[0];
170 };
171
172 static LIST_HEAD(script_specs);
173
174 static struct script_spec *script_spec__new(const char *spec,
175                                             struct scripting_ops *ops)
176 {
177         struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
178
179         if (s != NULL) {
180                 strcpy(s->spec, spec);
181                 s->ops = ops;
182         }
183
184         return s;
185 }
186
187 static void script_spec__delete(struct script_spec *s)
188 {
189         free(s->spec);
190         free(s);
191 }
192
193 static void script_spec__add(struct script_spec *s)
194 {
195         list_add_tail(&s->node, &script_specs);
196 }
197
198 static struct script_spec *script_spec__find(const char *spec)
199 {
200         struct script_spec *s;
201
202         list_for_each_entry(s, &script_specs, node)
203                 if (strcasecmp(s->spec, spec) == 0)
204                         return s;
205         return NULL;
206 }
207
208 static struct script_spec *script_spec__findnew(const char *spec,
209                                                 struct scripting_ops *ops)
210 {
211         struct script_spec *s = script_spec__find(spec);
212
213         if (s)
214                 return s;
215
216         s = script_spec__new(spec, ops);
217         if (!s)
218                 goto out_delete_spec;
219
220         script_spec__add(s);
221
222         return s;
223
224 out_delete_spec:
225         script_spec__delete(s);
226
227         return NULL;
228 }
229
230 int script_spec_register(const char *spec, struct scripting_ops *ops)
231 {
232         struct script_spec *s;
233
234         s = script_spec__find(spec);
235         if (s)
236                 return -1;
237
238         s = script_spec__findnew(spec, ops);
239         if (!s)
240                 return -1;
241
242         return 0;
243 }
244
245 static struct scripting_ops *script_spec__lookup(const char *spec)
246 {
247         struct script_spec *s = script_spec__find(spec);
248         if (!s)
249                 return NULL;
250
251         return s->ops;
252 }
253
254 static void list_available_languages(void)
255 {
256         struct script_spec *s;
257
258         fprintf(stderr, "\n");
259         fprintf(stderr, "Scripting language extensions (used in "
260                 "perf script -s [spec:]script.[spec]):\n\n");
261
262         list_for_each_entry(s, &script_specs, node)
263                 fprintf(stderr, "  %-42s [%s]\n", s->spec, s->ops->name);
264
265         fprintf(stderr, "\n");
266 }
267
268 static int parse_scriptname(const struct option *opt __used,
269                             const char *str, int unset __used)
270 {
271         char spec[PATH_MAX];
272         const char *script, *ext;
273         int len;
274
275         if (strcmp(str, "lang") == 0) {
276                 list_available_languages();
277                 exit(0);
278         }
279
280         script = strchr(str, ':');
281         if (script) {
282                 len = script - str;
283                 if (len >= PATH_MAX) {
284                         fprintf(stderr, "invalid language specifier");
285                         return -1;
286                 }
287                 strncpy(spec, str, len);
288                 spec[len] = '\0';
289                 scripting_ops = script_spec__lookup(spec);
290                 if (!scripting_ops) {
291                         fprintf(stderr, "invalid language specifier");
292                         return -1;
293                 }
294                 script++;
295         } else {
296                 script = str;
297                 ext = strrchr(script, '.');
298                 if (!ext) {
299                         fprintf(stderr, "invalid script extension");
300                         return -1;
301                 }
302                 scripting_ops = script_spec__lookup(++ext);
303                 if (!scripting_ops) {
304                         fprintf(stderr, "invalid script extension");
305                         return -1;
306                 }
307         }
308
309         script_name = strdup(script);
310
311         return 0;
312 }
313
314 /* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */
315 static int is_directory(const char *base_path, const struct dirent *dent)
316 {
317         char path[PATH_MAX];
318         struct stat st;
319
320         sprintf(path, "%s/%s", base_path, dent->d_name);
321         if (stat(path, &st))
322                 return 0;
323
324         return S_ISDIR(st.st_mode);
325 }
326
327 #define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\
328         while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) &&     \
329                lang_next)                                               \
330                 if ((lang_dirent.d_type == DT_DIR ||                    \
331                      (lang_dirent.d_type == DT_UNKNOWN &&               \
332                       is_directory(scripts_path, &lang_dirent))) &&     \
333                     (strcmp(lang_dirent.d_name, ".")) &&                \
334                     (strcmp(lang_dirent.d_name, "..")))
335
336 #define for_each_script(lang_path, lang_dir, script_dirent, script_next)\
337         while (!readdir_r(lang_dir, &script_dirent, &script_next) &&    \
338                script_next)                                             \
339                 if (script_dirent.d_type != DT_DIR &&                   \
340                     (script_dirent.d_type != DT_UNKNOWN ||              \
341                      !is_directory(lang_path, &script_dirent)))
342
343
344 #define RECORD_SUFFIX                   "-record"
345 #define REPORT_SUFFIX                   "-report"
346
347 struct script_desc {
348         struct list_head        node;
349         char                    *name;
350         char                    *half_liner;
351         char                    *args;
352 };
353
354 static LIST_HEAD(script_descs);
355
356 static struct script_desc *script_desc__new(const char *name)
357 {
358         struct script_desc *s = zalloc(sizeof(*s));
359
360         if (s != NULL && name)
361                 s->name = strdup(name);
362
363         return s;
364 }
365
366 static void script_desc__delete(struct script_desc *s)
367 {
368         free(s->name);
369         free(s->half_liner);
370         free(s->args);
371         free(s);
372 }
373
374 static void script_desc__add(struct script_desc *s)
375 {
376         list_add_tail(&s->node, &script_descs);
377 }
378
379 static struct script_desc *script_desc__find(const char *name)
380 {
381         struct script_desc *s;
382
383         list_for_each_entry(s, &script_descs, node)
384                 if (strcasecmp(s->name, name) == 0)
385                         return s;
386         return NULL;
387 }
388
389 static struct script_desc *script_desc__findnew(const char *name)
390 {
391         struct script_desc *s = script_desc__find(name);
392
393         if (s)
394                 return s;
395
396         s = script_desc__new(name);
397         if (!s)
398                 goto out_delete_desc;
399
400         script_desc__add(s);
401
402         return s;
403
404 out_delete_desc:
405         script_desc__delete(s);
406
407         return NULL;
408 }
409
410 static const char *ends_with(const char *str, const char *suffix)
411 {
412         size_t suffix_len = strlen(suffix);
413         const char *p = str;
414
415         if (strlen(str) > suffix_len) {
416                 p = str + strlen(str) - suffix_len;
417                 if (!strncmp(p, suffix, suffix_len))
418                         return p;
419         }
420
421         return NULL;
422 }
423
424 static char *ltrim(char *str)
425 {
426         int len = strlen(str);
427
428         while (len && isspace(*str)) {
429                 len--;
430                 str++;
431         }
432
433         return str;
434 }
435
436 static int read_script_info(struct script_desc *desc, const char *filename)
437 {
438         char line[BUFSIZ], *p;
439         FILE *fp;
440
441         fp = fopen(filename, "r");
442         if (!fp)
443                 return -1;
444
445         while (fgets(line, sizeof(line), fp)) {
446                 p = ltrim(line);
447                 if (strlen(p) == 0)
448                         continue;
449                 if (*p != '#')
450                         continue;
451                 p++;
452                 if (strlen(p) && *p == '!')
453                         continue;
454
455                 p = ltrim(p);
456                 if (strlen(p) && p[strlen(p) - 1] == '\n')
457                         p[strlen(p) - 1] = '\0';
458
459                 if (!strncmp(p, "description:", strlen("description:"))) {
460                         p += strlen("description:");
461                         desc->half_liner = strdup(ltrim(p));
462                         continue;
463                 }
464
465                 if (!strncmp(p, "args:", strlen("args:"))) {
466                         p += strlen("args:");
467                         desc->args = strdup(ltrim(p));
468                         continue;
469                 }
470         }
471
472         fclose(fp);
473
474         return 0;
475 }
476
477 static int list_available_scripts(const struct option *opt __used,
478                                   const char *s __used, int unset __used)
479 {
480         struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
481         char scripts_path[MAXPATHLEN];
482         DIR *scripts_dir, *lang_dir;
483         char script_path[MAXPATHLEN];
484         char lang_path[MAXPATHLEN];
485         struct script_desc *desc;
486         char first_half[BUFSIZ];
487         char *script_root;
488         char *str;
489
490         snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
491
492         scripts_dir = opendir(scripts_path);
493         if (!scripts_dir)
494                 return -1;
495
496         for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
497                 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
498                          lang_dirent.d_name);
499                 lang_dir = opendir(lang_path);
500                 if (!lang_dir)
501                         continue;
502
503                 for_each_script(lang_path, lang_dir, script_dirent, script_next) {
504                         script_root = strdup(script_dirent.d_name);
505                         str = (char *)ends_with(script_root, REPORT_SUFFIX);
506                         if (str) {
507                                 *str = '\0';
508                                 desc = script_desc__findnew(script_root);
509                                 snprintf(script_path, MAXPATHLEN, "%s/%s",
510                                          lang_path, script_dirent.d_name);
511                                 read_script_info(desc, script_path);
512                         }
513                         free(script_root);
514                 }
515         }
516
517         fprintf(stdout, "List of available trace scripts:\n");
518         list_for_each_entry(desc, &script_descs, node) {
519                 sprintf(first_half, "%s %s", desc->name,
520                         desc->args ? desc->args : "");
521                 fprintf(stdout, "  %-36s %s\n", first_half,
522                         desc->half_liner ? desc->half_liner : "");
523         }
524
525         exit(0);
526 }
527
528 static char *get_script_path(const char *script_root, const char *suffix)
529 {
530         struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
531         char scripts_path[MAXPATHLEN];
532         char script_path[MAXPATHLEN];
533         DIR *scripts_dir, *lang_dir;
534         char lang_path[MAXPATHLEN];
535         char *str, *__script_root;
536         char *path = NULL;
537
538         snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
539
540         scripts_dir = opendir(scripts_path);
541         if (!scripts_dir)
542                 return NULL;
543
544         for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
545                 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
546                          lang_dirent.d_name);
547                 lang_dir = opendir(lang_path);
548                 if (!lang_dir)
549                         continue;
550
551                 for_each_script(lang_path, lang_dir, script_dirent, script_next) {
552                         __script_root = strdup(script_dirent.d_name);
553                         str = (char *)ends_with(__script_root, suffix);
554                         if (str) {
555                                 *str = '\0';
556                                 if (strcmp(__script_root, script_root))
557                                         continue;
558                                 snprintf(script_path, MAXPATHLEN, "%s/%s",
559                                          lang_path, script_dirent.d_name);
560                                 path = strdup(script_path);
561                                 free(__script_root);
562                                 break;
563                         }
564                         free(__script_root);
565                 }
566         }
567
568         return path;
569 }
570
571 static bool is_top_script(const char *script_path)
572 {
573         return ends_with(script_path, "top") == NULL ? false : true;
574 }
575
576 static int has_required_arg(char *script_path)
577 {
578         struct script_desc *desc;
579         int n_args = 0;
580         char *p;
581
582         desc = script_desc__new(NULL);
583
584         if (read_script_info(desc, script_path))
585                 goto out;
586
587         if (!desc->args)
588                 goto out;
589
590         for (p = desc->args; *p; p++)
591                 if (*p == '<')
592                         n_args++;
593 out:
594         script_desc__delete(desc);
595
596         return n_args;
597 }
598
599 static const char * const script_usage[] = {
600         "perf script [<options>]",
601         "perf script [<options>] record <script> [<record-options>] <command>",
602         "perf script [<options>] report <script> [script-args]",
603         "perf script [<options>] <script> [<record-options>] <command>",
604         "perf script [<options>] <top-script> [script-args]",
605         NULL
606 };
607
608 static const struct option options[] = {
609         OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
610                     "dump raw trace in ASCII"),
611         OPT_INCR('v', "verbose", &verbose,
612                     "be more verbose (show symbol address, etc)"),
613         OPT_BOOLEAN('L', "Latency", &latency_format,
614                     "show latency attributes (irqs/preemption disabled, etc)"),
615         OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
616                            list_available_scripts),
617         OPT_CALLBACK('s', "script", NULL, "name",
618                      "script file name (lang:script name, script name, or *)",
619                      parse_scriptname),
620         OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
621                    "generate perf-script.xx script in specified language"),
622         OPT_STRING('i', "input", &input_name, "file",
623                     "input file name"),
624         OPT_BOOLEAN('d', "debug-mode", &debug_mode,
625                    "do various checks like samples ordering and lost events"),
626
627         OPT_END()
628 };
629
630 static bool have_cmd(int argc, const char **argv)
631 {
632         char **__argv = malloc(sizeof(const char *) * argc);
633
634         if (!__argv)
635                 die("malloc");
636         memcpy(__argv, argv, sizeof(const char *) * argc);
637         argc = parse_options(argc, (const char **)__argv, record_options,
638                              NULL, PARSE_OPT_STOP_AT_NON_OPTION);
639         free(__argv);
640
641         return argc != 0;
642 }
643
644 int cmd_script(int argc, const char **argv, const char *prefix __used)
645 {
646         char *rec_script_path = NULL;
647         char *rep_script_path = NULL;
648         struct perf_session *session;
649         char *script_path = NULL;
650         const char **__argv;
651         bool system_wide;
652         int i, j, err;
653
654         setup_scripting();
655
656         argc = parse_options(argc, argv, options, script_usage,
657                              PARSE_OPT_STOP_AT_NON_OPTION);
658
659         if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
660                 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
661                 if (!rec_script_path)
662                         return cmd_record(argc, argv, NULL);
663         }
664
665         if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
666                 rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
667                 if (!rep_script_path) {
668                         fprintf(stderr,
669                                 "Please specify a valid report script"
670                                 "(see 'perf script -l' for listing)\n");
671                         return -1;
672                 }
673         }
674
675         /* make sure PERF_EXEC_PATH is set for scripts */
676         perf_set_argv_exec_path(perf_exec_path());
677
678         if (argc && !script_name && !rec_script_path && !rep_script_path) {
679                 int live_pipe[2];
680                 int rep_args;
681                 pid_t pid;
682
683                 rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);
684                 rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
685
686                 if (!rec_script_path && !rep_script_path) {
687                         fprintf(stderr, " Couldn't find script %s\n\n See perf"
688                                 " script -l for available scripts.\n", argv[0]);
689                         usage_with_options(script_usage, options);
690                 }
691
692                 if (is_top_script(argv[0])) {
693                         rep_args = argc - 1;
694                 } else {
695                         int rec_args;
696
697                         rep_args = has_required_arg(rep_script_path);
698                         rec_args = (argc - 1) - rep_args;
699                         if (rec_args < 0) {
700                                 fprintf(stderr, " %s script requires options."
701                                         "\n\n See perf script -l for available "
702                                         "scripts and options.\n", argv[0]);
703                                 usage_with_options(script_usage, options);
704                         }
705                 }
706
707                 if (pipe(live_pipe) < 0) {
708                         perror("failed to create pipe");
709                         exit(-1);
710                 }
711
712                 pid = fork();
713                 if (pid < 0) {
714                         perror("failed to fork");
715                         exit(-1);
716                 }
717
718                 if (!pid) {
719                         system_wide = true;
720                         j = 0;
721
722                         dup2(live_pipe[1], 1);
723                         close(live_pipe[0]);
724
725                         if (!is_top_script(argv[0]))
726                                 system_wide = !have_cmd(argc - rep_args,
727                                                         &argv[rep_args]);
728
729                         __argv = malloc((argc + 6) * sizeof(const char *));
730                         if (!__argv)
731                                 die("malloc");
732
733                         __argv[j++] = "/bin/sh";
734                         __argv[j++] = rec_script_path;
735                         if (system_wide)
736                                 __argv[j++] = "-a";
737                         __argv[j++] = "-q";
738                         __argv[j++] = "-o";
739                         __argv[j++] = "-";
740                         for (i = rep_args + 1; i < argc; i++)
741                                 __argv[j++] = argv[i];
742                         __argv[j++] = NULL;
743
744                         execvp("/bin/sh", (char **)__argv);
745                         free(__argv);
746                         exit(-1);
747                 }
748
749                 dup2(live_pipe[0], 0);
750                 close(live_pipe[1]);
751
752                 __argv = malloc((argc + 4) * sizeof(const char *));
753                 if (!__argv)
754                         die("malloc");
755                 j = 0;
756                 __argv[j++] = "/bin/sh";
757                 __argv[j++] = rep_script_path;
758                 for (i = 1; i < rep_args + 1; i++)
759                         __argv[j++] = argv[i];
760                 __argv[j++] = "-i";
761                 __argv[j++] = "-";
762                 __argv[j++] = NULL;
763
764                 execvp("/bin/sh", (char **)__argv);
765                 free(__argv);
766                 exit(-1);
767         }
768
769         if (rec_script_path)
770                 script_path = rec_script_path;
771         if (rep_script_path)
772                 script_path = rep_script_path;
773
774         if (script_path) {
775                 system_wide = false;
776                 j = 0;
777
778                 if (rec_script_path)
779                         system_wide = !have_cmd(argc - 1, &argv[1]);
780
781                 __argv = malloc((argc + 2) * sizeof(const char *));
782                 if (!__argv)
783                         die("malloc");
784                 __argv[j++] = "/bin/sh";
785                 __argv[j++] = script_path;
786                 if (system_wide)
787                         __argv[j++] = "-a";
788                 for (i = 2; i < argc; i++)
789                         __argv[j++] = argv[i];
790                 __argv[j++] = NULL;
791
792                 execvp("/bin/sh", (char **)__argv);
793                 free(__argv);
794                 exit(-1);
795         }
796
797         if (symbol__init() < 0)
798                 return -1;
799         if (!script_name)
800                 setup_pager();
801
802         session = perf_session__new(input_name, O_RDONLY, 0, false, &event_ops);
803         if (session == NULL)
804                 return -ENOMEM;
805
806         if (strcmp(input_name, "-") &&
807             !perf_session__has_traces(session, "record -R"))
808                 return -EINVAL;
809
810         if (generate_script_lang) {
811                 struct stat perf_stat;
812
813                 int input = open(input_name, O_RDONLY);
814                 if (input < 0) {
815                         perror("failed to open file");
816                         exit(-1);
817                 }
818
819                 err = fstat(input, &perf_stat);
820                 if (err < 0) {
821                         perror("failed to stat file");
822                         exit(-1);
823                 }
824
825                 if (!perf_stat.st_size) {
826                         fprintf(stderr, "zero-sized file, nothing to do!\n");
827                         exit(0);
828                 }
829
830                 scripting_ops = script_spec__lookup(generate_script_lang);
831                 if (!scripting_ops) {
832                         fprintf(stderr, "invalid language specifier");
833                         return -1;
834                 }
835
836                 err = scripting_ops->generate_script("perf-script");
837                 goto out;
838         }
839
840         if (script_name) {
841                 err = scripting_ops->start_script(script_name, argc, argv);
842                 if (err)
843                         goto out;
844                 pr_debug("perf script started with script %s\n\n", script_name);
845         }
846
847         err = __cmd_script(session);
848
849         perf_session__delete(session);
850         cleanup_scripting();
851 out:
852         return err;
853 }