perf report: Accept fifos as input file
authorRobert Richter <robert.richter@amd.com>
Wed, 7 Dec 2011 09:02:54 +0000 (10:02 +0100)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 23 Dec 2011 19:01:03 +0000 (17:01 -0200)
The default input file for perf report is not handled the same way as
perf record does it for its output file. This leads to unexpected
behavior of perf report, etc. E.g.:

 # perf record -a -e cpu-cycles sleep 2 | perf report | cat
 failed to open perf.data: No such file or directory  (try 'perf record' first)

While perf record writes to a fifo, perf report expects perf.data to be
read. This patch changes this to accept fifos as input file.

Applies to the following commands:

 perf annotate
 perf buildid-list
 perf evlist
 perf kmem
 perf lock
 perf report
 perf sched
 perf script
 perf timechart

Also fixes char const* -> const char* type declaration for filename
strings.

v2:
* Prevent potential null pointer access to input_name in
  builtin-report.c. Needed due to removal of patch "perf report: Setup
  browser if stdout is a pipe"

Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1323248577-11268-5-git-send-email-robert.richter@amd.com
Signed-off-by: Robert Richter <robert.richter@amd.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
19 files changed:
tools/perf/Documentation/perf-annotate.txt
tools/perf/Documentation/perf-buildid-list.txt
tools/perf/Documentation/perf-evlist.txt
tools/perf/Documentation/perf-kmem.txt
tools/perf/Documentation/perf-lock.txt
tools/perf/Documentation/perf-report.txt
tools/perf/Documentation/perf-sched.txt
tools/perf/Documentation/perf-script.txt
tools/perf/Documentation/perf-timechart.txt
tools/perf/builtin-annotate.c
tools/perf/builtin-buildid-list.c
tools/perf/builtin-evlist.c
tools/perf/builtin-kmem.c
tools/perf/builtin-lock.c
tools/perf/builtin-report.c
tools/perf/builtin-sched.c
tools/perf/builtin-script.c
tools/perf/builtin-timechart.c
tools/perf/util/session.c

index 476029d30621b08aea50aa275875167beabe5447..c89f9e1453f7d937561e8202af3432b102291b73 100644 (file)
@@ -22,7 +22,7 @@ OPTIONS
 -------
 -i::
 --input=::
-        Input file name. (default: perf.data)
+        Input file name. (default: perf.data unless stdin is a fifo)
 
 -d::
 --dsos=<dso[,dso...]>::
index cc22325ffd1b90abf308b37ba4e52cf76e283358..25c52efcc7f062cfe17e9f9178fcad6f9300d166 100644 (file)
@@ -26,7 +26,7 @@ OPTIONS
         Show only DSOs with hits.
 -i::
 --input=::
-        Input file name. (default: perf.data)
+        Input file name. (default: perf.data unless stdin is a fifo)
 -f::
 --force::
        Don't do ownership validation.
index 0cada9e053dc06f3483d8e2a73745530caf14465..0507ec7bad717a5e869abc4b549efe30da033d2b 100644 (file)
@@ -18,7 +18,7 @@ OPTIONS
 -------
 -i::
 --input=::
-        Input file name. (default: perf.data)
+        Input file name. (default: perf.data unless stdin is a fifo)
 
 SEE ALSO
 --------
index a52fcde894c75ed2ab2a25cb3e8757f819b22e49..7c8fbbf3f61c8a9abbbca3990b1f07ac2ac968c8 100644 (file)
@@ -23,7 +23,7 @@ OPTIONS
 -------
 -i <file>::
 --input=<file>::
-       Select the input file (default: perf.data)
+       Select the input file (default: perf.data unless stdin is a fifo)
 
 --caller::
        Show per-callsite statistics
index 4a26a2f3a6a39a2da7e3954fdc8fed59c6647f20..d6b2a4f2108bf384e8fcb45eb780bd14a3dd122a 100644 (file)
@@ -29,7 +29,7 @@ COMMON OPTIONS
 
 -i::
 --input=<file>::
-        Input file name.
+        Input file name. (default: perf.data unless stdin is a fifo)
 
 -v::
 --verbose::
