perf top: Fix a memory leak
[deliverable/linux.git] / tools / perf / builtin-script.c
index 5f8afc65d5f3adb311c01b379b253de8abb03e65..3d4c0c7b576e309272f7a7371d625b03eaeb228c 100644 (file)
@@ -24,6 +24,7 @@ static u64                    nr_unordered;
 extern const struct option     record_options[];
 static bool                    no_callchain;
 static bool                    show_full_info;
+static bool                    system_wide;
 static const char              *cpu_list;
 static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
 
@@ -433,7 +434,7 @@ static int cleanup_scripting(void)
        return scripting_ops->stop_script();
 }
 
-static char const              *input_name = "perf.data";
+static const char *input_name;
 
 static int process_sample_event(struct perf_tool *tool __used,
                                union perf_event *event,
@@ -441,7 +442,8 @@ static int process_sample_event(struct perf_tool *tool __used,
                                struct perf_evsel *evsel,
                                struct machine *machine)
 {
-       struct thread *thread = machine__findnew_thread(machine, event->ip.pid);
+       struct addr_location al;
+       struct thread *thread = machine__findnew_thread(machine, event->ip.tid);
 
        if (thread == NULL) {
                pr_debug("problem processing %d event, skipping it.\n",
@@ -460,6 +462,15 @@ static int process_sample_event(struct perf_tool *tool __used,
                return 0;
        }
 
+       if (perf_event__preprocess_sample(event, machine, &al, sample, 0) < 0) {
+               pr_err("problem processing %d event, skipping it.\n",
+                      event->header.type);
+               return -1;
+       }
+
+       if (al.filtered)
+               return 0;
+
        if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
                return 0;
 
@@ -683,7 +694,8 @@ static int parse_output_fields(const struct option *opt __used,
                        type = PERF_TYPE_RAW;
                else {
                        fprintf(stderr, "Invalid event type in field string.\n");
-                       return -EINVAL;
+                       rc = -EINVAL;
+                       goto out;
                }
 
                if (output[type].user_set)
@@ -925,6 +937,24 @@ static int read_script_info(struct script_desc *desc, const char *filename)
        return 0;
 }
 
+static char *get_script_root(struct dirent *script_dirent, const char *suffix)
+{
+       char *script_root, *str;
+
+       script_root = strdup(script_dirent->d_name);
+       if (!script_root)
+               return NULL;
+
+       str = (char *)ends_with(script_root, suffix);
+       if (!str) {
+               free(script_root);
+               return NULL;
+       }
+
+       *str = '\0';
+       return script_root;
+}
+
 static int list_available_scripts(const struct option *opt __used,
                                  const char *s __used, int unset __used)
 {
@@ -936,7 +966,6 @@ static int list_available_scripts(const struct option *opt __used,
        struct script_desc *desc;
        char first_half[BUFSIZ];
        char *script_root;
-       char *str;
 
        snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
 
@@ -952,16 +981,14 @@ static int list_available_scripts(const struct option *opt __used,
                        continue;
 
                for_each_script(lang_path, lang_dir, script_dirent, script_next) {
-                       script_root = strdup(script_dirent.d_name);
-                       str = (char *)ends_with(script_root, REPORT_SUFFIX);
-                       if (str) {
-                               *str = '\0';
+                       script_root = get_script_root(&script_dirent, REPORT_SUFFIX);
+                       if (script_root) {
                                desc = script_desc__findnew(script_root);
                                snprintf(script_path, MAXPATHLEN, "%s/%s",
                                         lang_path, script_dirent.d_name);
                                read_script_info(desc, script_path);
+                               free(script_root);
                        }
-                       free(script_root);
                }
        }
 
@@ -983,8 +1010,7 @@ static char *get_script_path(const char *script_root, const char *suffix)
        char script_path[MAXPATHLEN];
        DIR *scripts_dir, *lang_dir;
        char lang_path[MAXPATHLEN];
-       char *str, *__script_root;
-       char *path = NULL;
+       char *__script_root;
 
        snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
 
@@ -1000,23 +1026,18 @@ static char *get_script_path(const char *script_root, const char *suffix)
                        continue;
 
                for_each_script(lang_path, lang_dir, script_dirent, script_next) {
-                       __script_root = strdup(script_dirent.d_name);
-                       str = (char *)ends_with(__script_root, suffix);
-                       if (str) {
-                               *str = '\0';
-                               if (strcmp(__script_root, script_root))
-                                       continue;
+                       __script_root = get_script_root(&script_dirent, suffix);
+                       if (__script_root && !strcmp(script_root, __script_root)) {
+                               free(__script_root);
                                snprintf(script_path, MAXPATHLEN, "%s/%s",
                                         lang_path, script_dirent.d_name);
-                               path = strdup(script_path);
-                               free(__script_root);
-                               break;
+                               return strdup(script_path);
                        }
                        free(__script_root);
                }
        }
 
-       return path;
+       return NULL;
 }
 
 static bool is_top_script(const char *script_path)
@@ -1085,7 +1106,11 @@ static const struct option options[] = {
        OPT_CALLBACK('f', "fields", NULL, "str",
                     "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr",
                     parse_output_fields),
-       OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
+       OPT_BOOLEAN('a', "all-cpus", &system_wide,
+                    "system-wide collection from all CPUs"),
+       OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
+       OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
+                  "only display events for these comms"),
        OPT_BOOLEAN('I', "show-info", &show_full_info,
                    "display extended information from perf.data file"),
        OPT_END()
@@ -1112,7 +1137,6 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
        struct perf_session *session;
        char *script_path = NULL;
        const char **__argv;
-       bool system_wide;
        int i, j, err;
 
        setup_scripting();
@@ -1180,15 +1204,17 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
                }
 
                if (!pid) {
-                       system_wide = true;
                        j = 0;
 
                        dup2(live_pipe[1], 1);
                        close(live_pipe[0]);
 
-                       if (!is_top_script(argv[0]))
+                       if (is_top_script(argv[0])) {
+                               system_wide = true;
+                       } else if (!system_wide) {
                                system_wide = !have_cmd(argc - rep_args,
                                                        &argv[rep_args]);
+                       }
 
                        __argv = malloc((argc + 6) * sizeof(const char *));
                        if (!__argv)
@@ -1236,10 +1262,11 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
                script_path = rep_script_path;
 
        if (script_path) {
-               system_wide = false;
                j = 0;
 
-               if (rec_script_path)
+               if (!rec_script_path)
+                       system_wide = false;
+               else if (!system_wide)
                        system_wide = !have_cmd(argc - 1, &argv[1]);
 
                __argv = malloc((argc + 2) * sizeof(const char *));
@@ -1289,7 +1316,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
                        return -1;
                }
 
-               input = open(input_name, O_RDONLY);
+               input = open(session->filename, O_RDONLY);      /* input_name */
                if (input < 0) {
                        perror("failed to open file");
                        exit(-1);
This page took 0.027445 seconds and 5 git commands to generate.