linux/tools/perf/builtin-script.c
<<
>>
Prefs
   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/tool.h"
  11#include "util/symbol.h"
  12#include "util/thread.h"
  13#include "util/trace-event.h"
  14#include "util/util.h"
  15#include "util/evlist.h"
  16#include "util/evsel.h"
  17#include "util/sort.h"
  18#include <linux/bitmap.h>
  19
  20static char const               *script_name;
  21static char const               *generate_script_lang;
  22static bool                     debug_mode;
  23static u64                      last_timestamp;
  24static u64                      nr_unordered;
  25extern const struct option      record_options[];
  26static bool                     no_callchain;
  27static bool                     latency_format;
  28static bool                     system_wide;
  29static const char               *cpu_list;
  30static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
  31
  32enum perf_output_field {
  33        PERF_OUTPUT_COMM            = 1U << 0,
  34        PERF_OUTPUT_TID             = 1U << 1,
  35        PERF_OUTPUT_PID             = 1U << 2,
  36        PERF_OUTPUT_TIME            = 1U << 3,
  37        PERF_OUTPUT_CPU             = 1U << 4,
  38        PERF_OUTPUT_EVNAME          = 1U << 5,
  39        PERF_OUTPUT_TRACE           = 1U << 6,
  40        PERF_OUTPUT_IP              = 1U << 7,
  41        PERF_OUTPUT_SYM             = 1U << 8,
  42        PERF_OUTPUT_DSO             = 1U << 9,
  43        PERF_OUTPUT_ADDR            = 1U << 10,
  44        PERF_OUTPUT_SYMOFFSET       = 1U << 11,
  45};
  46
  47struct output_option {
  48        const char *str;
  49        enum perf_output_field field;
  50} all_output_options[] = {
  51        {.str = "comm",  .field = PERF_OUTPUT_COMM},
  52        {.str = "tid",   .field = PERF_OUTPUT_TID},
  53        {.str = "pid",   .field = PERF_OUTPUT_PID},
  54        {.str = "time",  .field = PERF_OUTPUT_TIME},
  55        {.str = "cpu",   .field = PERF_OUTPUT_CPU},
  56        {.str = "event", .field = PERF_OUTPUT_EVNAME},
  57        {.str = "trace", .field = PERF_OUTPUT_TRACE},
  58        {.str = "ip",    .field = PERF_OUTPUT_IP},
  59        {.str = "sym",   .field = PERF_OUTPUT_SYM},
  60        {.str = "dso",   .field = PERF_OUTPUT_DSO},
  61        {.str = "addr",  .field = PERF_OUTPUT_ADDR},
  62        {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
  63};
  64
  65/* default set to maintain compatibility with current format */
  66static struct {
  67        bool user_set;
  68        bool wildcard_set;
  69        unsigned int print_ip_opts;
  70        u64 fields;
  71        u64 invalid_fields;
  72} output[PERF_TYPE_MAX] = {
  73
  74        [PERF_TYPE_HARDWARE] = {
  75                .user_set = false,
  76
  77                .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
  78                              PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
  79                              PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
  80                                  PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
  81
  82                .invalid_fields = PERF_OUTPUT_TRACE,
  83        },
  84
  85        [PERF_TYPE_SOFTWARE] = {
  86                .user_set = false,
  87
  88                .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
  89                              PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
  90                              PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
  91                                  PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
  92
  93                .invalid_fields = PERF_OUTPUT_TRACE,
  94        },
  95
  96        [PERF_TYPE_TRACEPOINT] = {
  97                .user_set = false,
  98
  99                .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
 100                                  PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
 101                                  PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE,
 102        },
 103
 104        [PERF_TYPE_RAW] = {
 105                .user_set = false,
 106
 107                .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
 108                              PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
 109                              PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
 110                                  PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
 111
 112                .invalid_fields = PERF_OUTPUT_TRACE,
 113        },
 114};
 115
 116static bool output_set_by_user(void)
 117{
 118        int j;
 119        for (j = 0; j < PERF_TYPE_MAX; ++j) {
 120                if (output[j].user_set)
 121                        return true;
 122        }
 123        return false;
 124}
 125
 126static const char *output_field2str(enum perf_output_field field)
 127{
 128        int i, imax = ARRAY_SIZE(all_output_options);
 129        const char *str = "";
 130
 131        for (i = 0; i < imax; ++i) {
 132                if (all_output_options[i].field == field) {
 133                        str = all_output_options[i].str;
 134                        break;
 135                }
 136        }
 137        return str;
 138}
 139
 140#define PRINT_FIELD(x)  (output[attr->type].fields & PERF_OUTPUT_##x)
 141
 142static int perf_evsel__check_stype(struct perf_evsel *evsel,
 143                                   u64 sample_type, const char *sample_msg,
 144                                   enum perf_output_field field)
 145{
 146        struct perf_event_attr *attr = &evsel->attr;
 147        int type = attr->type;
 148        const char *evname;
 149
 150        if (attr->sample_type & sample_type)
 151                return 0;
 152
 153        if (output[type].user_set) {
 154                evname = perf_evsel__name(evsel);
 155                pr_err("Samples for '%s' event do not have %s attribute set. "
 156                       "Cannot print '%s' field.\n",
 157                       evname, sample_msg, output_field2str(field));
 158                return -1;
 159        }
 160
 161        /* user did not ask for it explicitly so remove from the default list */
 162        output[type].fields &= ~field;
 163        evname = perf_evsel__name(evsel);
 164        pr_debug("Samples for '%s' event do not have %s attribute set. "
 165                 "Skipping '%s' field.\n",
 166                 evname, sample_msg, output_field2str(field));
 167
 168        return 0;
 169}
 170
 171static int perf_evsel__check_attr(struct perf_evsel *evsel,
 172                                  struct perf_session *session)
 173{
 174        struct perf_event_attr *attr = &evsel->attr;
 175
 176        if (PRINT_FIELD(TRACE) &&
 177                !perf_session__has_traces(session, "record -R"))
 178                return -EINVAL;
 179
 180        if (PRINT_FIELD(IP)) {
 181                if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP",
 182                                            PERF_OUTPUT_IP))
 183                        return -EINVAL;
 184
 185                if (!no_callchain &&
 186                    !(attr->sample_type & PERF_SAMPLE_CALLCHAIN))
 187                        symbol_conf.use_callchain = false;
 188        }
 189
 190        if (PRINT_FIELD(ADDR) &&
 191                perf_evsel__check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR",
 192                                        PERF_OUTPUT_ADDR))
 193                return -EINVAL;
 194
 195        if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
 196                pr_err("Display of symbols requested but neither sample IP nor "
 197                           "sample address\nis selected. Hence, no addresses to convert "
 198                       "to symbols.\n");
 199                return -EINVAL;
 200        }
 201        if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
 202                pr_err("Display of offsets requested but symbol is not"
 203                       "selected.\n");
 204                return -EINVAL;
 205        }
 206        if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
 207                pr_err("Display of DSO requested but neither sample IP nor "
 208                           "sample address\nis selected. Hence, no addresses to convert "
 209                       "to DSO.\n");
 210                return -EINVAL;
 211        }
 212
 213        if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
 214                perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID",
 215                                        PERF_OUTPUT_TID|PERF_OUTPUT_PID))
 216                return -EINVAL;
 217
 218        if (PRINT_FIELD(TIME) &&
 219                perf_evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME",
 220                                        PERF_OUTPUT_TIME))
 221                return -EINVAL;
 222
 223        if (PRINT_FIELD(CPU) &&
 224                perf_evsel__check_stype(evsel, PERF_SAMPLE_CPU, "CPU",
 225                                        PERF_OUTPUT_CPU))
 226                return -EINVAL;
 227
 228        return 0;
 229}
 230
 231/*
 232 * verify all user requested events exist and the samples
 233 * have the expected data
 234 */
 235static int perf_session__check_output_opt(struct perf_session *session)
 236{
 237        int j;
 238        struct perf_evsel *evsel;
 239        struct perf_event_attr *attr;
 240
 241        for (j = 0; j < PERF_TYPE_MAX; ++j) {
 242                evsel = perf_session__find_first_evtype(session, j);
 243
 244                /*
 245                 * even if fields is set to 0 (ie., show nothing) event must
 246                 * exist if user explicitly includes it on the command line
 247                 */
 248                if (!evsel && output[j].user_set && !output[j].wildcard_set) {
 249                        pr_err("%s events do not exist. "
 250                               "Remove corresponding -f option to proceed.\n",
 251                               event_type(j));
 252                        return -1;
 253                }
 254
 255                if (evsel && output[j].fields &&
 256                        perf_evsel__check_attr(evsel, session))
 257                        return -1;
 258
 259                if (evsel == NULL)
 260                        continue;
 261
 262                attr = &evsel->attr;
 263
 264                output[j].print_ip_opts = 0;
 265                if (PRINT_FIELD(IP))
 266                        output[j].print_ip_opts |= PRINT_IP_OPT_IP;
 267
 268                if (PRINT_FIELD(SYM))
 269                        output[j].print_ip_opts |= PRINT_IP_OPT_SYM;
 270
 271                if (PRINT_FIELD(DSO))
 272                        output[j].print_ip_opts |= PRINT_IP_OPT_DSO;
 273
 274                if (PRINT_FIELD(SYMOFFSET))
 275                        output[j].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
 276        }
 277
 278        return 0;
 279}
 280
 281static void print_sample_start(struct perf_sample *sample,
 282                               struct thread *thread,
 283                               struct perf_evsel *evsel)
 284{
 285        struct perf_event_attr *attr = &evsel->attr;
 286        const char *evname = NULL;
 287        unsigned long secs;
 288        unsigned long usecs;
 289        unsigned long long nsecs;
 290
 291        if (PRINT_FIELD(COMM)) {
 292                if (latency_format)
 293                        printf("%8.8s ", thread->comm);
 294                else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
 295                        printf("%s ", thread->comm);
 296                else
 297                        printf("%16s ", thread->comm);
 298        }
 299
 300        if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
 301                printf("%5d/%-5d ", sample->pid, sample->tid);
 302        else if (PRINT_FIELD(PID))
 303                printf("%5d ", sample->pid);
 304        else if (PRINT_FIELD(TID))
 305                printf("%5d ", sample->tid);
 306
 307        if (PRINT_FIELD(CPU)) {
 308                if (latency_format)
 309                        printf("%3d ", sample->cpu);
 310                else
 311                        printf("[%03d] ", sample->cpu);
 312        }
 313
 314        if (PRINT_FIELD(TIME)) {
 315                nsecs = sample->time;
 316                secs = nsecs / NSECS_PER_SEC;
 317                nsecs -= secs * NSECS_PER_SEC;
 318                usecs = nsecs / NSECS_PER_USEC;
 319                printf("%5lu.%06lu: ", secs, usecs);
 320        }
 321
 322        if (PRINT_FIELD(EVNAME)) {
 323                evname = perf_evsel__name(evsel);
 324                printf("%s: ", evname ? evname : "[unknown]");
 325        }
 326}
 327
 328static bool is_bts_event(struct perf_event_attr *attr)
 329{
 330        return ((attr->type == PERF_TYPE_HARDWARE) &&
 331                (attr->config & PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
 332                (attr->sample_period == 1));
 333}
 334
 335static bool sample_addr_correlates_sym(struct perf_event_attr *attr)
 336{
 337        if ((attr->type == PERF_TYPE_SOFTWARE) &&
 338            ((attr->config == PERF_COUNT_SW_PAGE_FAULTS) ||
 339             (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MIN) ||
 340             (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)))
 341                return true;
 342
 343        if (is_bts_event(attr))
 344                return true;
 345
 346        return false;
 347}
 348
 349static void print_sample_addr(union perf_event *event,
 350                          struct perf_sample *sample,
 351                          struct machine *machine,
 352                          struct thread *thread,
 353                          struct perf_event_attr *attr)
 354{
 355        struct addr_location al;
 356        u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 357
 358        printf("%16" PRIx64, sample->addr);
 359
 360        if (!sample_addr_correlates_sym(attr))
 361                return;
 362
 363        thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
 364                              sample->addr, &al);
 365        if (!al.map)
 366                thread__find_addr_map(thread, machine, cpumode, MAP__VARIABLE,
 367                                      sample->addr, &al);
 368
 369        al.cpu = sample->cpu;
 370        al.sym = NULL;
 371
 372        if (al.map)
 373                al.sym = map__find_symbol(al.map, al.addr, NULL);
 374
 375        if (PRINT_FIELD(SYM)) {
 376                printf(" ");
 377                if (PRINT_FIELD(SYMOFFSET))
 378                        symbol__fprintf_symname_offs(al.sym, &al, stdout);
 379                else
 380                        symbol__fprintf_symname(al.sym, stdout);
 381        }
 382
 383        if (PRINT_FIELD(DSO)) {
 384                printf(" (");
 385                map__fprintf_dsoname(al.map, stdout);
 386                printf(")");
 387        }
 388}
 389
 390static void print_sample_bts(union perf_event *event,
 391                             struct perf_sample *sample,
 392                             struct perf_evsel *evsel,
 393                             struct machine *machine,
 394                             struct thread *thread)
 395{
 396        struct perf_event_attr *attr = &evsel->attr;
 397
 398        /* print branch_from information */
 399        if (PRINT_FIELD(IP)) {
 400                if (!symbol_conf.use_callchain)
 401                        printf(" ");
 402                else
 403                        printf("\n");
 404                perf_evsel__print_ip(evsel, event, sample, machine,
 405                                     output[attr->type].print_ip_opts,
 406                                     PERF_MAX_STACK_DEPTH);
 407        }
 408
 409        printf(" => ");
 410
 411        /* print branch_to information */
 412        if (PRINT_FIELD(ADDR))
 413                print_sample_addr(event, sample, machine, thread, attr);
 414
 415        printf("\n");
 416}
 417
 418static void process_event(union perf_event *event, struct perf_sample *sample,
 419                          struct perf_evsel *evsel, struct machine *machine,
 420                          struct thread *thread,
 421                          struct addr_location *al __maybe_unused)
 422{
 423        struct perf_event_attr *attr = &evsel->attr;
 424
 425        if (output[attr->type].fields == 0)
 426                return;
 427
 428        print_sample_start(sample, thread, evsel);
 429
 430        if (is_bts_event(attr)) {
 431                print_sample_bts(event, sample, evsel, machine, thread);
 432                return;
 433        }
 434
 435        if (PRINT_FIELD(TRACE))
 436                event_format__print(evsel->tp_format, sample->cpu,
 437                                    sample->raw_data, sample->raw_size);
 438        if (PRINT_FIELD(ADDR))
 439                print_sample_addr(event, sample, machine, thread, attr);
 440
 441        if (PRINT_FIELD(IP)) {
 442                if (!symbol_conf.use_callchain)
 443                        printf(" ");
 444                else
 445                        printf("\n");
 446
 447                perf_evsel__print_ip(evsel, event, sample, machine,
 448                                     output[attr->type].print_ip_opts,
 449                                     PERF_MAX_STACK_DEPTH);
 450        }
 451
 452        printf("\n");
 453}
 454
 455static int default_start_script(const char *script __maybe_unused,
 456                                int argc __maybe_unused,
 457                                const char **argv __maybe_unused)
 458{
 459        return 0;
 460}
 461
 462static int default_stop_script(void)
 463{
 464        return 0;
 465}
 466
 467static int default_generate_script(struct pevent *pevent __maybe_unused,
 468                                   const char *outfile __maybe_unused)
 469{
 470        return 0;
 471}
 472
 473static struct scripting_ops default_scripting_ops = {
 474        .start_script           = default_start_script,
 475        .stop_script            = default_stop_script,
 476        .process_event          = process_event,
 477        .generate_script        = default_generate_script,
 478};
 479
 480static struct scripting_ops     *scripting_ops;
 481
 482static void setup_scripting(void)
 483{
 484        setup_perl_scripting();
 485        setup_python_scripting();
 486
 487        scripting_ops = &default_scripting_ops;
 488}
 489
 490static int cleanup_scripting(void)
 491{
 492        pr_debug("\nperf script stopped\n");
 493
 494        return scripting_ops->stop_script();
 495}
 496
 497static int process_sample_event(struct perf_tool *tool __maybe_unused,
 498                                union perf_event *event,
 499                                struct perf_sample *sample,
 500                                struct perf_evsel *evsel,
 501                                struct machine *machine)
 502{
 503        struct addr_location al;
 504        struct thread *thread = machine__findnew_thread(machine, sample->pid,
 505                                                        sample->tid);
 506
 507        if (thread == NULL) {
 508                pr_debug("problem processing %d event, skipping it.\n",
 509                         event->header.type);
 510                return -1;
 511        }
 512
 513        if (debug_mode) {
 514                if (sample->time < last_timestamp) {
 515                        pr_err("Samples misordered, previous: %" PRIu64
 516                                " this: %" PRIu64 "\n", last_timestamp,
 517                                sample->time);
 518                        nr_unordered++;
 519                }
 520                last_timestamp = sample->time;
 521                return 0;
 522        }
 523
 524        if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
 525                pr_err("problem processing %d event, skipping it.\n",
 526                       event->header.type);
 527                return -1;
 528        }
 529
 530        if (al.filtered)
 531                return 0;
 532
 533        if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
 534                return 0;
 535
 536        scripting_ops->process_event(event, sample, evsel, machine, thread, &al);
 537
 538        evsel->hists.stats.total_period += sample->period;
 539        return 0;
 540}
 541
 542static struct perf_tool perf_script = {
 543        .sample          = process_sample_event,
 544        .mmap            = perf_event__process_mmap,
 545        .mmap2           = perf_event__process_mmap2,
 546        .comm            = perf_event__process_comm,
 547        .exit            = perf_event__process_exit,
 548        .fork            = perf_event__process_fork,
 549        .attr            = perf_event__process_attr,
 550        .tracing_data    = perf_event__process_tracing_data,
 551        .build_id        = perf_event__process_build_id,
 552        .ordered_samples = true,
 553        .ordering_requires_timestamps = true,
 554};
 555
 556static void sig_handler(int sig __maybe_unused)
 557{
 558        session_done = 1;
 559}
 560
 561static int __cmd_script(struct perf_session *session)
 562{
 563        int ret;
 564
 565        signal(SIGINT, sig_handler);
 566
 567        ret = perf_session__process_events(session, &perf_script);
 568
 569        if (debug_mode)
 570                pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
 571
 572        return ret;
 573}
 574
 575struct script_spec {
 576        struct list_head        node;
 577        struct scripting_ops    *ops;
 578        char                    spec[0];
 579};
 580
 581static LIST_HEAD(script_specs);
 582
 583static struct script_spec *script_spec__new(const char *spec,
 584                                            struct scripting_ops *ops)
 585{
 586        struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
 587
 588        if (s != NULL) {
 589                strcpy(s->spec, spec);
 590                s->ops = ops;
 591        }
 592
 593        return s;
 594}
 595
 596static void script_spec__add(struct script_spec *s)
 597{
 598        list_add_tail(&s->node, &script_specs);
 599}
 600
 601static struct script_spec *script_spec__find(const char *spec)
 602{
 603        struct script_spec *s;
 604
 605        list_for_each_entry(s, &script_specs, node)
 606                if (strcasecmp(s->spec, spec) == 0)
 607                        return s;
 608        return NULL;
 609}
 610
 611static struct script_spec *script_spec__findnew(const char *spec,
 612                                                struct scripting_ops *ops)
 613{
 614        struct script_spec *s = script_spec__find(spec);
 615
 616        if (s)
 617                return s;
 618
 619        s = script_spec__new(spec, ops);
 620        if (!s)
 621                return NULL;
 622
 623        script_spec__add(s);
 624
 625        return s;
 626}
 627
 628int script_spec_register(const char *spec, struct scripting_ops *ops)
 629{
 630        struct script_spec *s;
 631
 632        s = script_spec__find(spec);
 633        if (s)
 634                return -1;
 635
 636        s = script_spec__findnew(spec, ops);
 637        if (!s)
 638                return -1;
 639
 640        return 0;
 641}
 642
 643static struct scripting_ops *script_spec__lookup(const char *spec)
 644{
 645        struct script_spec *s = script_spec__find(spec);
 646        if (!s)
 647                return NULL;
 648
 649        return s->ops;
 650}
 651
 652static void list_available_languages(void)
 653{
 654        struct script_spec *s;
 655
 656        fprintf(stderr, "\n");
 657        fprintf(stderr, "Scripting language extensions (used in "
 658                "perf script -s [spec:]script.[spec]):\n\n");
 659
 660        list_for_each_entry(s, &script_specs, node)
 661                fprintf(stderr, "  %-42s [%s]\n", s->spec, s->ops->name);
 662
 663        fprintf(stderr, "\n");
 664}
 665
 666static int parse_scriptname(const struct option *opt __maybe_unused,
 667                            const char *str, int unset __maybe_unused)
 668{
 669        char spec[PATH_MAX];
 670        const char *script, *ext;
 671        int len;
 672
 673        if (strcmp(str, "lang") == 0) {
 674                list_available_languages();
 675                exit(0);
 676        }
 677
 678        script = strchr(str, ':');
 679        if (script) {
 680                len = script - str;
 681                if (len >= PATH_MAX) {
 682                        fprintf(stderr, "invalid language specifier");
 683                        return -1;
 684                }
 685                strncpy(spec, str, len);
 686                spec[len] = '\0';
 687                scripting_ops = script_spec__lookup(spec);
 688                if (!scripting_ops) {
 689                        fprintf(stderr, "invalid language specifier");
 690                        return -1;
 691                }
 692                script++;
 693        } else {
 694                script = str;
 695                ext = strrchr(script, '.');
 696                if (!ext) {
 697                        fprintf(stderr, "invalid script extension");
 698                        return -1;
 699                }
 700                scripting_ops = script_spec__lookup(++ext);
 701                if (!scripting_ops) {
 702                        fprintf(stderr, "invalid script extension");
 703                        return -1;
 704                }
 705        }
 706
 707        script_name = strdup(script);
 708
 709        return 0;
 710}
 711
 712static int parse_output_fields(const struct option *opt __maybe_unused,
 713                            const char *arg, int unset __maybe_unused)
 714{
 715        char *tok;
 716        int i, imax = ARRAY_SIZE(all_output_options);
 717        int j;
 718        int rc = 0;
 719        char *str = strdup(arg);
 720        int type = -1;
 721
 722        if (!str)
 723                return -ENOMEM;
 724
 725        /* first word can state for which event type the user is specifying
 726         * the fields. If no type exists, the specified fields apply to all
 727         * event types found in the file minus the invalid fields for a type.
 728         */
 729        tok = strchr(str, ':');
 730        if (tok) {
 731                *tok = '\0';
 732                tok++;
 733                if (!strcmp(str, "hw"))
 734                        type = PERF_TYPE_HARDWARE;
 735                else if (!strcmp(str, "sw"))
 736                        type = PERF_TYPE_SOFTWARE;
 737                else if (!strcmp(str, "trace"))
 738                        type = PERF_TYPE_TRACEPOINT;
 739                else if (!strcmp(str, "raw"))
 740                        type = PERF_TYPE_RAW;
 741                else {
 742                        fprintf(stderr, "Invalid event type in field string.\n");
 743                        rc = -EINVAL;
 744                        goto out;
 745                }
 746
 747                if (output[type].user_set)
 748                        pr_warning("Overriding previous field request for %s events.\n",
 749                                   event_type(type));
 750
 751                output[type].fields = 0;
 752                output[type].user_set = true;
 753                output[type].wildcard_set = false;
 754
 755        } else {
 756                tok = str;
 757                if (strlen(str) == 0) {
 758                        fprintf(stderr,
 759                                "Cannot set fields to 'none' for all event types.\n");
 760                        rc = -EINVAL;
 761                        goto out;
 762                }
 763
 764                if (output_set_by_user())
 765                        pr_warning("Overriding previous field request for all events.\n");
 766
 767                for (j = 0; j < PERF_TYPE_MAX; ++j) {
 768                        output[j].fields = 0;
 769                        output[j].user_set = true;
 770                        output[j].wildcard_set = true;
 771                }
 772        }
 773
 774        tok = strtok(tok, ",");
 775        while (tok) {
 776                for (i = 0; i < imax; ++i) {
 777                        if (strcmp(tok, all_output_options[i].str) == 0)
 778                                break;
 779                }
 780                if (i == imax) {
 781                        fprintf(stderr, "Invalid field requested.\n");
 782                        rc = -EINVAL;
 783                        goto out;
 784                }
 785
 786                if (type == -1) {
 787                        /* add user option to all events types for
 788                         * which it is valid
 789                         */
 790                        for (j = 0; j < PERF_TYPE_MAX; ++j) {
 791                                if (output[j].invalid_fields & all_output_options[i].field) {
 792                                        pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
 793                                                   all_output_options[i].str, event_type(j));
 794                                } else
 795                                        output[j].fields |= all_output_options[i].field;
 796                        }
 797                } else {
 798                        if (output[type].invalid_fields & all_output_options[i].field) {
 799                                fprintf(stderr, "\'%s\' not valid for %s events.\n",
 800                                         all_output_options[i].str, event_type(type));
 801
 802                                rc = -EINVAL;
 803                                goto out;
 804                        }
 805                        output[type].fields |= all_output_options[i].field;
 806                }
 807
 808                tok = strtok(NULL, ",");
 809        }
 810
 811        if (type >= 0) {
 812                if (output[type].fields == 0) {
 813                        pr_debug("No fields requested for %s type. "
 814                                 "Events will not be displayed.\n", event_type(type));
 815                }
 816        }
 817
 818out:
 819        free(str);
 820        return rc;
 821}
 822
 823/* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */
 824static int is_directory(const char *base_path, const struct dirent *dent)
 825{
 826        char path[PATH_MAX];
 827        struct stat st;
 828
 829        sprintf(path, "%s/%s", base_path, dent->d_name);
 830        if (stat(path, &st))
 831                return 0;
 832
 833        return S_ISDIR(st.st_mode);
 834}
 835
 836#define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\
 837        while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) &&     \
 838               lang_next)                                               \
 839                if ((lang_dirent.d_type == DT_DIR ||                    \
 840                     (lang_dirent.d_type == DT_UNKNOWN &&               \
 841                      is_directory(scripts_path, &lang_dirent))) &&     \
 842                    (strcmp(lang_dirent.d_name, ".")) &&                \
 843                    (strcmp(lang_dirent.d_name, "..")))
 844
 845#define for_each_script(lang_path, lang_dir, script_dirent, script_next)\
 846        while (!readdir_r(lang_dir, &script_dirent, &script_next) &&    \
 847               script_next)                                             \
 848                if (script_dirent.d_type != DT_DIR &&                   \
 849                    (script_dirent.d_type != DT_UNKNOWN ||              \
 850                     !is_directory(lang_path, &script_dirent)))
 851
 852
 853#define RECORD_SUFFIX                   "-record"
 854#define REPORT_SUFFIX                   "-report"
 855
 856struct script_desc {
 857        struct list_head        node;
 858        char                    *name;
 859        char                    *half_liner;
 860        char                    *args;
 861};
 862
 863static LIST_HEAD(script_descs);
 864
 865static struct script_desc *script_desc__new(const char *name)
 866{
 867        struct script_desc *s = zalloc(sizeof(*s));
 868
 869        if (s != NULL && name)
 870                s->name = strdup(name);
 871
 872        return s;
 873}
 874
 875static void script_desc__delete(struct script_desc *s)
 876{
 877        free(s->name);
 878        free(s->half_liner);
 879        free(s->args);
 880        free(s);
 881}
 882
 883static void script_desc__add(struct script_desc *s)
 884{
 885        list_add_tail(&s->node, &script_descs);
 886}
 887
 888static struct script_desc *script_desc__find(const char *name)
 889{
 890        struct script_desc *s;
 891
 892        list_for_each_entry(s, &script_descs, node)
 893                if (strcasecmp(s->name, name) == 0)
 894                        return s;
 895        return NULL;
 896}
 897
 898static struct script_desc *script_desc__findnew(const char *name)
 899{
 900        struct script_desc *s = script_desc__find(name);
 901
 902        if (s)
 903                return s;
 904
 905        s = script_desc__new(name);
 906        if (!s)
 907                goto out_delete_desc;
 908
 909        script_desc__add(s);
 910
 911        return s;
 912
 913out_delete_desc:
 914        script_desc__delete(s);
 915
 916        return NULL;
 917}
 918
 919static const char *ends_with(const char *str, const char *suffix)
 920{
 921        size_t suffix_len = strlen(suffix);
 922        const char *p = str;
 923
 924        if (strlen(str) > suffix_len) {
 925                p = str + strlen(str) - suffix_len;
 926                if (!strncmp(p, suffix, suffix_len))
 927                        return p;
 928        }
 929
 930        return NULL;
 931}
 932
 933static int read_script_info(struct script_desc *desc, const char *filename)
 934{
 935        char line[BUFSIZ], *p;
 936        FILE *fp;
 937
 938        fp = fopen(filename, "r");
 939        if (!fp)
 940                return -1;
 941
 942        while (fgets(line, sizeof(line), fp)) {
 943                p = ltrim(line);
 944                if (strlen(p) == 0)
 945                        continue;
 946                if (*p != '#')
 947                        continue;
 948                p++;
 949                if (strlen(p) && *p == '!')
 950                        continue;
 951
 952                p = ltrim(p);
 953                if (strlen(p) && p[strlen(p) - 1] == '\n')
 954                        p[strlen(p) - 1] = '\0';
 955
 956                if (!strncmp(p, "description:", strlen("description:"))) {
 957                        p += strlen("description:");
 958                        desc->half_liner = strdup(ltrim(p));
 959                        continue;
 960                }
 961
 962                if (!strncmp(p, "args:", strlen("args:"))) {
 963                        p += strlen("args:");
 964                        desc->args = strdup(ltrim(p));
 965                        continue;
 966                }
 967        }
 968
 969        fclose(fp);
 970
 971        return 0;
 972}
 973
 974static char *get_script_root(struct dirent *script_dirent, const char *suffix)
 975{
 976        char *script_root, *str;
 977
 978        script_root = strdup(script_dirent->d_name);
 979        if (!script_root)
 980                return NULL;
 981
 982        str = (char *)ends_with(script_root, suffix);
 983        if (!str) {
 984                free(script_root);
 985                return NULL;
 986        }
 987
 988        *str = '\0';
 989        return script_root;
 990}
 991
 992static int list_available_scripts(const struct option *opt __maybe_unused,
 993                                  const char *s __maybe_unused,
 994                                  int unset __maybe_unused)
 995{
 996        struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
 997        char scripts_path[MAXPATHLEN];
 998        DIR *scripts_dir, *lang_dir;
 999        char script_path[MAXPATHLEN];
1000        char lang_path[MAXPATHLEN];
1001        struct script_desc *desc;
1002        char first_half[BUFSIZ];
1003        char *script_root;
1004
1005        snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
1006
1007        scripts_dir = opendir(scripts_path);
1008        if (!scripts_dir)
1009                return -1;
1010
1011        for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
1012                snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
1013                         lang_dirent.d_name);
1014                lang_dir = opendir(lang_path);
1015                if (!lang_dir)
1016                        continue;
1017
1018                for_each_script(lang_path, lang_dir, script_dirent, script_next) {
1019                        script_root = get_script_root(&script_dirent, REPORT_SUFFIX);
1020                        if (script_root) {
1021                                desc = script_desc__findnew(script_root);
1022                                snprintf(script_path, MAXPATHLEN, "%s/%s",
1023                                         lang_path, script_dirent.d_name);
1024                                read_script_info(desc, script_path);
1025                                free(script_root);
1026                        }
1027                }
1028        }
1029
1030        fprintf(stdout, "List of available trace scripts:\n");
1031        list_for_each_entry(desc, &script_descs, node) {
1032                sprintf(first_half, "%s %s", desc->name,
1033                        desc->args ? desc->args : "");
1034                fprintf(stdout, "  %-36s %s\n", first_half,
1035                        desc->half_liner ? desc->half_liner : "");
1036        }
1037
1038        exit(0);
1039}
1040
1041/*
1042 * Some scripts specify the required events in their "xxx-record" file,
1043 * this function will check if the events in perf.data match those
1044 * mentioned in the "xxx-record".
1045 *
1046 * Fixme: All existing "xxx-record" are all in good formats "-e event ",
1047 * which is covered well now. And new parsing code should be added to
1048 * cover the future complexing formats like event groups etc.
1049 */
1050static int check_ev_match(char *dir_name, char *scriptname,
1051                        struct perf_session *session)
1052{
1053        char filename[MAXPATHLEN], evname[128];
1054        char line[BUFSIZ], *p;
1055        struct perf_evsel *pos;
1056        int match, len;
1057        FILE *fp;
1058
1059        sprintf(filename, "%s/bin/%s-record", dir_name, scriptname);
1060
1061        fp = fopen(filename, "r");
1062        if (!fp)
1063                return -1;
1064
1065        while (fgets(line, sizeof(line), fp)) {
1066                p = ltrim(line);
1067                if (*p == '#')
1068                        continue;
1069
1070                while (strlen(p)) {
1071                        p = strstr(p, "-e");
1072                        if (!p)
1073                                break;
1074
1075                        p += 2;
1076                        p = ltrim(p);
1077                        len = strcspn(p, " \t");
1078                        if (!len)
1079                                break;
1080
1081                        snprintf(evname, len + 1, "%s", p);
1082
1083                        match = 0;
1084                        list_for_each_entry(pos,
1085                                        &session->evlist->entries, node) {
1086                                if (!strcmp(perf_evsel__name(pos), evname)) {
1087                                        match = 1;
1088                                        break;
1089                                }
1090                        }
1091
1092                        if (!match) {
1093                                fclose(fp);
1094                                return -1;
1095                        }
1096                }
1097        }
1098
1099        fclose(fp);
1100        return 0;
1101}
1102
1103/*
1104 * Return -1 if none is found, otherwise the actual scripts number.
1105 *
1106 * Currently the only user of this function is the script browser, which
1107 * will list all statically runnable scripts, select one, execute it and
1108 * show the output in a perf browser.
1109 */
1110int find_scripts(char **scripts_array, char **scripts_path_array)
1111{
1112        struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
1113        char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
1114        DIR *scripts_dir, *lang_dir;
1115        struct perf_session *session;
1116        char *temp;
1117        int i = 0;
1118
1119        session = perf_session__new(input_name, O_RDONLY, 0, false, NULL);
1120        if (!session)
1121                return -1;
1122
1123        snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
1124
1125        scripts_dir = opendir(scripts_path);
1126        if (!scripts_dir) {
1127                perf_session__delete(session);
1128                return -1;
1129        }
1130
1131        for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
1132                snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
1133                         lang_dirent.d_name);
1134#ifdef NO_LIBPERL
1135                if (strstr(lang_path, "perl"))
1136                        continue;
1137#endif
1138#ifdef NO_LIBPYTHON
1139                if (strstr(lang_path, "python"))
1140                        continue;
1141#endif
1142
1143                lang_dir = opendir(lang_path);
1144                if (!lang_dir)
1145                        continue;
1146
1147                for_each_script(lang_path, lang_dir, script_dirent, script_next) {
1148                        /* Skip those real time scripts: xxxtop.p[yl] */
1149                        if (strstr(script_dirent.d_name, "top."))
1150                                continue;
1151                        sprintf(scripts_path_array[i], "%s/%s", lang_path,
1152                                script_dirent.d_name);
1153                        temp = strchr(script_dirent.d_name, '.');
1154                        snprintf(scripts_array[i],
1155                                (temp - script_dirent.d_name) + 1,
1156                                "%s", script_dirent.d_name);
1157
1158                        if (check_ev_match(lang_path,
1159                                        scripts_array[i], session))
1160                                continue;
1161
1162                        i++;
1163                }
1164                closedir(lang_dir);
1165        }
1166
1167        closedir(scripts_dir);
1168        perf_session__delete(session);
1169        return i;
1170}
1171
1172static char *get_script_path(const char *script_root, const char *suffix)
1173{
1174        struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
1175        char scripts_path[MAXPATHLEN];
1176        char script_path[MAXPATHLEN];
1177        DIR *scripts_dir, *lang_dir;
1178        char lang_path[MAXPATHLEN];
1179        char *__script_root;
1180
1181        snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
1182
1183        scripts_dir = opendir(scripts_path);
1184        if (!scripts_dir)
1185                return NULL;
1186
1187        for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
1188                snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
1189                         lang_dirent.d_name);
1190                lang_dir = opendir(lang_path);
1191                if (!lang_dir)
1192                        continue;
1193
1194                for_each_script(lang_path, lang_dir, script_dirent, script_next) {
1195                        __script_root = get_script_root(&script_dirent, suffix);
1196                        if (__script_root && !strcmp(script_root, __script_root)) {
1197                                free(__script_root);
1198                                closedir(lang_dir);
1199                                closedir(scripts_dir);
1200                                snprintf(script_path, MAXPATHLEN, "%s/%s",
1201                                         lang_path, script_dirent.d_name);
1202                                return strdup(script_path);
1203                        }
1204                        free(__script_root);
1205                }
1206                closedir(lang_dir);
1207        }
1208        closedir(scripts_dir);
1209
1210        return NULL;
1211}
1212
1213static bool is_top_script(const char *script_path)
1214{
1215        return ends_with(script_path, "top") == NULL ? false : true;
1216}
1217
1218static int has_required_arg(char *script_path)
1219{
1220        struct script_desc *desc;
1221        int n_args = 0;
1222        char *p;
1223
1224        desc = script_desc__new(NULL);
1225
1226        if (read_script_info(desc, script_path))
1227                goto out;
1228
1229        if (!desc->args)
1230                goto out;
1231
1232        for (p = desc->args; *p; p++)
1233                if (*p == '<')
1234                        n_args++;
1235out:
1236        script_desc__delete(desc);
1237
1238        return n_args;
1239}
1240
1241static int have_cmd(int argc, const char **argv)
1242{
1243        char **__argv = malloc(sizeof(const char *) * argc);
1244
1245        if (!__argv) {
1246                pr_err("malloc failed\n");
1247                return -1;
1248        }
1249
1250        memcpy(__argv, argv, sizeof(const char *) * argc);
1251        argc = parse_options(argc, (const char **)__argv, record_options,
1252                             NULL, PARSE_OPT_STOP_AT_NON_OPTION);
1253        free(__argv);
1254
1255        system_wide = (argc == 0);
1256
1257        return 0;
1258}
1259
1260int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1261{
1262        bool show_full_info = false;
1263        char *rec_script_path = NULL;
1264        char *rep_script_path = NULL;
1265        struct perf_session *session;
1266        char *script_path = NULL;
1267        const char **__argv;
1268        int i, j, err;
1269        const struct option options[] = {
1270        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1271                    "dump raw trace in ASCII"),
1272        OPT_INCR('v', "verbose", &verbose,
1273                 "be more verbose (show symbol address, etc)"),
1274        OPT_BOOLEAN('L', "Latency", &latency_format,
1275                    "show latency attributes (irqs/preemption disabled, etc)"),
1276        OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
1277                           list_available_scripts),
1278        OPT_CALLBACK('s', "script", NULL, "name",
1279                     "script file name (lang:script name, script name, or *)",
1280                     parse_scriptname),
1281        OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
1282                   "generate perf-script.xx script in specified language"),
1283        OPT_STRING('i', "input", &input_name, "file", "input file name"),
1284        OPT_BOOLEAN('d', "debug-mode", &debug_mode,
1285                   "do various checks like samples ordering and lost events"),
1286        OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
1287                   "file", "vmlinux pathname"),
1288        OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
1289                   "file", "kallsyms pathname"),
1290        OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
1291                    "When printing symbols do not display call chain"),
1292        OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
1293                    "Look for files with symbols relative to this directory"),
1294        OPT_CALLBACK('f', "fields", NULL, "str",
1295                     "comma separated output fields prepend with 'type:'. "
1296                     "Valid types: hw,sw,trace,raw. "
1297                     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
1298                     "addr,symoff", parse_output_fields),
1299        OPT_BOOLEAN('a', "all-cpus", &system_wide,
1300                    "system-wide collection from all CPUs"),
1301        OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
1302                   "only consider these symbols"),
1303        OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
1304        OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
1305                   "only display events for these comms"),
1306        OPT_BOOLEAN('I', "show-info", &show_full_info,
1307                    "display extended information from perf.data file"),
1308        OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
1309                    "Show the path of [kernel.kallsyms]"),
1310        OPT_END()
1311        };
1312        const char * const script_usage[] = {
1313                "perf script [<options>]",
1314                "perf script [<options>] record <script> [<record-options>] <command>",
1315                "perf script [<options>] report <script> [script-args]",
1316                "perf script [<options>] <script> [<record-options>] <command>",
1317                "perf script [<options>] <top-script> [script-args]",
1318                NULL
1319        };
1320
1321        setup_scripting();
1322
1323        argc = parse_options(argc, argv, options, script_usage,
1324                             PARSE_OPT_STOP_AT_NON_OPTION);
1325
1326        if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
1327                rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
1328                if (!rec_script_path)
1329                        return cmd_record(argc, argv, NULL);
1330        }
1331
1332        if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
1333                rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
1334                if (!rep_script_path) {
1335                        fprintf(stderr,
1336                                "Please specify a valid report script"
1337                                "(see 'perf script -l' for listing)\n");
1338                        return -1;
1339                }
1340        }
1341
1342        /* make sure PERF_EXEC_PATH is set for scripts */
1343        perf_set_argv_exec_path(perf_exec_path());
1344
1345        if (argc && !script_name && !rec_script_path && !rep_script_path) {
1346                int live_pipe[2];
1347                int rep_args;
1348                pid_t pid;
1349
1350                rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);
1351                rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
1352
1353                if (!rec_script_path && !rep_script_path) {
1354                        fprintf(stderr, " Couldn't find script %s\n\n See perf"
1355                                " script -l for available scripts.\n", argv[0]);
1356                        usage_with_options(script_usage, options);
1357                }
1358
1359                if (is_top_script(argv[0])) {
1360                        rep_args = argc - 1;
1361                } else {
1362                        int rec_args;
1363
1364                        rep_args = has_required_arg(rep_script_path);
1365                        rec_args = (argc - 1) - rep_args;
1366                        if (rec_args < 0) {
1367                                fprintf(stderr, " %s script requires options."
1368                                        "\n\n See perf script -l for available "
1369                                        "scripts and options.\n", argv[0]);
1370                                usage_with_options(script_usage, options);
1371                        }
1372                }
1373
1374                if (pipe(live_pipe) < 0) {
1375                        perror("failed to create pipe");
1376                        return -1;
1377                }
1378
1379                pid = fork();
1380                if (pid < 0) {
1381                        perror("failed to fork");
1382                        return -1;
1383                }
1384
1385                if (!pid) {
1386                        j = 0;
1387
1388                        dup2(live_pipe[1], 1);
1389                        close(live_pipe[0]);
1390
1391                        if (is_top_script(argv[0])) {
1392                                system_wide = true;
1393                        } else if (!system_wide) {
1394                                if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
1395                                        err = -1;
1396                                        goto out;
1397                                }
1398                        }
1399
1400                        __argv = malloc((argc + 6) * sizeof(const char *));
1401                        if (!__argv) {
1402                                pr_err("malloc failed\n");
1403                                err = -ENOMEM;
1404                                goto out;
1405                        }
1406
1407                        __argv[j++] = "/bin/sh";
1408                        __argv[j++] = rec_script_path;
1409                        if (system_wide)
1410                                __argv[j++] = "-a";
1411                        __argv[j++] = "-q";
1412                        __argv[j++] = "-o";
1413                        __argv[j++] = "-";
1414                        for (i = rep_args + 1; i < argc; i++)
1415                                __argv[j++] = argv[i];
1416                        __argv[j++] = NULL;
1417
1418                        execvp("/bin/sh", (char **)__argv);
1419                        free(__argv);
1420                        exit(-1);
1421                }
1422
1423                dup2(live_pipe[0], 0);
1424                close(live_pipe[1]);
1425
1426                __argv = malloc((argc + 4) * sizeof(const char *));
1427                if (!__argv) {
1428                        pr_err("malloc failed\n");
1429                        err = -ENOMEM;
1430                        goto out;
1431                }
1432
1433                j = 0;
1434                __argv[j++] = "/bin/sh";
1435                __argv[j++] = rep_script_path;
1436                for (i = 1; i < rep_args + 1; i++)
1437                        __argv[j++] = argv[i];
1438                __argv[j++] = "-i";
1439                __argv[j++] = "-";
1440                __argv[j++] = NULL;
1441
1442                execvp("/bin/sh", (char **)__argv);
1443                free(__argv);
1444                exit(-1);
1445        }
1446
1447        if (rec_script_path)
1448                script_path = rec_script_path;
1449        if (rep_script_path)
1450                script_path = rep_script_path;
1451
1452        if (script_path) {
1453                j = 0;
1454
1455                if (!rec_script_path)
1456                        system_wide = false;
1457                else if (!system_wide) {
1458                        if (have_cmd(argc - 1, &argv[1]) != 0) {
1459                                err = -1;
1460                                goto out;
1461                        }
1462                }
1463
1464                __argv = malloc((argc + 2) * sizeof(const char *));
1465                if (!__argv) {
1466                        pr_err("malloc failed\n");
1467                        err = -ENOMEM;
1468                        goto out;
1469                }
1470
1471                __argv[j++] = "/bin/sh";
1472                __argv[j++] = script_path;
1473                if (system_wide)
1474                        __argv[j++] = "-a";
1475                for (i = 2; i < argc; i++)
1476                        __argv[j++] = argv[i];
1477                __argv[j++] = NULL;
1478
1479                execvp("/bin/sh", (char **)__argv);
1480                free(__argv);
1481                exit(-1);
1482        }
1483
1484        if (symbol__init() < 0)
1485                return -1;
1486        if (!script_name)
1487                setup_pager();
1488
1489        session = perf_session__new(input_name, O_RDONLY, 0, false,
1490                                    &perf_script);
1491        if (session == NULL)
1492                return -ENOMEM;
1493
1494        if (cpu_list) {
1495                if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
1496                        return -1;
1497        }
1498
1499        if (!script_name && !generate_script_lang)
1500                perf_session__fprintf_info(session, stdout, show_full_info);
1501
1502        if (!no_callchain)
1503                symbol_conf.use_callchain = true;
1504        else
1505                symbol_conf.use_callchain = false;
1506
1507        if (generate_script_lang) {
1508                struct stat perf_stat;
1509                int input;
1510
1511                if (output_set_by_user()) {
1512                        fprintf(stderr,
1513                                "custom fields not supported for generated scripts");
1514                        return -1;
1515                }
1516
1517                input = open(session->filename, O_RDONLY);      /* input_name */
1518                if (input < 0) {
1519                        perror("failed to open file");
1520                        return -1;
1521                }
1522
1523                err = fstat(input, &perf_stat);
1524                if (err < 0) {
1525                        perror("failed to stat file");
1526                        return -1;
1527                }
1528
1529                if (!perf_stat.st_size) {
1530                        fprintf(stderr, "zero-sized file, nothing to do!\n");
1531                        return 0;
1532                }
1533
1534                scripting_ops = script_spec__lookup(generate_script_lang);
1535                if (!scripting_ops) {
1536                        fprintf(stderr, "invalid language specifier");
1537                        return -1;
1538                }
1539
1540                err = scripting_ops->generate_script(session->pevent,
1541                                                     "perf-script");
1542                goto out;
1543        }
1544
1545        if (script_name) {
1546                err = scripting_ops->start_script(script_name, argc, argv);
1547                if (err)
1548                        goto out;
1549                pr_debug("perf script started with script %s\n\n", script_name);
1550        }
1551
1552
1553        err = perf_session__check_output_opt(session);
1554        if (err < 0)
1555                goto out;
1556
1557        err = __cmd_script(session);
1558
1559        perf_session__delete(session);
1560        cleanup_scripting();
1561out:
1562        return err;
1563}
1564