index 35af0dc8ccb4986d369adcc28341525d6cce9eb5..9b430e98712e9035d26d565b2fdb5a16fb42e471 100644 (file)
@@ -19,7 +19,7 @@ OPTIONS
 -------
 -i::
 --input=::
-        Input file name. (default: perf.data)
+        Input file name. (default: perf.data unless stdin is a fifo)
 
 -v::
 --verbose::
index 5b212b57f70bd61205740e03f5b1b93ce4427990..8ff4df95695128259abbd60e111283770f3a4b76 100644 (file)
@@ -40,7 +40,7 @@ OPTIONS
 -------
 -i::
 --input=<file>::
-        Input file name. (default: perf.data)
+        Input file name. (default: perf.data unless stdin is a fifo)
 
 -v::
 --verbose::
index 7f61eaaf9ab882b657206fcc63bf0952a590bd73..2f6cef43da25091e769f890291a69f6cf2ad9d19 100644 (file)
@@ -106,7 +106,7 @@ OPTIONS
 
 -i::
 --input=::
-        Input file name.
+        Input file name. (default: perf.data unless stdin is a fifo)
 
 -d::
 --debug-mode::
index d7b79e2ba2adbe2cc0cb6468a9d84d6b73b8ed0f..1632b0efc7577a730388154164be888c619ad934 100644 (file)
@@ -27,7 +27,7 @@ OPTIONS
         Select the output file (default: output.svg)
 -i::
 --input=::
-        Select the input file (default: perf.data)
+        Select the input file (default: perf.data unless stdin is a fifo)
 -w::
 --width=::
         Select the width of the SVG file (default: 1000)
index d449645c5ef1e1a6da0a339625e7244be5c961c5..214ba7f9f57759afe6aaa08720b045681d467cdd 100644 (file)
@@ -215,7 +215,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
        }
 
        if (total_nr_samples == 0) {
-               ui__warning("The %s file has no samples!\n", ann->input_name);
+               ui__warning("The %s file has no samples!\n", session->filename);
                goto out_delete;
        }
 out_delete:
@@ -250,7 +250,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
                        .ordered_samples = true,
                        .ordering_requires_timestamps = true,
                },
