提交 fea20d66 编写于 作者: N Namhyung Kim 提交者: Arnaldo Carvalho de Melo

perf inject: Fix output from a pipe to a file

Sometimes it needs to save the perf inject data to a file for debugging.
But normally it assumes the same format for input and output, so the end
result cannot be used due to a broken format.

  # perf record -a -o - sleep 1 | perf inject -b -o my.data

  # perf report -i my.data --stdio
  0x208 [0]: failed to process type: 0 [Invalid argument]
  Error:
  failed to process sample
  # To display the perf.data header info, please use --header/--header-only options.
  #

In this case, it thought the data has a regular file header since the
output is not a pipe.  But actually it doesn't have one and has a pipe
file header.  At the end of the session, it tries to rewrite the regular
file header with updated features and it overwrites the data just
follows the pipe header.

Fix it by checking either the input and the output is a pipe.
Signed-off-by: NNamhyung Kim <namhyung@kernel.org>
Acked-by: NJiri Olsa <jolsa@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lore.kernel.org/lkml/20210719223153.1618812-4-namhyung@kernel.orgSigned-off-by: NArnaldo Carvalho de Melo <acme@redhat.com>
上级 0ae03893
......@@ -46,6 +46,7 @@ struct perf_inject {
bool jit_mode;
bool in_place_update;
bool in_place_update_dry_run;
bool is_pipe;
const char *input_name;
struct perf_data output;
u64 bytes_written;
......@@ -126,7 +127,7 @@ static int perf_event__repipe_attr(struct perf_tool *tool,
if (ret)
return ret;
if (!inject->output.is_pipe)
if (!inject->is_pipe)
return 0;
return perf_event__repipe_synth(tool, event);
......@@ -826,14 +827,14 @@ static int __cmd_inject(struct perf_inject *inject)
if (!inject->itrace_synth_opts.set)
auxtrace_index__free(&session->auxtrace_index);
if (!data_out->is_pipe && !inject->in_place_update)
if (!inject->is_pipe && !inject->in_place_update)
lseek(fd, output_data_offset, SEEK_SET);
ret = perf_session__process_events(session);
if (ret)
return ret;
if (!data_out->is_pipe && !inject->in_place_update) {
if (!inject->is_pipe && !inject->in_place_update) {
if (inject->build_ids)
perf_header__set_feat(&session->header,
HEADER_BUILD_ID);
......@@ -992,8 +993,12 @@ int cmd_inject(int argc, const char **argv)
}
data.path = inject.input_name;
inject.session = __perf_session__new(&data, inject.output.is_pipe,
perf_data__fd(&inject.output), &inject.tool);
if (!strcmp(inject.input_name, "-") || inject.output.is_pipe)
inject.is_pipe = true;
inject.session = __perf_session__new(&data, inject.is_pipe,
perf_data__fd(&inject.output),
&inject.tool);
if (IS_ERR(inject.session)) {
ret = PTR_ERR(inject.session);
goto out_close_output;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册