aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2018-03-02 11:13:54 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2018-03-05 09:52:41 -0500
commitcfacbabd1d9c35d2a179650b2911f17a8d8620b8 (patch)
tree12cc9e08fa2cba80b0a9f616203875c5977dba57 /tools/perf
parent9cf195f80c5e8a6d779119a7d292e537315d2ea6 (diff)
perf record: Fix crash in pipe mode
Currently we can crash perf record when running in pipe mode, like: $ perf record ls | perf report # To display the perf.data header info, please use --header/--header-only options. # perf: Segmentation fault Error: The - file has no samples! The callstack of the crash is: 0x0000000000515242 in perf_event__synthesize_event_update_name 3513 ev = event_update_event__new(len + 1, PERF_EVENT_UPDATE__NAME, evsel->id[0]); (gdb) bt #0 0x0000000000515242 in perf_event__synthesize_event_update_name #1 0x00000000005158a4 in perf_event__synthesize_extra_attr #2 0x0000000000443347 in record__synthesize #3 0x00000000004438e3 in __cmd_record #4 0x000000000044514e in cmd_record #5 0x00000000004cbc95 in run_builtin #6 0x00000000004cbf02 in handle_internal_command #7 0x00000000004cc054 in run_argv #8 0x00000000004cc422 in main The reason of the crash is that the evsel does not have ids array allocated and the pipe's synthesize code tries to access it. We don't force evsel ids allocation when we have single event, because it's not needed. However we need it when we are in pipe mode even for single event as a key for evsel update event. Fixing this by forcing evsel ids allocation event for single event, when we are in pipe mode. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20180302161354.30192-1-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-record.c9
-rw-r--r--tools/perf/perf.h1
-rw-r--r--tools/perf/util/record.c8
3 files changed, 16 insertions, 2 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index bf4ca749d1ac..a217623fec2e 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -881,6 +881,15 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
881 } 881 }
882 } 882 }
883 883
884 /*
885 * If we have just single event and are sending data
886 * through pipe, we need to force the ids allocation,
887 * because we synthesize event name through the pipe
888 * and need the id for that.
889 */
890 if (data->is_pipe && rec->evlist->nr_entries == 1)
891 rec->opts.sample_id = true;
892
884 if (record__open(rec) != 0) { 893 if (record__open(rec) != 0) {
885 err = -1; 894 err = -1;
886 goto out_child; 895 goto out_child;
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index cfe46236a5e5..57b9b342d533 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -61,6 +61,7 @@ struct record_opts {
61 bool tail_synthesize; 61 bool tail_synthesize;
62 bool overwrite; 62 bool overwrite;
63 bool ignore_missing_thread; 63 bool ignore_missing_thread;
64 bool sample_id;
64 unsigned int freq; 65 unsigned int freq;
65 unsigned int mmap_pages; 66 unsigned int mmap_pages;
66 unsigned int auxtrace_mmap_pages; 67 unsigned int auxtrace_mmap_pages;
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 1e97937b03a9..6f09e4962dad 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -137,6 +137,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
137 struct perf_evsel *evsel; 137 struct perf_evsel *evsel;
138 bool use_sample_identifier = false; 138 bool use_sample_identifier = false;
139 bool use_comm_exec; 139 bool use_comm_exec;
140 bool sample_id = opts->sample_id;
140 141
141 /* 142 /*
142 * Set the evsel leader links before we configure attributes, 143 * Set the evsel leader links before we configure attributes,
@@ -163,8 +164,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
163 * match the id. 164 * match the id.
164 */ 165 */
165 use_sample_identifier = perf_can_sample_identifier(); 166 use_sample_identifier = perf_can_sample_identifier();
166 evlist__for_each_entry(evlist, evsel) 167 sample_id = true;
167 perf_evsel__set_sample_id(evsel, use_sample_identifier);
168 } else if (evlist->nr_entries > 1) { 168 } else if (evlist->nr_entries > 1) {
169 struct perf_evsel *first = perf_evlist__first(evlist); 169 struct perf_evsel *first = perf_evlist__first(evlist);
170 170
@@ -174,6 +174,10 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
174 use_sample_identifier = perf_can_sample_identifier(); 174 use_sample_identifier = perf_can_sample_identifier();
175 break; 175 break;
176 } 176 }
177 sample_id = true;
178 }
179
180 if (sample_id) {
177 evlist__for_each_entry(evlist, evsel) 181 evlist__for_each_entry(evlist, evsel)
178 perf_evsel__set_sample_id(evsel, use_sample_identifier); 182 perf_evsel__set_sample_id(evsel, use_sample_identifier);
179 } 183 }