perf record: Prevent reading invalid data in record__mmap_read
[deliverable/linux.git] / tools / perf / builtin-record.c
CommitLineData
abaff32a 1/*
bf9e1876
IM
2 * builtin-record.c
3 *
4 * Builtin record command: Record the profile of a workload
5 * (or a CPU, or a PID) into the perf.data output file - for
6 * later analysis via perf report.
abaff32a 7 */
16f762a2 8#include "builtin.h"
bf9e1876
IM
9
10#include "perf.h"
11
6122e4e4 12#include "util/build-id.h"
6eda5838 13#include "util/util.h"
4b6ab94e 14#include <subcmd/parse-options.h>
8ad8db37 15#include "util/parse-events.h"
6eda5838 16
8f651eae 17#include "util/callchain.h"
f14d5707 18#include "util/cgroup.h"
7c6a1c65 19#include "util/header.h"
66e274f3 20#include "util/event.h"
361c99a6 21#include "util/evlist.h"
69aad6f1 22#include "util/evsel.h"
8f28827a 23#include "util/debug.h"
94c744b6 24#include "util/session.h"
45694aa7 25#include "util/tool.h"
8d06367f 26#include "util/symbol.h"
a12b51c4 27#include "util/cpumap.h"
fd78260b 28#include "util/thread_map.h"
f5fc1412 29#include "util/data.h"
bcc84ec6 30#include "util/perf_regs.h"
ef149c25 31#include "util/auxtrace.h"
46bc29b9 32#include "util/tsc.h"
f00898f4 33#include "util/parse-branch-options.h"
bcc84ec6 34#include "util/parse-regs-options.h"
71dc2326 35#include "util/llvm-utils.h"
8690a2a7 36#include "util/bpf-loader.h"
5f9cf599 37#include "util/trigger.h"
d8871ea7 38#include "asm/bug.h"
7c6a1c65 39
97124d5e 40#include <unistd.h>
de9ac07b 41#include <sched.h>
a41794cd 42#include <sys/mman.h>
2d11c650 43#include <asm/bug.h>
de9ac07b 44
78da39fa 45
8c6f45a7 46struct record {
45694aa7 47 struct perf_tool tool;
b4006796 48 struct record_opts opts;
d20deb64 49 u64 bytes_written;
f5fc1412 50 struct perf_data_file file;
ef149c25 51 struct auxtrace_record *itr;
d20deb64
ACM
52 struct perf_evlist *evlist;
53 struct perf_session *session;
54 const char *progname;
d20deb64 55 int realtime_prio;
d20deb64 56 bool no_buildid;
d2db9a98 57 bool no_buildid_set;
d20deb64 58 bool no_buildid_cache;
d2db9a98 59 bool no_buildid_cache_set;
6156681b 60 bool buildid_all;
ecfd7a9c 61 bool timestamp_filename;
3c1cb7e3 62 bool switch_output;
9f065194 63 unsigned long long samples;
0f82ebc4 64};
a21ca2ca 65
8c6f45a7 66static int record__write(struct record *rec, void *bf, size_t size)
f5970550 67{
cf8b2e69 68 if (perf_data_file__write(rec->session->file, bf, size) < 0) {
50a9b868
JO
69 pr_err("failed to write perf data, error: %m\n");
70 return -1;
f5970550 71 }
8d3eca20 72
cf8b2e69 73 rec->bytes_written += size;
8d3eca20 74 return 0;
f5970550
PZ
75}
76
45694aa7 77static int process_synthesized_event(struct perf_tool *tool,
d20deb64 78 union perf_event *event,
1d037ca1
IT
79 struct perf_sample *sample __maybe_unused,
80 struct machine *machine __maybe_unused)
234fbbf5 81{
8c6f45a7
ACM
82 struct record *rec = container_of(tool, struct record, tool);
83 return record__write(rec, event, event->header.size);
234fbbf5
ACM
84}
85
e5685730 86static int record__mmap_read(struct record *rec, int idx)
de9ac07b 87{
e5685730 88 struct perf_mmap *md = &rec->evlist->mmap[idx];
7b8283b5
DA
89 u64 head = perf_mmap__read_head(md);
90 u64 old = md->prev;
918512b4 91 unsigned char *data = md->base + page_size;
de9ac07b
PZ
92 unsigned long size;
93 void *buf;
8d3eca20 94 int rc = 0;
de9ac07b 95
dc82009a 96 if (old == head)
8d3eca20 97 return 0;
dc82009a 98
d20deb64 99 rec->samples++;
de9ac07b
PZ
100
101 size = head - old;
2d11c650
WN
102 if (size > (unsigned long)(md->mask) + 1) {
103 WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
104
105 md->prev = head;
106 perf_evlist__mmap_consume(rec->evlist, idx);
107 return 0;
108 }
de9ac07b
PZ
109
110 if ((old & md->mask) + size != (head & md->mask)) {
111 buf = &data[old & md->mask];
112 size = md->mask + 1 - (old & md->mask);
113 old += size;
021e9f47 114
8c6f45a7 115 if (record__write(rec, buf, size) < 0) {
8d3eca20
DA
116 rc = -1;
117 goto out;
118 }
de9ac07b
PZ
119 }
120
121 buf = &data[old & md->mask];
122 size = head - old;
123 old += size;
021e9f47 124
8c6f45a7 125 if (record__write(rec, buf, size) < 0) {
8d3eca20
DA
126 rc = -1;
127 goto out;
128 }
de9ac07b
PZ
129
130 md->prev = old;
e5685730 131 perf_evlist__mmap_consume(rec->evlist, idx);
8d3eca20
DA
132out:
133 return rc;
de9ac07b
PZ
134}
135
2dd6d8a1
AH
136static volatile int done;
137static volatile int signr = -1;
138static volatile int child_finished;
c0bdc1c4 139
2dd6d8a1 140static volatile int auxtrace_record__snapshot_started;
5f9cf599 141static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
3c1cb7e3 142static DEFINE_TRIGGER(switch_output_trigger);
2dd6d8a1
AH
143
144static void sig_handler(int sig)
145{
146 if (sig == SIGCHLD)
147 child_finished = 1;
148 else
149 signr = sig;
150
151 done = 1;
152}
153
154static void record__sig_exit(void)
155{
156 if (signr == -1)
157 return;
158
159 signal(signr, SIG_DFL);
160 raise(signr);
161}
162
e31f0d01
AH
163#ifdef HAVE_AUXTRACE_SUPPORT
164
ef149c25
AH
165static int record__process_auxtrace(struct perf_tool *tool,
166 union perf_event *event, void *data1,
167 size_t len1, void *data2, size_t len2)
168{
169 struct record *rec = container_of(tool, struct record, tool);
99fa2984 170 struct perf_data_file *file = &rec->file;
ef149c25
AH
171 size_t padding;
172 u8 pad[8] = {0};
173
99fa2984
AH
174 if (!perf_data_file__is_pipe(file)) {
175 off_t file_offset;
176 int fd = perf_data_file__fd(file);
177 int err;
178
179 file_offset = lseek(fd, 0, SEEK_CUR);
180 if (file_offset == -1)
181 return -1;
182 err = auxtrace_index__auxtrace_event(&rec->session->auxtrace_index,
183 event, file_offset);
184 if (err)
185 return err;
186 }
187
ef149c25
AH
188 /* event.auxtrace.size includes padding, see __auxtrace_mmap__read() */
189 padding = (len1 + len2) & 7;
190 if (padding)
191 padding = 8 - padding;
192
193 record__write(rec, event, event->header.size);
194 record__write(rec, data1, len1);
195 if (len2)
196 record__write(rec, data2, len2);
197 record__write(rec, &pad, padding);
198
199 return 0;
200}
201
202static int record__auxtrace_mmap_read(struct record *rec,
203 struct auxtrace_mmap *mm)
204{
205 int ret;
206
207 ret = auxtrace_mmap__read(mm, rec->itr, &rec->tool,
208 record__process_auxtrace);
209 if (ret < 0)
210 return ret;
211
212 if (ret)
213 rec->samples++;
214
215 return 0;
216}
217
2dd6d8a1
AH
218static int record__auxtrace_mmap_read_snapshot(struct record *rec,
219 struct auxtrace_mmap *mm)
220{
221 int ret;
222
223 ret = auxtrace_mmap__read_snapshot(mm, rec->itr, &rec->tool,
224 record__process_auxtrace,
225 rec->opts.auxtrace_snapshot_size);
226 if (ret < 0)
227 return ret;
228
229 if (ret)
230 rec->samples++;
231
232 return 0;
233}
234
235static int record__auxtrace_read_snapshot_all(struct record *rec)
236{
237 int i;
238 int rc = 0;
239
240 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
241 struct auxtrace_mmap *mm =
242 &rec->evlist->mmap[i].auxtrace_mmap;
243
244 if (!mm->base)
245 continue;
246
247 if (record__auxtrace_mmap_read_snapshot(rec, mm) != 0) {
248 rc = -1;
249 goto out;
250 }
251 }
252out:
253 return rc;
254}
255
256static void record__read_auxtrace_snapshot(struct record *rec)
257{
258 pr_debug("Recording AUX area tracing snapshot\n");
259 if (record__auxtrace_read_snapshot_all(rec) < 0) {
5f9cf599 260 trigger_error(&auxtrace_snapshot_trigger);
2dd6d8a1 261 } else {
5f9cf599
WN
262 if (auxtrace_record__snapshot_finish(rec->itr))
263 trigger_error(&auxtrace_snapshot_trigger);
264 else
265 trigger_ready(&auxtrace_snapshot_trigger);
2dd6d8a1
AH
266 }
267}
268
e31f0d01
AH
269#else
270
271static inline
272int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
273 struct auxtrace_mmap *mm __maybe_unused)
274{
275 return 0;
276}
277
2dd6d8a1
AH
278static inline
279void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
de9ac07b 280{
f7b7c26e
PZ
281}
282
2dd6d8a1
AH
283static inline
284int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
f7b7c26e 285{
2dd6d8a1 286 return 0;
de9ac07b
PZ
287}
288
2dd6d8a1
AH
289#endif
290
8c6f45a7 291static int record__open(struct record *rec)
dd7927f4 292{
56e52e85 293 char msg[512];
6a4bb04c 294 struct perf_evsel *pos;
d20deb64
ACM
295 struct perf_evlist *evlist = rec->evlist;
296 struct perf_session *session = rec->session;
b4006796 297 struct record_opts *opts = &rec->opts;
8d3eca20 298 int rc = 0;
dd7927f4 299
e68ae9cf 300 perf_evlist__config(evlist, opts, &callchain_param);
cac21425 301
0050f7aa 302 evlist__for_each(evlist, pos) {
dd7927f4 303try_again:
d988d5ee 304 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
56e52e85 305 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
d6d901c2 306 if (verbose)
c0a54341 307 ui__warning("%s\n", msg);
d6d901c2
ZY
308 goto try_again;
309 }
ca6a4258 310
56e52e85
ACM
311 rc = -errno;
312 perf_evsel__open_strerror(pos, &opts->target,
313 errno, msg, sizeof(msg));
314 ui__error("%s\n", msg);
8d3eca20 315 goto out;
c171b552
LZ
316 }
317 }
a43d3f08 318
23d4aad4
ACM
319 if (perf_evlist__apply_filters(evlist, &pos)) {
320 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
321 pos->filter, perf_evsel__name(pos), errno,
35550da3 322 strerror_r(errno, msg, sizeof(msg)));
8d3eca20
DA
323 rc = -1;
324 goto out;
0a102479
FW
325 }
326
ef149c25 327 if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
2dd6d8a1
AH
328 opts->auxtrace_mmap_pages,
329 opts->auxtrace_snapshot_mode) < 0) {
8d3eca20
DA
330 if (errno == EPERM) {
331 pr_err("Permission error mapping pages.\n"
332 "Consider increasing "
333 "/proc/sys/kernel/perf_event_mlock_kb,\n"
334 "or try again with a smaller value of -m/--mmap_pages.\n"
ef149c25
AH
335 "(current value: %u,%u)\n",
336 opts->mmap_pages, opts->auxtrace_mmap_pages);
8d3eca20 337 rc = -errno;
8d3eca20 338 } else {
35550da3
MH
339 pr_err("failed to mmap with %d (%s)\n", errno,
340 strerror_r(errno, msg, sizeof(msg)));
95c36561
WN
341 if (errno)
342 rc = -errno;
343 else
344 rc = -EINVAL;
8d3eca20
DA
345 }
346 goto out;
18e60939 347 }
0a27d7f9 348
563aecb2 349 session->evlist = evlist;
7b56cce2 350 perf_session__set_id_hdr_size(session);
8d3eca20
DA
351out:
352 return rc;
16c8a109
PZ
353}
354
e3d59112
NK
355static int process_sample_event(struct perf_tool *tool,
356 union perf_event *event,
357 struct perf_sample *sample,
358 struct perf_evsel *evsel,
359 struct machine *machine)
360{
361 struct record *rec = container_of(tool, struct record, tool);
362
363 rec->samples++;
364
365 return build_id__mark_dso_hit(tool, event, sample, evsel, machine);
366}
367
8c6f45a7 368static int process_buildids(struct record *rec)
6122e4e4 369{
f5fc1412
JO
370 struct perf_data_file *file = &rec->file;
371 struct perf_session *session = rec->session;
6122e4e4 372
457ae94a 373 if (file->size == 0)
9f591fd7
ACM
374 return 0;
375
00dc8657
NK
376 /*
377 * During this process, it'll load kernel map and replace the
378 * dso->long_name to a real pathname it found. In this case
379 * we prefer the vmlinux path like
380 * /lib/modules/3.16.4/build/vmlinux
381 *
382 * rather than build-id path (in debug directory).
383 * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551
384 */
385 symbol_conf.ignore_vmlinux_buildid = true;
386
6156681b
NK
387 /*
388 * If --buildid-all is given, it marks all DSO regardless of hits,
389 * so no need to process samples.
390 */
391 if (rec->buildid_all)
392 rec->tool.sample = NULL;
393
b7b61cbe 394 return perf_session__process_events(session);
6122e4e4
ACM
395}
396
8115d60c 397static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
a1645ce1
ZY
398{
399 int err;
45694aa7 400 struct perf_tool *tool = data;
a1645ce1
ZY
401 /*
402 *As for guest kernel when processing subcommand record&report,
403 *we arrange module mmap prior to guest kernel mmap and trigger
404 *a preload dso because default guest module symbols are loaded
405 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
406 *method is used to avoid symbol missing when the first addr is
407 *in module instead of in guest kernel.
408 */
45694aa7 409 err = perf_event__synthesize_modules(tool, process_synthesized_event,
743eb868 410 machine);
a1645ce1
ZY
411 if (err < 0)
412 pr_err("Couldn't record guest kernel [%d]'s reference"
23346f21 413 " relocation symbol.\n", machine->pid);
a1645ce1 414
a1645ce1
ZY
415 /*
416 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
417 * have no _text sometimes.
418 */
45694aa7 419 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
0ae617be 420 machine);
a1645ce1
ZY
421 if (err < 0)
422 pr_err("Couldn't record guest kernel [%d]'s reference"
23346f21 423 " relocation symbol.\n", machine->pid);
a1645ce1
ZY
424}
425
98402807
FW
426static struct perf_event_header finished_round_event = {
427 .size = sizeof(struct perf_event_header),
428 .type = PERF_RECORD_FINISHED_ROUND,
429};
430
8c6f45a7 431static int record__mmap_read_all(struct record *rec)
98402807 432{
dcabb507 433 u64 bytes_written = rec->bytes_written;
0e2e63dd 434 int i;
8d3eca20 435 int rc = 0;
98402807 436
d20deb64 437 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
ef149c25
AH
438 struct auxtrace_mmap *mm = &rec->evlist->mmap[i].auxtrace_mmap;
439
8d3eca20 440 if (rec->evlist->mmap[i].base) {
e5685730 441 if (record__mmap_read(rec, i) != 0) {
8d3eca20
DA
442 rc = -1;
443 goto out;
444 }
445 }
ef149c25 446
2dd6d8a1 447 if (mm->base && !rec->opts.auxtrace_snapshot_mode &&
ef149c25
AH
448 record__auxtrace_mmap_read(rec, mm) != 0) {
449 rc = -1;
450 goto out;
451 }
98402807
FW
452 }
453
dcabb507
JO
454 /*
455 * Mark the round finished in case we wrote
456 * at least one event.
457 */
458 if (bytes_written != rec->bytes_written)
459 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
8d3eca20
DA
460
461out:
462 return rc;
98402807
FW
463}
464
8c6f45a7 465static void record__init_features(struct record *rec)
57706abc 466{
57706abc
DA
467 struct perf_session *session = rec->session;
468 int feat;
469
470 for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
471 perf_header__set_feat(&session->header, feat);
472
473 if (rec->no_buildid)
474 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
475
3e2be2da 476 if (!have_tracepoints(&rec->evlist->entries))
57706abc
DA
477 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
478
479 if (!rec->opts.branch_stack)
480 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
ef149c25
AH
481
482 if (!rec->opts.full_auxtrace)
483 perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
ffa517ad
JO
484
485 perf_header__clear_feat(&session->header, HEADER_STAT);
57706abc
DA
486}
487
e1ab48ba
WN
488static void
489record__finish_output(struct record *rec)
490{
491 struct perf_data_file *file = &rec->file;
492 int fd = perf_data_file__fd(file);
493
494 if (file->is_pipe)
495 return;
496
497 rec->session->header.data_size += rec->bytes_written;
498 file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR);
499
500 if (!rec->no_buildid) {
501 process_buildids(rec);
502
503 if (rec->buildid_all)
504 dsos__hit_all(rec->session);
505 }
506 perf_session__write_header(rec->session, rec->evlist, fd, true);
507
508 return;
509}
510
be7b0c9e
WN
511static int record__synthesize_workload(struct record *rec)
512{
513 struct {
514 struct thread_map map;
515 struct thread_map_data map_data;
516 } thread_map;
517
518 thread_map.map.nr = 1;
519 thread_map.map.map[0].pid = rec->evlist->workload.pid;
520 thread_map.map.map[0].comm = NULL;
521 return perf_event__synthesize_thread_map(&rec->tool, &thread_map.map,
522 process_synthesized_event,
523 &rec->session->machines.host,
524 rec->opts.sample_address,
525 rec->opts.proc_map_timeout);
526}
527
3c1cb7e3
WN
528static int record__synthesize(struct record *rec);
529
ecfd7a9c
WN
530static int
531record__switch_output(struct record *rec, bool at_exit)
532{
533 struct perf_data_file *file = &rec->file;
534 int fd, err;
535
536 /* Same Size: "2015122520103046"*/
537 char timestamp[] = "InvalidTimestamp";
538
539 rec->samples = 0;
540 record__finish_output(rec);
541 err = fetch_current_timestamp(timestamp, sizeof(timestamp));
542 if (err) {
543 pr_err("Failed to get current timestamp\n");
544 return -EINVAL;
545 }
546
547 fd = perf_data_file__switch(file, timestamp,
548 rec->session->header.data_offset,
549 at_exit);
550 if (fd >= 0 && !at_exit) {
551 rec->bytes_written = 0;
552 rec->session->header.data_size = 0;
553 }
554
555 if (!quiet)
556 fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
557 file->path, timestamp);
3c1cb7e3
WN
558
559 /* Output tracking events */
be7b0c9e 560 if (!at_exit) {
3c1cb7e3
WN
561 record__synthesize(rec);
562
be7b0c9e
WN
563 /*
564 * In 'perf record --switch-output' without -a,
565 * record__synthesize() in record__switch_output() won't
566 * generate tracking events because there's no thread_map
567 * in evlist. Which causes newly created perf.data doesn't
568 * contain map and comm information.
569 * Create a fake thread_map and directly call
570 * perf_event__synthesize_thread_map() for those events.
571 */
572 if (target__none(&rec->opts.target))
573 record__synthesize_workload(rec);
574 }
ecfd7a9c
WN
575 return fd;
576}
577
f33cbe72
ACM
578static volatile int workload_exec_errno;
579
580/*
581 * perf_evlist__prepare_workload will send a SIGUSR1
582 * if the fork fails, since we asked by setting its
583 * want_signal to true.
584 */
45604710
NK
585static void workload_exec_failed_signal(int signo __maybe_unused,
586 siginfo_t *info,
f33cbe72
ACM
587 void *ucontext __maybe_unused)
588{
589 workload_exec_errno = info->si_value.sival_int;
590 done = 1;
f33cbe72
ACM
591 child_finished = 1;
592}
593
2dd6d8a1
AH
594static void snapshot_sig_handler(int sig);
595
46bc29b9
AH
596int __weak
597perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
598 struct perf_tool *tool __maybe_unused,
599 perf_event__handler_t process __maybe_unused,
600 struct machine *machine __maybe_unused)
601{
602 return 0;
603}
604
c45c86eb
WN
605static int record__synthesize(struct record *rec)
606{
607 struct perf_session *session = rec->session;
608 struct machine *machine = &session->machines.host;
609 struct perf_data_file *file = &rec->file;
610 struct record_opts *opts = &rec->opts;
611 struct perf_tool *tool = &rec->tool;
612 int fd = perf_data_file__fd(file);
613 int err = 0;
614
615 if (file->is_pipe) {
616 err = perf_event__synthesize_attrs(tool, session,
617 process_synthesized_event);
618 if (err < 0) {
619 pr_err("Couldn't synthesize attrs.\n");
620 goto out;
621 }
622
623 if (have_tracepoints(&rec->evlist->entries)) {
624 /*
625 * FIXME err <= 0 here actually means that
626 * there were no tracepoints so its not really
627 * an error, just that we don't need to
628 * synthesize anything. We really have to
629 * return this more properly and also
630 * propagate errors that now are calling die()
631 */
632 err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist,
633 process_synthesized_event);
634 if (err <= 0) {
635 pr_err("Couldn't record tracing data.\n");
636 goto out;
637 }
638 rec->bytes_written += err;
639 }
640 }
641
46bc29b9
AH
642 err = perf_event__synth_time_conv(rec->evlist->mmap[0].base, tool,
643 process_synthesized_event, machine);
644 if (err)
645 goto out;
646
c45c86eb
WN
647 if (rec->opts.full_auxtrace) {
648 err = perf_event__synthesize_auxtrace_info(rec->itr, tool,
649 session, process_synthesized_event);
650 if (err)
651 goto out;
652 }
653
654 err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
655 machine);
656 WARN_ONCE(err < 0, "Couldn't record kernel reference relocation symbol\n"
657 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
658 "Check /proc/kallsyms permission or run as root.\n");
659
660 err = perf_event__synthesize_modules(tool, process_synthesized_event,
661 machine);
662 WARN_ONCE(err < 0, "Couldn't record kernel module information.\n"
663 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
664 "Check /proc/modules permission or run as root.\n");
665
666 if (perf_guest) {
667 machines__process_guests(&session->machines,
668 perf_event__synthesize_guest_os, tool);
669 }
670
671 err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
672 process_synthesized_event, opts->sample_address,
673 opts->proc_map_timeout);
674out:
675 return err;
676}
677
8c6f45a7 678static int __cmd_record(struct record *rec, int argc, const char **argv)
16c8a109 679{
57706abc 680 int err;
45604710 681 int status = 0;
8b412664 682 unsigned long waking = 0;
46be604b 683 const bool forks = argc > 0;
23346f21 684 struct machine *machine;
45694aa7 685 struct perf_tool *tool = &rec->tool;
b4006796 686 struct record_opts *opts = &rec->opts;
f5fc1412 687 struct perf_data_file *file = &rec->file;
d20deb64 688 struct perf_session *session;
6dcf45ef 689 bool disabled = false, draining = false;
42aa276f 690 int fd;
de9ac07b 691
d20deb64 692 rec->progname = argv[0];
33e49ea7 693
45604710 694 atexit(record__sig_exit);
f5970550
PZ
695 signal(SIGCHLD, sig_handler);
696 signal(SIGINT, sig_handler);
804f7ac7 697 signal(SIGTERM, sig_handler);
c0bdc1c4 698
3c1cb7e3 699 if (rec->opts.auxtrace_snapshot_mode || rec->switch_output) {
2dd6d8a1 700 signal(SIGUSR2, snapshot_sig_handler);
3c1cb7e3
WN
701 if (rec->opts.auxtrace_snapshot_mode)
702 trigger_on(&auxtrace_snapshot_trigger);
703 if (rec->switch_output)
704 trigger_on(&switch_output_trigger);
c0bdc1c4 705 } else {
2dd6d8a1 706 signal(SIGUSR2, SIG_IGN);
c0bdc1c4 707 }
f5970550 708
b7b61cbe 709 session = perf_session__new(file, false, tool);
94c744b6 710 if (session == NULL) {
ffa91880 711 pr_err("Perf session creation failed.\n");
a9a70bbc
ACM
712 return -1;
713 }
714
42aa276f 715 fd = perf_data_file__fd(file);
d20deb64
ACM
716 rec->session = session;
717
8c6f45a7 718 record__init_features(rec);
330aa675 719
d4db3f16 720 if (forks) {
3e2be2da 721 err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
f5fc1412 722 argv, file->is_pipe,
735f7e0b 723 workload_exec_failed_signal);
35b9d88e
ACM
724 if (err < 0) {
725 pr_err("Couldn't run the workload!\n");
45604710 726 status = err;
35b9d88e 727 goto out_delete_session;
856e9660 728 }
856e9660
PZ
729 }
730
8c6f45a7 731 if (record__open(rec) != 0) {
8d3eca20 732 err = -1;
45604710 733 goto out_child;
8d3eca20 734 }
de9ac07b 735
8690a2a7
WN
736 err = bpf__apply_obj_config();
737 if (err) {
738 char errbuf[BUFSIZ];
739
740 bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
741 pr_err("ERROR: Apply config to BPF failed: %s\n",
742 errbuf);
743 goto out_child;
744 }
745
cca8482c
AH
746 /*
747 * Normally perf_session__new would do this, but it doesn't have the
748 * evlist.
749 */
750 if (rec->tool.ordered_events && !perf_evlist__sample_id_all(rec->evlist)) {
751 pr_warning("WARNING: No sample_id_all support, falling back to unordered processing\n");
752 rec->tool.ordered_events = false;
753 }
754
3e2be2da 755 if (!rec->evlist->nr_groups)
a8bb559b
NK
756 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
757
f5fc1412 758 if (file->is_pipe) {
42aa276f 759 err = perf_header__write_pipe(fd);
529870e3 760 if (err < 0)
45604710 761 goto out_child;
563aecb2 762 } else {
42aa276f 763 err = perf_session__write_header(session, rec->evlist, fd, false);
d5eed904 764 if (err < 0)
45604710 765 goto out_child;
56b03f3c
ACM
766 }
767
d3665498 768 if (!rec->no_buildid
e20960c0 769 && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
d3665498 770 pr_err("Couldn't generate buildids. "
e20960c0 771 "Use --no-buildid to profile anyway.\n");
8d3eca20 772 err = -1;
45604710 773 goto out_child;
e20960c0
RR
774 }
775
34ba5122 776 machine = &session->machines.host;
743eb868 777
c45c86eb
WN
778 err = record__synthesize(rec);
779 if (err < 0)
45604710 780 goto out_child;
8d3eca20 781
d20deb64 782 if (rec->realtime_prio) {
de9ac07b
PZ
783 struct sched_param param;
784
d20deb64 785 param.sched_priority = rec->realtime_prio;
de9ac07b 786 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
6beba7ad 787 pr_err("Could not set realtime priority.\n");
8d3eca20 788 err = -1;
45604710 789 goto out_child;
de9ac07b
PZ
790 }
791 }
792
774cb499
JO
793 /*
794 * When perf is starting the traced process, all the events
795 * (apart from group members) have enable_on_exec=1 set,
796 * so don't spoil it by prematurely enabling them.
797 */
6619a53e 798 if (!target__none(&opts->target) && !opts->initial_delay)
3e2be2da 799 perf_evlist__enable(rec->evlist);
764e16a3 800
856e9660
PZ
801 /*
802 * Let the child rip
803 */
e803cf97 804 if (forks) {
e5bed564
NK
805 union perf_event *event;
806
807 event = malloc(sizeof(event->comm) + machine->id_hdr_size);
808 if (event == NULL) {
809 err = -ENOMEM;
810 goto out_child;
811 }
812
e803cf97
NK
813 /*
814 * Some H/W events are generated before COMM event
815 * which is emitted during exec(), so perf script
816 * cannot see a correct process name for those events.
817 * Synthesize COMM event to prevent it.
818 */
e5bed564 819 perf_event__synthesize_comm(tool, event,
e803cf97
NK
820 rec->evlist->workload.pid,
821 process_synthesized_event,
822 machine);
e5bed564 823 free(event);
e803cf97 824
3e2be2da 825 perf_evlist__start_workload(rec->evlist);
e803cf97 826 }
856e9660 827
6619a53e
AK
828 if (opts->initial_delay) {
829 usleep(opts->initial_delay * 1000);
830 perf_evlist__enable(rec->evlist);
831 }
832
5f9cf599 833 trigger_ready(&auxtrace_snapshot_trigger);
3c1cb7e3 834 trigger_ready(&switch_output_trigger);
649c48a9 835 for (;;) {
9f065194 836 unsigned long long hits = rec->samples;
de9ac07b 837
8c6f45a7 838 if (record__mmap_read_all(rec) < 0) {
5f9cf599 839 trigger_error(&auxtrace_snapshot_trigger);
3c1cb7e3 840 trigger_error(&switch_output_trigger);
8d3eca20 841 err = -1;
45604710 842 goto out_child;
8d3eca20 843 }
de9ac07b 844
2dd6d8a1
AH
845 if (auxtrace_record__snapshot_started) {
846 auxtrace_record__snapshot_started = 0;
5f9cf599 847 if (!trigger_is_error(&auxtrace_snapshot_trigger))
2dd6d8a1 848 record__read_auxtrace_snapshot(rec);
5f9cf599 849 if (trigger_is_error(&auxtrace_snapshot_trigger)) {
2dd6d8a1
AH
850 pr_err("AUX area tracing snapshot failed\n");
851 err = -1;
852 goto out_child;
853 }
854 }
855
3c1cb7e3
WN
856 if (trigger_is_hit(&switch_output_trigger)) {
857 trigger_ready(&switch_output_trigger);
858
859 if (!quiet)
860 fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n",
861 waking);
862 waking = 0;
863 fd = record__switch_output(rec, false);
864 if (fd < 0) {
865 pr_err("Failed to switch to new file\n");
866 trigger_error(&switch_output_trigger);
867 err = fd;
868 goto out_child;
869 }
870 }
871
d20deb64 872 if (hits == rec->samples) {
6dcf45ef 873 if (done || draining)
649c48a9 874 break;
f66a889d 875 err = perf_evlist__poll(rec->evlist, -1);
a515114f
JO
876 /*
877 * Propagate error, only if there's any. Ignore positive
878 * number of returned events and interrupt error.
879 */
880 if (err > 0 || (err < 0 && errno == EINTR))
45604710 881 err = 0;
8b412664 882 waking++;
6dcf45ef
ACM
883
884 if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
885 draining = true;
8b412664
PZ
886 }
887
774cb499
JO
888 /*
889 * When perf is starting the traced process, at the end events
890 * die with the process and we wait for that. Thus no need to
891 * disable events in this case.
892 */
602ad878 893 if (done && !disabled && !target__none(&opts->target)) {
5f9cf599 894 trigger_off(&auxtrace_snapshot_trigger);
3e2be2da 895 perf_evlist__disable(rec->evlist);
2711926a
JO
896 disabled = true;
897 }
de9ac07b 898 }
5f9cf599 899 trigger_off(&auxtrace_snapshot_trigger);
3c1cb7e3 900 trigger_off(&switch_output_trigger);
de9ac07b 901
f33cbe72 902 if (forks && workload_exec_errno) {
35550da3 903 char msg[STRERR_BUFSIZE];
f33cbe72
ACM
904 const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
905 pr_err("Workload failed: %s\n", emsg);
906 err = -1;
45604710 907 goto out_child;
f33cbe72
ACM
908 }
909
e3d59112 910 if (!quiet)
45604710 911 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
b44308f5 912
45604710
NK
913out_child:
914 if (forks) {
915 int exit_status;
addc2785 916
45604710
NK
917 if (!child_finished)
918 kill(rec->evlist->workload.pid, SIGTERM);
919
920 wait(&exit_status);
921
922 if (err < 0)
923 status = err;
924 else if (WIFEXITED(exit_status))
925 status = WEXITSTATUS(exit_status);
926 else if (WIFSIGNALED(exit_status))
927 signr = WTERMSIG(exit_status);
928 } else
929 status = err;
930
e3d59112
NK
931 /* this will be recalculated during process_buildids() */
932 rec->samples = 0;
933
ecfd7a9c
WN
934 if (!err) {
935 if (!rec->timestamp_filename) {
936 record__finish_output(rec);
937 } else {
938 fd = record__switch_output(rec, true);
939 if (fd < 0) {
940 status = fd;
941 goto out_delete_session;
942 }
943 }
944 }
39d17dac 945
e3d59112
NK
946 if (!err && !quiet) {
947 char samples[128];
ecfd7a9c
WN
948 const char *postfix = rec->timestamp_filename ?
949 ".<timestamp>" : "";
e3d59112 950
ef149c25 951 if (rec->samples && !rec->opts.full_auxtrace)
e3d59112
NK
952 scnprintf(samples, sizeof(samples),
953 " (%" PRIu64 " samples)", rec->samples);
954 else
955 samples[0] = '\0';
956
ecfd7a9c 957 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
e3d59112 958 perf_data_file__size(file) / 1024.0 / 1024.0,
ecfd7a9c 959 file->path, postfix, samples);
e3d59112
NK
960 }
961
39d17dac
ACM
962out_delete_session:
963 perf_session__delete(session);
45604710 964 return status;
de9ac07b 965}
0e9b20b8 966
0883e820 967static void callchain_debug(struct callchain_param *callchain)
09b0fd45 968{
aad2b21c 969 static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
a601fdff 970
0883e820 971 pr_debug("callchain: type %s\n", str[callchain->record_mode]);
26d33022 972
0883e820 973 if (callchain->record_mode == CALLCHAIN_DWARF)
09b0fd45 974 pr_debug("callchain: stack dump size %d\n",
0883e820 975 callchain->dump_size);
09b0fd45
JO
976}
977
0883e820
ACM
978int record_opts__parse_callchain(struct record_opts *record,
979 struct callchain_param *callchain,
980 const char *arg, bool unset)
09b0fd45 981{
09b0fd45 982 int ret;
0883e820 983 callchain->enabled = !unset;
eb853e80 984
09b0fd45
JO
985 /* --no-call-graph */
986 if (unset) {
0883e820 987 callchain->record_mode = CALLCHAIN_NONE;
09b0fd45
JO
988 pr_debug("callchain: disabled\n");
989 return 0;
990 }
991
0883e820 992 ret = parse_callchain_record_opt(arg, callchain);
5c0cf224
JO
993 if (!ret) {
994 /* Enable data address sampling for DWARF unwind. */
0883e820 995 if (callchain->record_mode == CALLCHAIN_DWARF)
5c0cf224 996 record->sample_address = true;
0883e820 997 callchain_debug(callchain);
5c0cf224 998 }
26d33022
JO
999
1000 return ret;
1001}
1002
0883e820
ACM
1003int record_parse_callchain_opt(const struct option *opt,
1004 const char *arg,
1005 int unset)
1006{
1007 return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
1008}
1009
c421e80b 1010int record_callchain_opt(const struct option *opt,
09b0fd45
JO
1011 const char *arg __maybe_unused,
1012 int unset __maybe_unused)
1013{
2ddd5c04 1014 struct callchain_param *callchain = opt->value;
c421e80b 1015
2ddd5c04 1016 callchain->enabled = true;
09b0fd45 1017
2ddd5c04
ACM
1018 if (callchain->record_mode == CALLCHAIN_NONE)
1019 callchain->record_mode = CALLCHAIN_FP;
eb853e80 1020
2ddd5c04 1021 callchain_debug(callchain);
09b0fd45
JO
1022 return 0;
1023}
1024
eb853e80
JO
1025static int perf_record_config(const char *var, const char *value, void *cb)
1026{
7a29c087
NK
1027 struct record *rec = cb;
1028
1029 if (!strcmp(var, "record.build-id")) {
1030 if (!strcmp(value, "cache"))
1031 rec->no_buildid_cache = false;
1032 else if (!strcmp(value, "no-cache"))
1033 rec->no_buildid_cache = true;
1034 else if (!strcmp(value, "skip"))
1035 rec->no_buildid = true;
1036 else
1037 return -1;
1038 return 0;
1039 }
eb853e80 1040 if (!strcmp(var, "record.call-graph"))
5a2e5e85 1041 var = "call-graph.record-mode"; /* fall-through */
eb853e80
JO
1042
1043 return perf_default_config(var, value, cb);
1044}
1045
814c8c38
PZ
1046struct clockid_map {
1047 const char *name;
1048 int clockid;
1049};
1050
1051#define CLOCKID_MAP(n, c) \
1052 { .name = n, .clockid = (c), }
1053
1054#define CLOCKID_END { .name = NULL, }
1055
1056
1057/*
1058 * Add the missing ones, we need to build on many distros...
1059 */
1060#ifndef CLOCK_MONOTONIC_RAW
1061#define CLOCK_MONOTONIC_RAW 4
1062#endif
1063#ifndef CLOCK_BOOTTIME
1064#define CLOCK_BOOTTIME 7
1065#endif
1066#ifndef CLOCK_TAI
1067#define CLOCK_TAI 11
1068#endif
1069
1070static const struct clockid_map clockids[] = {
1071 /* available for all events, NMI safe */
1072 CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
1073 CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
1074
1075 /* available for some events */
1076 CLOCKID_MAP("realtime", CLOCK_REALTIME),
1077 CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
1078 CLOCKID_MAP("tai", CLOCK_TAI),
1079
1080 /* available for the lazy */
1081 CLOCKID_MAP("mono", CLOCK_MONOTONIC),
1082 CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
1083 CLOCKID_MAP("real", CLOCK_REALTIME),
1084 CLOCKID_MAP("boot", CLOCK_BOOTTIME),
1085
1086 CLOCKID_END,
1087};
1088
1089static int parse_clockid(const struct option *opt, const char *str, int unset)
1090{
1091 struct record_opts *opts = (struct record_opts *)opt->value;
1092 const struct clockid_map *cm;
1093 const char *ostr = str;
1094
1095 if (unset) {
1096 opts->use_clockid = 0;
1097 return 0;
1098 }
1099
1100 /* no arg passed */
1101 if (!str)
1102 return 0;
1103
1104 /* no setting it twice */
1105 if (opts->use_clockid)
1106 return -1;
1107
1108 opts->use_clockid = true;
1109
1110 /* if its a number, we're done */
1111 if (sscanf(str, "%d", &opts->clockid) == 1)
1112 return 0;
1113
1114 /* allow a "CLOCK_" prefix to the name */
1115 if (!strncasecmp(str, "CLOCK_", 6))
1116 str += 6;
1117
1118 for (cm = clockids; cm->name; cm++) {
1119 if (!strcasecmp(str, cm->name)) {
1120 opts->clockid = cm->clockid;
1121 return 0;
1122 }
1123 }
1124
1125 opts->use_clockid = false;
1126 ui__warning("unknown clockid %s, check man page\n", ostr);
1127 return -1;
1128}
1129
e9db1310
AH
1130static int record__parse_mmap_pages(const struct option *opt,
1131 const char *str,
1132 int unset __maybe_unused)
1133{
1134 struct record_opts *opts = opt->value;
1135 char *s, *p;
1136 unsigned int mmap_pages;
1137 int ret;
1138
1139 if (!str)
1140 return -EINVAL;
1141
1142 s = strdup(str);
1143 if (!s)
1144 return -ENOMEM;
1145
1146 p = strchr(s, ',');
1147 if (p)
1148 *p = '\0';
1149
1150 if (*s) {
1151 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, s);
1152 if (ret)
1153 goto out_free;
1154 opts->mmap_pages = mmap_pages;
1155 }
1156
1157 if (!p) {
1158 ret = 0;
1159 goto out_free;
1160 }
1161
1162 ret = __perf_evlist__parse_mmap_pages(&mmap_pages, p + 1);
1163 if (ret)
1164 goto out_free;
1165
1166 opts->auxtrace_mmap_pages = mmap_pages;
1167
1168out_free:
1169 free(s);
1170 return ret;
1171}
1172
e5b2c207 1173static const char * const __record_usage[] = {
9e096753
MG
1174 "perf record [<options>] [<command>]",
1175 "perf record [<options>] -- <command> [<options>]",
0e9b20b8
IM
1176 NULL
1177};
e5b2c207 1178const char * const *record_usage = __record_usage;
0e9b20b8 1179
d20deb64 1180/*
8c6f45a7
ACM
1181 * XXX Ideally would be local to cmd_record() and passed to a record__new
1182 * because we need to have access to it in record__exit, that is called
d20deb64
ACM
1183 * after cmd_record() exits, but since record_options need to be accessible to
1184 * builtin-script, leave it here.
1185 *
1186 * At least we don't ouch it in all the other functions here directly.
1187 *
1188 * Just say no to tons of global variables, sigh.
1189 */
8c6f45a7 1190static struct record record = {
d20deb64 1191 .opts = {
8affc2b8 1192 .sample_time = true,
d20deb64
ACM
1193 .mmap_pages = UINT_MAX,
1194 .user_freq = UINT_MAX,
1195 .user_interval = ULLONG_MAX,
447a6013 1196 .freq = 4000,
d1cb9fce
NK
1197 .target = {
1198 .uses_mmap = true,
3aa5939d 1199 .default_per_cpu = true,
d1cb9fce 1200 },
9d9cad76 1201 .proc_map_timeout = 500,
d20deb64 1202 },
e3d59112
NK
1203 .tool = {
1204 .sample = process_sample_event,
1205 .fork = perf_event__process_fork,
cca8482c 1206 .exit = perf_event__process_exit,
e3d59112
NK
1207 .comm = perf_event__process_comm,
1208 .mmap = perf_event__process_mmap,
1209 .mmap2 = perf_event__process_mmap2,
cca8482c 1210 .ordered_events = true,
e3d59112 1211 },
d20deb64 1212};
7865e817 1213
76a26549
NK
1214const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
1215 "\n\t\t\t\tDefault: fp";
61eaa3be 1216
d20deb64
ACM
1217/*
1218 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
1219 * with it and switch to use the library functions in perf_evlist that came
b4006796 1220 * from builtin-record.c, i.e. use record_opts,
d20deb64
ACM
1221 * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
1222 * using pipes, etc.
1223 */
e5b2c207 1224struct option __record_options[] = {
d20deb64 1225 OPT_CALLBACK('e', "event", &record.evlist, "event",
86847b62 1226 "event selector. use 'perf list' to list available events",
f120f9d5 1227 parse_events_option),
d20deb64 1228 OPT_CALLBACK(0, "filter", &record.evlist, "filter",
c171b552 1229 "event filter", parse_filter),
4ba1faa1
WN
1230 OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
1231 NULL, "don't record events from perf itself",
1232 exclude_perf),
bea03405 1233 OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
d6d901c2 1234 "record events on existing process id"),
bea03405 1235 OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
d6d901c2 1236 "record events on existing thread id"),
d20deb64 1237 OPT_INTEGER('r', "realtime", &record.realtime_prio,
0e9b20b8 1238 "collect data with this RT SCHED_FIFO priority"),
509051ea 1239 OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
acac03fa 1240 "collect data without buffering"),
d20deb64 1241 OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
daac07b2 1242 "collect raw sample records from all opened counters"),
bea03405 1243 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
0e9b20b8 1244 "system-wide collection from all CPUs"),
bea03405 1245 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
c45c6ea2 1246 "list of cpus to monitor"),
d20deb64 1247 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
f5fc1412 1248 OPT_STRING('o', "output", &record.file.path, "file",
abaff32a 1249 "output file name"),
69e7e5b0
AH
1250 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
1251 &record.opts.no_inherit_set,
1252 "child tasks do not inherit counters"),
d20deb64 1253 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
e9db1310
AH
1254 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
1255 "number of mmap data pages and AUX area tracing mmap pages",
1256 record__parse_mmap_pages),
d20deb64 1257 OPT_BOOLEAN(0, "group", &record.opts.group,
43bece79 1258 "put the counters into a counter group"),
2ddd5c04 1259 OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
09b0fd45
JO
1260 NULL, "enables call-graph recording" ,
1261 &record_callchain_opt),
1262 OPT_CALLBACK(0, "call-graph", &record.opts,
76a26549 1263 "record_mode[,record_size]", record_callchain_help,
09b0fd45 1264 &record_parse_callchain_opt),
c0555642 1265 OPT_INCR('v', "verbose", &verbose,
3da297a6 1266 "be more verbose (show counter open errors, etc)"),
b44308f5 1267 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
d20deb64 1268 OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
649c48a9 1269 "per thread counts"),
56100321 1270 OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
3abebc55
AH
1271 OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
1272 &record.opts.sample_time_set,
1273 "Record the sample timestamps"),
56100321 1274 OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
d20deb64 1275 OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
649c48a9 1276 "don't sample"),
d2db9a98
WN
1277 OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
1278 &record.no_buildid_cache_set,
1279 "do not update the buildid cache"),
1280 OPT_BOOLEAN_SET('B', "no-buildid", &record.no_buildid,
1281 &record.no_buildid_set,
1282 "do not collect buildids in perf.data"),
d20deb64 1283 OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
023695d9
SE
1284 "monitor event in cgroup name only",
1285 parse_cgroups),
a6205a35 1286 OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
6619a53e 1287 "ms to wait before starting measurement after program start"),
bea03405
NK
1288 OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
1289 "user to profile"),
a5aabdac
SE
1290
1291 OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack,
1292 "branch any", "sample any taken branches",
1293 parse_branch_stack),
1294
1295 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
1296 "branch filter mask", "branch stack filter modes",
bdfebd84 1297 parse_branch_stack),
05484298
AK
1298 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
1299 "sample by weight (on special events only)"),
475eeab9
AK
1300 OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
1301 "sample transaction flags (special events only)"),
3aa5939d
AH
1302 OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
1303 "use per-thread mmaps"),
bcc84ec6
SE
1304 OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
1305 "sample selected machine registers on interrupt,"
1306 " use -I ? to list register names", parse_regs),
85c273d2
AK
1307 OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
1308 "Record running/enabled time of read (:S) events"),
814c8c38
PZ
1309 OPT_CALLBACK('k', "clockid", &record.opts,
1310 "clockid", "clockid to use for events, see clock_gettime()",
1311 parse_clockid),
2dd6d8a1
AH
1312 OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
1313 "opts", "AUX area tracing Snapshot Mode", ""),
9d9cad76
KL
1314 OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
1315 "per thread proc mmap processing timeout in ms"),
b757bb09
AH
1316 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1317 "Record context switch events"),
85723885
JO
1318 OPT_BOOLEAN_FLAG(0, "all-kernel", &record.opts.all_kernel,
1319 "Configure all used events to run in kernel space.",
1320 PARSE_OPT_EXCLUSIVE),
1321 OPT_BOOLEAN_FLAG(0, "all-user", &record.opts.all_user,
1322 "Configure all used events to run in user space.",
1323 PARSE_OPT_EXCLUSIVE),
71dc2326
WN
1324 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
1325 "clang binary to use for compiling BPF scriptlets"),
1326 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
1327 "options passed to clang when compiling BPF scriptlets"),
7efe0e03
HK
1328 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
1329 "file", "vmlinux pathname"),
6156681b
NK
1330 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
1331 "Record build-id of all DSOs regardless of hits"),
ecfd7a9c
WN
1332 OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1333 "append timestamp to output filename"),
3c1cb7e3
WN
1334 OPT_BOOLEAN(0, "switch-output", &record.switch_output,
1335 "Switch output when receive SIGUSR2"),
0e9b20b8
IM
1336 OPT_END()
1337};
1338
e5b2c207
NK
1339struct option *record_options = __record_options;
1340
1d037ca1 1341int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
0e9b20b8 1342{
ef149c25 1343 int err;
8c6f45a7 1344 struct record *rec = &record;
16ad2ffb 1345 char errbuf[BUFSIZ];
0e9b20b8 1346
48e1cab1
WN
1347#ifndef HAVE_LIBBPF_SUPPORT
1348# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
1349 set_nobuild('\0', "clang-path", true);
1350 set_nobuild('\0', "clang-opt", true);
1351# undef set_nobuild
7efe0e03
HK
1352#endif
1353
1354#ifndef HAVE_BPF_PROLOGUE
1355# if !defined (HAVE_DWARF_SUPPORT)
1356# define REASON "NO_DWARF=1"
1357# elif !defined (HAVE_LIBBPF_SUPPORT)
1358# define REASON "NO_LIBBPF=1"
1359# else
1360# define REASON "this architecture doesn't support BPF prologue"
1361# endif
1362# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
1363 set_nobuild('\0', "vmlinux", true);
1364# undef set_nobuild
1365# undef REASON
48e1cab1
WN
1366#endif
1367
3e2be2da
ACM
1368 rec->evlist = perf_evlist__new();
1369 if (rec->evlist == NULL)
361c99a6
ACM
1370 return -ENOMEM;
1371
eb853e80
JO
1372 perf_config(perf_record_config, rec);
1373
bca647aa 1374 argc = parse_options(argc, argv, record_options, record_usage,
655000e7 1375 PARSE_OPT_STOP_AT_NON_OPTION);
602ad878 1376 if (!argc && target__none(&rec->opts.target))
bca647aa 1377 usage_with_options(record_usage, record_options);
0e9b20b8 1378
bea03405 1379 if (nr_cgroups && !rec->opts.target.system_wide) {
c7118369
NK
1380 usage_with_options_msg(record_usage, record_options,
1381 "cgroup monitoring only available in system-wide mode");
1382
023695d9 1383 }
b757bb09
AH
1384 if (rec->opts.record_switch_events &&
1385 !perf_can_record_switch_events()) {
c7118369
NK
1386 ui__error("kernel does not support recording context switch events\n");
1387 parse_options_usage(record_usage, record_options, "switch-events", 0);
1388 return -EINVAL;
b757bb09 1389 }
023695d9 1390
eca857ab
WN
1391 if (rec->switch_output)
1392 rec->timestamp_filename = true;
1393
ef149c25
AH
1394 if (!rec->itr) {
1395 rec->itr = auxtrace_record__init(rec->evlist, &err);
1396 if (err)
1397 return err;
1398 }
1399
2dd6d8a1
AH
1400 err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
1401 rec->opts.auxtrace_snapshot_opts);
1402 if (err)
1403 return err;
1404
d7888573
WN
1405 err = bpf__setup_stdout(rec->evlist);
1406 if (err) {
1407 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
1408 pr_err("ERROR: Setup BPF stdout failed: %s\n",
1409 errbuf);
1410 return err;
1411 }
1412
ef149c25
AH
1413 err = -ENOMEM;
1414
0a7e6d1b 1415 symbol__init(NULL);
baa2f6ce 1416
ec80fde7 1417 if (symbol_conf.kptr_restrict)
646aaea6
ACM
1418 pr_warning(
1419"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
1420"check /proc/sys/kernel/kptr_restrict.\n\n"
1421"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
1422"file is not found in the buildid cache or in the vmlinux path.\n\n"
1423"Samples in kernel modules won't be resolved at all.\n\n"
1424"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
1425"even with a suitable vmlinux or kallsyms file.\n\n");
ec80fde7 1426
0c1d46a8 1427 if (rec->no_buildid_cache || rec->no_buildid) {
a1ac1d3c 1428 disable_buildid_cache();
0c1d46a8
WN
1429 } else if (rec->switch_output) {
1430 /*
1431 * In 'perf record --switch-output', disable buildid
1432 * generation by default to reduce data file switching
1433 * overhead. Still generate buildid if they are required
1434 * explicitly using
1435 *
1436 * perf record --signal-trigger --no-no-buildid \
1437 * --no-no-buildid-cache
1438 *
1439 * Following code equals to:
1440 *
1441 * if ((rec->no_buildid || !rec->no_buildid_set) &&
1442 * (rec->no_buildid_cache || !rec->no_buildid_cache_set))
1443 * disable_buildid_cache();
1444 */
1445 bool disable = true;
1446
1447 if (rec->no_buildid_set && !rec->no_buildid)
1448 disable = false;
1449 if (rec->no_buildid_cache_set && !rec->no_buildid_cache)
1450 disable = false;
1451 if (disable) {
1452 rec->no_buildid = true;
1453 rec->no_buildid_cache = true;
1454 disable_buildid_cache();
1455 }
1456 }
655000e7 1457
3e2be2da
ACM
1458 if (rec->evlist->nr_entries == 0 &&
1459 perf_evlist__add_default(rec->evlist) < 0) {
69aad6f1
ACM
1460 pr_err("Not enough memory for event selector list\n");
1461 goto out_symbol_exit;
bbd36e5e 1462 }
0e9b20b8 1463
69e7e5b0
AH
1464 if (rec->opts.target.tid && !rec->opts.no_inherit_set)
1465 rec->opts.no_inherit = true;
1466
602ad878 1467 err = target__validate(&rec->opts.target);
16ad2ffb 1468 if (err) {
602ad878 1469 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
16ad2ffb
NK
1470 ui__warning("%s", errbuf);
1471 }
1472
602ad878 1473 err = target__parse_uid(&rec->opts.target);
16ad2ffb
NK
1474 if (err) {
1475 int saved_errno = errno;
4bd0f2d2 1476
602ad878 1477 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
3780f488 1478 ui__error("%s", errbuf);
16ad2ffb
NK
1479
1480 err = -saved_errno;
8fa60e1f 1481 goto out_symbol_exit;
16ad2ffb 1482 }
0d37aa34 1483
16ad2ffb 1484 err = -ENOMEM;
3e2be2da 1485 if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
dd7927f4 1486 usage_with_options(record_usage, record_options);
69aad6f1 1487
ef149c25
AH
1488 err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
1489 if (err)
1490 goto out_symbol_exit;
1491
6156681b
NK
1492 /*
1493 * We take all buildids when the file contains
1494 * AUX area tracing data because we do not decode the
1495 * trace because it would take too long.
1496 */
1497 if (rec->opts.full_auxtrace)
1498 rec->buildid_all = true;
1499
b4006796 1500 if (record_opts__config(&rec->opts)) {
39d17dac 1501 err = -EINVAL;
03ad9747 1502 goto out_symbol_exit;
7e4ff9e3
MG
1503 }
1504
d20deb64 1505 err = __cmd_record(&record, argc, argv);
d65a458b 1506out_symbol_exit:
45604710 1507 perf_evlist__delete(rec->evlist);
d65a458b 1508 symbol__exit();
ef149c25 1509 auxtrace_record__free(rec->itr);
39d17dac 1510 return err;
0e9b20b8 1511}
2dd6d8a1
AH
1512
1513static void snapshot_sig_handler(int sig __maybe_unused)
1514{
5f9cf599
WN
1515 if (trigger_is_ready(&auxtrace_snapshot_trigger)) {
1516 trigger_hit(&auxtrace_snapshot_trigger);
1517 auxtrace_record__snapshot_started = 1;
1518 if (auxtrace_record__snapshot_start(record.itr))
1519 trigger_error(&auxtrace_snapshot_trigger);
1520 }
3c1cb7e3
WN
1521
1522 if (trigger_is_ready(&switch_output_trigger))
1523 trigger_hit(&switch_output_trigger);
2dd6d8a1 1524}
This page took 0.355734 seconds and 5 git commands to generate.