perf report: Accept fifos as input file
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>
This commit is contained in:
parent
1b5495043d
commit
efad14150a
|
@ -22,7 +22,7 @@ OPTIONS
|
||||||
-------
|
-------
|
||||||
-i::
|
-i::
|
||||||
--input=::
|
--input=::
|
||||||
Input file name. (default: perf.data)
|
Input file name. (default: perf.data unless stdin is a fifo)
|
||||||
|
|
||||||
-d::
|
-d::
|
||||||
--dsos=<dso[,dso...]>::
|
--dsos=<dso[,dso...]>::
|
||||||
|
|
|
@ -26,7 +26,7 @@ OPTIONS
|
||||||
Show only DSOs with hits.
|
Show only DSOs with hits.
|
||||||
-i::
|
-i::
|
||||||
--input=::
|
--input=::
|
||||||
Input file name. (default: perf.data)
|
Input file name. (default: perf.data unless stdin is a fifo)
|
||||||
-f::
|
-f::
|
||||||
--force::
|
--force::
|
||||||
Don't do ownership validation.
|
Don't do ownership validation.
|
||||||
|
|
|
@ -18,7 +18,7 @@ OPTIONS
|
||||||
-------
|
-------
|
||||||
-i::
|
-i::
|
||||||
--input=::
|
--input=::
|
||||||
Input file name. (default: perf.data)
|
Input file name. (default: perf.data unless stdin is a fifo)
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -23,7 +23,7 @@ OPTIONS
|
||||||
-------
|
-------
|
||||||
-i <file>::
|
-i <file>::
|
||||||
--input=<file>::
|
--input=<file>::
|
||||||
Select the input file (default: perf.data)
|
Select the input file (default: perf.data unless stdin is a fifo)
|
||||||
|
|
||||||
--caller::
|
--caller::
|
||||||
Show per-callsite statistics
|
Show per-callsite statistics
|
||||||
|
|
|
@ -29,7 +29,7 @@ COMMON OPTIONS
|
||||||
|
|
||||||
-i::
|
-i::
|
||||||
--input=<file>::
|
--input=<file>::
|
||||||
Input file name.
|
Input file name. (default: perf.data unless stdin is a fifo)
|
||||||
|
|
||||||
-v::
|
-v::
|
||||||
--verbose::
|
--verbose::
|
||||||
|
|
|
@ -19,7 +19,7 @@ OPTIONS
|
||||||
-------
|
-------
|
||||||
-i::
|
-i::
|
||||||
--input=::
|
--input=::
|
||||||
Input file name. (default: perf.data)
|
Input file name. (default: perf.data unless stdin is a fifo)
|
||||||
|
|
||||||
-v::
|
-v::
|
||||||
--verbose::
|
--verbose::
|
||||||
|
|
|
@ -40,7 +40,7 @@ OPTIONS
|
||||||
-------
|
-------
|
||||||
-i::
|
-i::
|
||||||
--input=<file>::
|
--input=<file>::
|
||||||
Input file name. (default: perf.data)
|
Input file name. (default: perf.data unless stdin is a fifo)
|
||||||
|
|
||||||
-v::
|
-v::
|
||||||
--verbose::
|
--verbose::
|
||||||
|
|
|
@ -106,7 +106,7 @@ OPTIONS
|
||||||
|
|
||||||
-i::
|
-i::
|
||||||
--input=::
|
--input=::
|
||||||
Input file name.
|
Input file name. (default: perf.data unless stdin is a fifo)
|
||||||
|
|
||||||
-d::
|
-d::
|
||||||
--debug-mode::
|
--debug-mode::
|
||||||
|
|
|
@ -27,7 +27,7 @@ OPTIONS
|
||||||
Select the output file (default: output.svg)
|
Select the output file (default: output.svg)
|
||||||
-i::
|
-i::
|
||||||
--input=::
|
--input=::
|
||||||
Select the input file (default: perf.data)
|
Select the input file (default: perf.data unless stdin is a fifo)
|
||||||
-w::
|
-w::
|
||||||
--width=::
|
--width=::
|
||||||
Select the width of the SVG file (default: 1000)
|
Select the width of the SVG file (default: 1000)
|
||||||
|
|
|
@ -215,7 +215,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (total_nr_samples == 0) {
|
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;
|
goto out_delete;
|
||||||
}
|
}
|
||||||
out_delete:
|
out_delete:
|
||||||
|
@ -250,7 +250,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
|
||||||
.ordered_samples = true,
|
.ordered_samples = true,
|
||||||
.ordering_requires_timestamps = true,
|
.ordering_requires_timestamps = true,
|
||||||
},
|
},
|
||||||
.input_name = "perf.data",
|
|
||||||
};
|
};
|
||||||
const struct option options[] = {
|
const struct option options[] = {
|
||||||
OPT_STRING('i', "input", &annotate.input_name, "file",
|
OPT_STRING('i', "input", &annotate.input_name, "file",
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include <libelf.h>
|
#include <libelf.h>
|
||||||
|
|
||||||
static char const *input_name = "perf.data";
|
static const char *input_name;
|
||||||
static bool force;
|
static bool force;
|
||||||
static bool show_kernel;
|
static bool show_kernel;
|
||||||
static bool with_hits;
|
static bool with_hits;
|
||||||
|
@ -71,16 +71,24 @@ static int perf_session__list_build_ids(void)
|
||||||
{
|
{
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
|
|
||||||
|
elf_version(EV_CURRENT);
|
||||||
|
|
||||||
session = perf_session__new(input_name, O_RDONLY, force, false,
|
session = perf_session__new(input_name, O_RDONLY, force, false,
|
||||||
&build_id__mark_dso_hit_ops);
|
&build_id__mark_dso_hit_ops);
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if this is an ELF file first:
|
||||||
|
*/
|
||||||
|
if (filename__fprintf_build_id(session->filename, stdout))
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (with_hits)
|
if (with_hits)
|
||||||
perf_session__process_events(session, &build_id__mark_dso_hit_ops);
|
perf_session__process_events(session, &build_id__mark_dso_hit_ops);
|
||||||
|
|
||||||
perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
|
perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
|
||||||
|
out:
|
||||||
perf_session__delete(session);
|
perf_session__delete(session);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -90,13 +98,6 @@ static int __cmd_buildid_list(void)
|
||||||
if (show_kernel)
|
if (show_kernel)
|
||||||
return sysfs__fprintf_build_id(stdout);
|
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();
|
return perf_session__list_build_ids();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "util/parse-options.h"
|
#include "util/parse-options.h"
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
|
|
||||||
static char const *input_name = "perf.data";
|
static const char *input_name;
|
||||||
|
|
||||||
static int __cmd_evlist(void)
|
static int __cmd_evlist(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
struct alloc_stat;
|
struct alloc_stat;
|
||||||
typedef int (*sort_fn_t)(struct alloc_stat *, 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 alloc_flag;
|
||||||
static int caller_flag;
|
static int caller_flag;
|
||||||
|
|
|
@ -326,7 +326,7 @@ alloc_failed:
|
||||||
die("memory allocation failed\n");
|
die("memory allocation failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static char const *input_name = "perf.data";
|
static const char *input_name;
|
||||||
|
|
||||||
struct raw_event_sample {
|
struct raw_event_sample {
|
||||||
u32 size;
|
u32 size;
|
||||||
|
|
|
@ -321,8 +321,7 @@ static int __cmd_report(struct perf_report *rep)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nr_samples == 0) {
|
if (nr_samples == 0) {
|
||||||
ui__warning("The %s file has no samples!\n",
|
ui__warning("The %s file has no samples!\n", session->filename);
|
||||||
rep->input_name);
|
|
||||||
goto out_delete;
|
goto out_delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,6 +429,7 @@ setup:
|
||||||
|
|
||||||
int cmd_report(int argc, const char **argv, const char *prefix __used)
|
int cmd_report(int argc, const char **argv, const char *prefix __used)
|
||||||
{
|
{
|
||||||
|
struct stat st;
|
||||||
char callchain_default_opt[] = "fractal,0.5,callee";
|
char callchain_default_opt[] = "fractal,0.5,callee";
|
||||||
const char * const report_usage[] = {
|
const char * const report_usage[] = {
|
||||||
"perf report [<options>]",
|
"perf report [<options>]",
|
||||||
|
@ -451,7 +451,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
|
||||||
.ordered_samples = true,
|
.ordered_samples = true,
|
||||||
.ordering_requires_timestamps = true,
|
.ordering_requires_timestamps = true,
|
||||||
},
|
},
|
||||||
.input_name = "perf.data",
|
|
||||||
.pretty_printing_style = "normal",
|
.pretty_printing_style = "normal",
|
||||||
};
|
};
|
||||||
const struct option options[] = {
|
const struct option options[] = {
|
||||||
|
@ -531,10 +530,18 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
|
||||||
if (report.inverted_callchain)
|
if (report.inverted_callchain)
|
||||||
callchain_param.order = ORDER_CALLER;
|
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)
|
if (strcmp(report.input_name, "-") != 0)
|
||||||
setup_browser(true);
|
setup_browser(true);
|
||||||
else
|
else
|
||||||
use_browser = 0;
|
use_browser = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only in the newt browser we are doing integrated annotation,
|
* Only in the newt browser we are doing integrated annotation,
|
||||||
* so don't allocate extra space that won't be used in the stdio
|
* so don't allocate extra space that won't be used in the stdio
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <math.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 char default_sort_order[] = "avg, max, switch, runtime";
|
||||||
static const char *sort_order = default_sort_order;
|
static const char *sort_order = default_sort_order;
|
||||||
|
|
|
@ -434,7 +434,7 @@ static int cleanup_scripting(void)
|
||||||
return scripting_ops->stop_script();
|
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,
|
static int process_sample_event(struct perf_tool *tool __used,
|
||||||
union perf_event *event,
|
union perf_event *event,
|
||||||
|
@ -1316,7 +1316,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
input = open(input_name, O_RDONLY);
|
input = open(session->filename, O_RDONLY); /* input_name */
|
||||||
if (input < 0) {
|
if (input < 0) {
|
||||||
perror("failed to open file");
|
perror("failed to open file");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|
|
@ -38,8 +38,8 @@
|
||||||
#define PWR_EVENT_EXIT -1
|
#define PWR_EVENT_EXIT -1
|
||||||
|
|
||||||
|
|
||||||
static char const *input_name = "perf.data";
|
static const char *input_name;
|
||||||
static char const *output_name = "output.svg";
|
static const char *output_name = "output.svg";
|
||||||
|
|
||||||
static unsigned int numcpus;
|
static unsigned int numcpus;
|
||||||
static u64 min_freq; /* Lowest CPU frequency seen */
|
static u64 min_freq; /* Lowest CPU frequency seen */
|
||||||
|
|
|
@ -107,8 +107,19 @@ struct perf_session *perf_session__new(const char *filename, int mode,
|
||||||
bool force, bool repipe,
|
bool force, bool repipe,
|
||||||
struct perf_tool *tool)
|
struct perf_tool *tool)
|
||||||
{
|
{
|
||||||
size_t len = filename ? strlen(filename) : 0;
|
struct perf_session *self;
|
||||||
struct perf_session *self = zalloc(sizeof(*self) + len);
|
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)
|
if (self == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
Loading…
Reference in New Issue