Commit-ID:  c4068f51d40df151a661a384ab1309b11d7f012e
Gitweb:     http://git.kernel.org/tip/c4068f51d40df151a661a384ab1309b11d7f012e
Author:     Masami Hiramatsu <masami.hiramatsu...@hitachi.com>
AuthorDate: Thu, 19 Nov 2015 15:04:53 +0900
Committer:  Arnaldo Carvalho de Melo <a...@redhat.com>
CommitDate: Thu, 19 Nov 2015 13:19:19 -0300

perf tools: Make perf_exec_path() always return malloc'd string

Since system_path() returns malloc'd string if given path is not an
absolute path, perf_exec_path() sometimes returns a static string and
sometimes returns a malloc'd string depending on the environment
variables or command options.

This may cause a memory leak because the caller can not unconditionally
free the returned string.

This fixes perf_exec_path() and system_path() to always return a
malloc'd string, so the caller can always free it.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu...@hitachi.com>
Cc: Adrian Hunter <adrian.hun...@intel.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhy...@kernel.org>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Link: 
http://lkml.kernel.org/r/20151119060453.14210.65666.stgit@localhost.localdomain
Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com>
---
 tools/perf/util/exec_cmd.c | 21 +++++++++++----------
 tools/perf/util/exec_cmd.h |  5 +++--
 tools/perf/util/help.c     |  6 ++++--
 3 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/tools/perf/util/exec_cmd.c b/tools/perf/util/exec_cmd.c
index 7adf4ad..1099e92 100644
--- a/tools/perf/util/exec_cmd.c
+++ b/tools/perf/util/exec_cmd.c
@@ -9,17 +9,17 @@
 static const char *argv_exec_path;
 static const char *argv0_path;
 
-const char *system_path(const char *path)
+char *system_path(const char *path)
 {
        static const char *prefix = PREFIX;
        struct strbuf d = STRBUF_INIT;
 
        if (is_absolute_path(path))
-               return path;
+               return strdup(path);
 
        strbuf_addf(&d, "%s/%s", prefix, path);
        path = strbuf_detach(&d, NULL);
-       return path;
+       return (char *)path;
 }
 
 const char *perf_extract_argv0_path(const char *argv0)
@@ -52,17 +52,16 @@ void perf_set_argv_exec_path(const char *exec_path)
 
 
 /* Returns the highest-priority, location to look for perf programs. */
-const char *perf_exec_path(void)
+char *perf_exec_path(void)
 {
-       const char *env;
+       char *env;
 
        if (argv_exec_path)
-               return argv_exec_path;
+               return strdup(argv_exec_path);
 
        env = getenv(EXEC_PATH_ENVIRONMENT);
-       if (env && *env) {
-               return env;
-       }
+       if (env && *env)
+               return strdup(env);
 
        return system_path(PERF_EXEC_PATH);
 }
@@ -83,9 +82,11 @@ void setup_path(void)
 {
        const char *old_path = getenv("PATH");
        struct strbuf new_path = STRBUF_INIT;
+       char *tmp = perf_exec_path();
 
-       add_path(&new_path, perf_exec_path());
+       add_path(&new_path, tmp);
        add_path(&new_path, argv0_path);
+       free(tmp);
 
        if (old_path)
                strbuf_addstr(&new_path, old_path);
diff --git a/tools/perf/util/exec_cmd.h b/tools/perf/util/exec_cmd.h
index bc4b915..48b4175 100644
--- a/tools/perf/util/exec_cmd.h
+++ b/tools/perf/util/exec_cmd.h
@@ -3,10 +3,11 @@
 
 extern void perf_set_argv_exec_path(const char *exec_path);
 extern const char *perf_extract_argv0_path(const char *path);
-extern const char *perf_exec_path(void);
 extern void setup_path(void);
 extern int execv_perf_cmd(const char **argv); /* NULL terminated */
 extern int execl_perf_cmd(const char *cmd, ...);
-extern const char *system_path(const char *path);
+/* perf_exec_path and system_path return malloc'd string, caller must free it 
*/
+extern char *perf_exec_path(void);
+extern char *system_path(const char *path);
 
 #endif /* __PERF_EXEC_CMD_H */
diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c
index 86c37c4..fa1fc4a 100644
--- a/tools/perf/util/help.c
+++ b/tools/perf/util/help.c
@@ -159,7 +159,7 @@ void load_command_list(const char *prefix,
                struct cmdnames *other_cmds)
 {
        const char *env_path = getenv("PATH");
-       const char *exec_path = perf_exec_path();
+       char *exec_path = perf_exec_path();
 
        if (exec_path) {
                list_commands_in_dir(main_cmds, exec_path, prefix);
@@ -187,6 +187,7 @@ void load_command_list(const char *prefix,
                      sizeof(*other_cmds->names), cmdname_compare);
                uniq(other_cmds);
        }
+       free(exec_path);
        exclude_cmds(other_cmds, main_cmds);
 }
 
@@ -203,13 +204,14 @@ void list_commands(const char *title, struct cmdnames 
*main_cmds,
                        longest = other_cmds->names[i]->len;
 
        if (main_cmds->cnt) {
-               const char *exec_path = perf_exec_path();
+               char *exec_path = perf_exec_path();
                printf("available %s in '%s'\n", title, exec_path);
                printf("----------------");
                mput_char('-', strlen(title) + strlen(exec_path));
                putchar('\n');
                pretty_print_string_list(main_cmds, longest);
                putchar('\n');
+               free(exec_path);
        }
 
        if (other_cmds->cnt) {
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to