-               .input_name = "perf.data",
        };
        const struct option options[] = {
        OPT_STRING('i', "input", &annotate.input_name, "file",
index 4895668577b5742c7a24aca0aeefe5febeeaa365..52480467e9ffeebe8d48e69f9ae47eeef57954ec 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <libelf.h>
 
-static char const *input_name = "perf.data";
+static const char *input_name;
 static bool force;
 static bool show_kernel;
 static bool with_hits;
@@ -71,16 +71,24 @@ static int perf_session__list_build_ids(void)
 {
        struct perf_session *session;
 
+       elf_version(EV_CURRENT);
+
        session = perf_session__new(input_name, O_RDONLY, force, false,
                                    &build_id__mark_dso_hit_ops);
        if (session == NULL)
                return -1;
 
+       /*
+        * See if this is an ELF file first:
+        */
+       if (filename__fprintf_build_id(session->filename, stdout))
+               goto out;
+
        if (with_hits)
                perf_session__process_events(session, &build_id__mark_dso_hit_ops);
 
        perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
-
+out:
        perf_session__delete(session);
        return 0;
 }
@@ -90,13 +98,6 @@ static int __cmd_buildid_list(void)
        if (show_kernel)
                return sysfs__fprintf_build_id(stdout);
 
-       elf_version(EV_CURRENT);
-       /*
-        * See if this is an ELF file first:
-        */
-       if (filename__fprintf_build_id(input_name, stdout))
-               return 0;
-
        return perf_session__list_build_ids();
 }
 
index 4c5e9e04a41fcb6b875432d0d77052facd0a91c5..26760322c4f4178a91a1edb1f35e5e0ce6d8a2b7 100644 (file)
@@ -15,7 +15,7 @@
 #include "util/parse-options.h"
 #include "util/session.h"
 
-static char const *input_name = "perf.data";
+static const char *input_name;
 
 static int __cmd_evlist(void)
 {
index 886174e9525b5e275be2dd9c16b6385c0c800f8c..fe1ad8f21961512a6a81e5f5670de71fcc9a2279 100644 (file)
@@ -19,7 +19,7 @@
 struct alloc_stat;
 typedef int (*sort_fn_t)(struct alloc_stat *, struct alloc_stat *);
 
-static char const              *input_name = "perf.data";
+static const char              *input_name;
 
 static int                     alloc_flag;
 static int                     caller_flag;
index 4db5e52930672d1ab1d3b5f230357bdf355e0335..2296c391d0f581246c8c72a913d47357bbb15842 100644 (file)
@@ -326,7 +326,7 @@ alloc_failed:
        die("memory allocation failed\n");
 }
 
-static char                    const *input_name = "perf.data";
+static const char *input_name;
 
 struct raw_event_sample {
        u32                     size;
index 9051f6bfaa7e4a44a8357cacf30af261a5dee1bd..25d34d483e494b23d6c13acd46df579d067f0509 100644 (file)
@@ -321,8 +321,7 @@ static int __cmd_report(struct perf_report *rep)
        }
 
        if (nr_samples == 0) {
-               ui__warning("The %s file has no samples!\n",
-                           rep->input_name);
+               ui__warning("The %s file has no samples!\n", session->filename);
                goto out_delete;
        }
 
@@ -430,6 +429,7 @@ setup:
 
 int cmd_report(int argc, const char **argv, const char *prefix __used)
 {
+       struct stat st;
        char callchain_default_opt[] = "fractal,0.5,callee";
        const char * const report_usage[] = {
                "perf report [<options>]",
@@ -451,7 +451,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
                        .ordered_samples = true,
                        .ordering_requires_timestamps = true,
                },
-               .input_name              = "perf.data",
                .pretty_printing_style   = "normal",
        };
        const struct option options[] = {
@@ -531,10 +530,18 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
        if (report.inverted_callchain)
                callchain_param.order = ORDER_CALLER;
 
+       if (!report.input_name || !strlen(report.input_name)) {
+               if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
+                       report.input_name = "-";
+               else
+                       report.input_name = "perf.data";
+       }
+
        if (strcmp(report.input_name, "-") != 0)
                setup_browser(true);
        else
                use_browser = 0;
+
        /*
         * Only in the newt browser we are doing integrated annotation,
         * so don't allocate extra space that won't be used in the stdio
index 6284ed2317f2e6697a4f8227c20d86e55ea11e43..fb8b5f83b4a0ae77736fbffe6a6736d56813eed6 100644 (file)
@@ -22,7 +22,7 @@
 #include <pthread.h>
 #include <math.h>
 
-static char                    const *input_name = "perf.data";
+static const char              *input_name;
 
 static char                    default_sort_order[] = "avg, max, switch, runtime";
 static const char              *sort_order = default_sort_order;
index d71b745da06e3c13f93c7a21a840b6187226ee50..3d4c0c7b576e309272f7a7371d625b03eaeb228c 100644 (file)
@@ -434,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,
@@ -1316,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);
index 135376a37f974e24cc18db3c0466046bfae4690f..3b75b2e21ea55e51739a7200ffeeb61aa8e613ad 100644 (file)
@@ -38,8 +38,8 @@
 #define PWR_EVENT_EXIT -1
 
 
-static char            const *input_name = "perf.data";
-static char            const *output_name = "output.svg";
+static const char      *input_name;
+static const char      *output_name = "output.svg";
 
 static unsigned int    numcpus;
 static u64             min_freq;       /* Lowest CPU frequency seen */
index ea17dfb85baa3f6ddad7791650329607150e47cf..cc5e6be46d8670d7e5f7dadaa05cc276710021e5 100644 (file)
@@ -107,8 +107,19 @@ struct perf_session *perf_session__new(const char *filename, int mode,
                                       bool force, bool repipe,
                                       struct perf_tool *tool)
 {
-       size_t len = filename ? strlen(filename) : 0;
-       struct perf_session *self = zalloc(sizeof(*self) + len);
+       struct perf_session *self;
+       struct stat st;
+       size_t len;
+
+       if (!filename || !strlen(filename)) {
+               if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
+                       filename = "-";
+               else
+                       filename = "perf.data";
+       }
+
+       len = strlen(filename);
+       self = zalloc(sizeof(*self) + len);
 
        if (self == NULL)
                goto out;