From 9955d0be161a9baa241ae7b98426a4c705cb21cb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 15 Jun 2016 15:48:08 -0300 Subject: perf annotate: Use pipe + fork instead of popen We will need to redirect the stderr as well, so open code popen as a starting point. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-k0zt9svg4bswiglem7ornts4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index e9825fe825fd..2dd396a1f64b 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1134,8 +1134,10 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) char symfs_filename[PATH_MAX]; struct kcore_extract kce; bool delete_extract = false; + int stdout_fd[2]; int lineno = 0; int nline; + pid_t pid; if (filename) symbol__join_symfs(symfs_filename, filename); @@ -1258,9 +1260,32 @@ fallback: pr_debug("Executing: %s\n", command); - file = popen(command, "r"); + err = -1; + if (pipe(stdout_fd) < 0) { + pr_err("Failure creating the pipe to run %s\n", command); + goto out_remove_tmp; + } + + pid = fork(); + if (pid < 0) { + pr_err("Failure forking to run %s\n", command); + goto out_close_stdout; + } + + if (pid == 0) { + close(stdout_fd[0]); + dup2(stdout_fd[1], 1); + close(stdout_fd[1]); + execl("/bin/sh", "sh", "-c", command, NULL); + perror(command); + exit(-1); + } + + close(stdout_fd[1]); + + file = fdopen(stdout_fd[0], "r"); if (!file) { - pr_err("Failure running %s\n", command); + pr_err("Failure creating FILE stream for %s\n", command); /* * If we were using debug info should retry with * original binary. @@ -1286,9 +1311,11 @@ fallback: if (dso__is_kcore(dso)) delete_last_nop(sym); - pclose(file); - + fclose(file); + err = 0; out_remove_tmp: + close(stdout_fd[0]); + if (dso__needs_decompress(dso)) unlink(symfs_filename); out_free_filename: @@ -1297,6 +1324,10 @@ out_free_filename: if (free_filename) free(filename); return err; + +out_close_stdout: + close(stdout_fd[1]); + goto out_remove_tmp; } static void insert_source_line(struct rb_root *root, struct source_line *src_line) -- cgit v1.2.3