diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2015-11-19 01:04:53 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-11-19 11:19:19 -0500 |
commit | c4068f51d40df151a661a384ab1309b11d7f012e (patch) | |
tree | 49f5332f3aa16b6eef6089885da532d8ae353e02 | |
parent | ebe9729c8c3171aa46ad5d7af40acdc29806689d (diff) |
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.pt@hitachi.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20151119060453.14210.65666.stgit@localhost.localdomain
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/exec_cmd.c | 21 | ||||
-rw-r--r-- | tools/perf/util/exec_cmd.h | 5 | ||||
-rw-r--r-- | 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 7adf4ad15d8f..1099e92f5ee1 100644 --- a/tools/perf/util/exec_cmd.c +++ b/tools/perf/util/exec_cmd.c | |||
@@ -9,17 +9,17 @@ | |||
9 | static const char *argv_exec_path; | 9 | static const char *argv_exec_path; |
10 | static const char *argv0_path; | 10 | static const char *argv0_path; |
11 | 11 | ||
12 | const char *system_path(const char *path) | 12 | char *system_path(const char *path) |
13 | { | 13 | { |
14 | static const char *prefix = PREFIX; | 14 | static const char *prefix = PREFIX; |
15 | struct strbuf d = STRBUF_INIT; | 15 | struct strbuf d = STRBUF_INIT; |
16 | 16 | ||
17 | if (is_absolute_path(path)) | 17 | if (is_absolute_path(path)) |
18 | return path; | 18 | return strdup(path); |
19 | 19 | ||
20 | strbuf_addf(&d, "%s/%s", prefix, path); | 20 | strbuf_addf(&d, "%s/%s", prefix, path); |
21 | path = strbuf_detach(&d, NULL); | 21 | path = strbuf_detach(&d, NULL); |
22 | return path; | 22 | return (char *)path; |
23 | } | 23 | } |
24 | 24 | ||
25 | const char *perf_extract_argv0_path(const char *argv0) | 25 | const char *perf_extract_argv0_path(const char *argv0) |
@@ -52,17 +52,16 @@ void perf_set_argv_exec_path(const char *exec_path) | |||
52 | 52 | ||
53 | 53 | ||
54 | /* Returns the highest-priority, location to look for perf programs. */ | 54 | /* Returns the highest-priority, location to look for perf programs. */ |
55 | const char *perf_exec_path(void) | 55 | char *perf_exec_path(void) |
56 | { | 56 | { |
57 | const char *env; | 57 | char *env; |
58 | 58 | ||
59 | if (argv_exec_path) | 59 | if (argv_exec_path) |
60 | return argv_exec_path; | 60 | return strdup(argv_exec_path); |
61 | 61 | ||
62 | env = getenv(EXEC_PATH_ENVIRONMENT); | 62 | env = getenv(EXEC_PATH_ENVIRONMENT); |
63 | if (env && *env) { | 63 | if (env && *env) |
64 | return env; | 64 | return strdup(env); |
65 | } | ||
66 | 65 | ||
67 | return system_path(PERF_EXEC_PATH); | 66 | return system_path(PERF_EXEC_PATH); |
68 | } | 67 | } |
@@ -83,9 +82,11 @@ void setup_path(void) | |||
83 | { | 82 | { |
84 | const char *old_path = getenv("PATH"); | 83 | const char *old_path = getenv("PATH"); |
85 | struct strbuf new_path = STRBUF_INIT; | 84 | struct strbuf new_path = STRBUF_INIT; |
85 | char *tmp = perf_exec_path(); | ||
86 | 86 | ||
87 | add_path(&new_path, perf_exec_path()); | 87 | add_path(&new_path, tmp); |
88 | add_path(&new_path, argv0_path); | 88 | add_path(&new_path, argv0_path); |
89 | free(tmp); | ||
89 | 90 | ||
90 | if (old_path) | 91 | if (old_path) |
91 | strbuf_addstr(&new_path, old_path); | 92 | strbuf_addstr(&new_path, old_path); |
diff --git a/tools/perf/util/exec_cmd.h b/tools/perf/util/exec_cmd.h index bc4b915963f5..48b4175f1e11 100644 --- a/tools/perf/util/exec_cmd.h +++ b/tools/perf/util/exec_cmd.h | |||
@@ -3,10 +3,11 @@ | |||
3 | 3 | ||
4 | extern void perf_set_argv_exec_path(const char *exec_path); | 4 | extern void perf_set_argv_exec_path(const char *exec_path); |
5 | extern const char *perf_extract_argv0_path(const char *path); | 5 | extern const char *perf_extract_argv0_path(const char *path); |
6 | extern const char *perf_exec_path(void); | ||
7 | extern void setup_path(void); | 6 | extern void setup_path(void); |
8 | extern int execv_perf_cmd(const char **argv); /* NULL terminated */ | 7 | extern int execv_perf_cmd(const char **argv); /* NULL terminated */ |
9 | extern int execl_perf_cmd(const char *cmd, ...); | 8 | extern int execl_perf_cmd(const char *cmd, ...); |
10 | extern const char *system_path(const char *path); | 9 | /* perf_exec_path and system_path return malloc'd string, caller must free it */ |
10 | extern char *perf_exec_path(void); | ||
11 | extern char *system_path(const char *path); | ||
11 | 12 | ||
12 | #endif /* __PERF_EXEC_CMD_H */ | 13 | #endif /* __PERF_EXEC_CMD_H */ |
diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c index 86c37c472263..fa1fc4acb8a4 100644 --- a/tools/perf/util/help.c +++ b/tools/perf/util/help.c | |||
@@ -159,7 +159,7 @@ void load_command_list(const char *prefix, | |||
159 | struct cmdnames *other_cmds) | 159 | struct cmdnames *other_cmds) |
160 | { | 160 | { |
161 | const char *env_path = getenv("PATH"); | 161 | const char *env_path = getenv("PATH"); |
162 | const char *exec_path = perf_exec_path(); | 162 | char *exec_path = perf_exec_path(); |
163 | 163 | ||
164 | if (exec_path) { | 164 | if (exec_path) { |
165 | list_commands_in_dir(main_cmds, exec_path, prefix); | 165 | list_commands_in_dir(main_cmds, exec_path, prefix); |
@@ -187,6 +187,7 @@ void load_command_list(const char *prefix, | |||
187 | sizeof(*other_cmds->names), cmdname_compare); | 187 | sizeof(*other_cmds->names), cmdname_compare); |
188 | uniq(other_cmds); | 188 | uniq(other_cmds); |
189 | } | 189 | } |
190 | free(exec_path); | ||
190 | exclude_cmds(other_cmds, main_cmds); | 191 | exclude_cmds(other_cmds, main_cmds); |
191 | } | 192 | } |
192 | 193 | ||
@@ -203,13 +204,14 @@ void list_commands(const char *title, struct cmdnames *main_cmds, | |||
203 | longest = other_cmds->names[i]->len; | 204 | longest = other_cmds->names[i]->len; |
204 | 205 | ||
205 | if (main_cmds->cnt) { | 206 | if (main_cmds->cnt) { |
206 | const char *exec_path = perf_exec_path(); | 207 | char *exec_path = perf_exec_path(); |
207 | printf("available %s in '%s'\n", title, exec_path); | 208 | printf("available %s in '%s'\n", title, exec_path); |
208 | printf("----------------"); | 209 | printf("----------------"); |
209 | mput_char('-', strlen(title) + strlen(exec_path)); | 210 | mput_char('-', strlen(title) + strlen(exec_path)); |
210 | putchar('\n'); | 211 | putchar('\n'); |
211 | pretty_print_string_list(main_cmds, longest); | 212 | pretty_print_string_list(main_cmds, longest); |
212 | putchar('\n'); | 213 | putchar('\n'); |
214 | free(exec_path); | ||
213 | } | 215 | } |
214 | 216 | ||
215 | if (other_cmds->cnt) { | 217 | if (other_cmds->cnt) { |