]> git.karo-electronics.de Git - karo-tx-linux.git/blob - tools/perf/builtin-record.c
perf record: Prevent reading invalid data in record__mmap_read
[karo-tx-linux.git] / tools / perf / builtin-record.c
1 /*
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.
7  */
8 #include "builtin.h"
9
10 #include "perf.h"
11
12 #include "util/build-id.h"
13 #include "util/util.h"
14 #include <subcmd/parse-options.h>
15 #include "util/parse-events.h"
16
17 #include "util/callchain.h"
18 #include "util/cgroup.h"
19 #include "util/header.h"
20 #include "util/event.h"
21 #include "util/evlist.h"
22 #include "util/evsel.h"
23 #include "util/debug.h"
24 #include "util/session.h"
25 #include "util/tool.h"
26 #include "util/symbol.h"
27 #include "util/cpumap.h"
28 #include "util/thread_map.h"
29 #include "util/data.h"
30 #include "util/perf_regs.h"
31 #include "util/auxtrace.h"
32 #include "util/tsc.h"
33 #include "util/parse-branch-options.h"
34 #include "util/parse-regs-options.h"
35 #include "util/llvm-utils.h"
36 #include "util/bpf-loader.h"
37 #include "util/trigger.h"
38 #include "asm/bug.h"
39
40 #include <unistd.h>
41 #include <sched.h>
42 #include <sys/mman.h>
43 #include <asm/bug.h>
44
45
46 struct record {
47         struct perf_tool        tool;
48         struct record_opts      opts;
49         u64                     bytes_written;
50         struct perf_data_file   file;
51         struct auxtrace_record  *itr;
52         struct perf_evlist      *evlist;
53         struct perf_session     *session;
54         const char              *progname;
55         int                     realtime_prio;
56         bool                    no_buildid;
57         bool                    no_buildid_set;
58         bool                    no_buildid_cache;
59         bool                    no_buildid_cache_set;
60         bool                    buildid_all;
61         bool                    timestamp_filename;
62         bool                    switch_output;
63         unsigned long long      samples;
64 };
65
66 static int record__write(struct record *rec, void *bf, size_t size)
67 {
68         if (perf_data_file__write(rec->session->file, bf, size) < 0) {
69                 pr_err("failed to write perf data, error: %m\n");
70                 return -1;
71         }
72
73         rec->bytes_written += size;
74         return 0;
75 }
76
77 static int process_synthesized_event(struct perf_tool *tool,
78                                      union perf_event *event,
79                                      struct perf_sample *sample __maybe_unused,
80                                      struct machine *machine __maybe_unused)
81 {
82         struct record *rec = container_of(tool, struct record, tool);
83         return record__write(rec, event, event->header.size);
84 }
85
86 static int record__mmap_read(struct record *rec, int idx)
87 {
88         struct perf_mmap *md = &rec->evlist->mmap[idx];
89         u64 head = perf_mmap__read_head(md);
90         u64 old = md->prev;
91         unsigned char *data = md->base + page_size;
92         unsigned long size;
93         void *buf;
94         int rc = 0;
95
96         if (old == head)
97                 return 0;
98
99         rec->samples++;
100
101         size = head - old;
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         }
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;
114
115                 if (record__write(rec, buf, size) < 0) {
116                         rc = -1;
117                         goto out;
118                 }
119         }
120
121         buf = &data[old & md->mask];
122         size = head - old;
123         old += size;
124
125         if (record__write(rec, buf, size) < 0) {
126                 rc = -1;
127                 goto out;
128         }
129
130         md->prev = old;
131         perf_evlist__mmap_consume(rec->evlist, idx);
132 out:
133         return rc;
134 }
135
136 static volatile int done;
137 static volatile int signr = -1;
138 static volatile int child_finished;
139
140 static volatile int auxtrace_record__snapshot_started;
141 static DEFINE_TRIGGER(auxtrace_snapshot_trigger);
142 static DEFINE_TRIGGER(switch_output_trigger);
143
144 static 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
154 static void record__sig_exit(void)
155 {
156         if (signr == -1)
157                 return;
158
159         signal(signr, SIG_DFL);
160         raise(signr);
161 }
162
163 #ifdef HAVE_AUXTRACE_SUPPORT
164
165 static 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);
170         struct perf_data_file *file = &rec->file;
171         size_t padding;
172         u8 pad[8] = {0};
173
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
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
202 static 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
218 static 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
235 static 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         }
252 out:
253         return rc;
254 }
255
256 static 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) {
260                 trigger_error(&auxtrace_snapshot_trigger);
261         } else {
262                 if (auxtrace_record__snapshot_finish(rec->itr))
263                         trigger_error(&auxtrace_snapshot_trigger);
264                 else
265                         trigger_ready(&auxtrace_snapshot_trigger);
266         }
267 }
268
269 #else
270
271 static inline
272 int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
273                                struct auxtrace_mmap *mm __maybe_unused)
274 {
275         return 0;
276 }
277
278 static inline
279 void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
280 {
281 }
282
283 static inline
284 int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
285 {
286         return 0;
287 }
288
289 #endif
290
291 static int record__open(struct record *rec)
292 {
293         char msg[512];
294         struct perf_evsel *pos;
295         struct perf_evlist *evlist = rec->evlist;
296         struct perf_session *session = rec->session;
297         struct record_opts *opts = &rec->opts;
298         int rc = 0;
299
300         perf_evlist__config(evlist, opts, &callchain_param);
301
302         evlist__for_each(evlist, pos) {
303 try_again:
304                 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
305                         if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
306                                 if (verbose)
307                                         ui__warning("%s\n", msg);
308                                 goto try_again;
309                         }
310
311                         rc = -errno;
312                         perf_evsel__open_strerror(pos, &opts->target,
313                                                   errno, msg, sizeof(msg));
314                         ui__error("%s\n", msg);
315                         goto out;
316                 }
317         }
318
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,
322                         strerror_r(errno, msg, sizeof(msg)));
323                 rc = -1;
324                 goto out;
325         }
326
327         if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
328                                  opts->auxtrace_mmap_pages,
329                                  opts->auxtrace_snapshot_mode) < 0) {
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"
335                                "(current value: %u,%u)\n",
336                                opts->mmap_pages, opts->auxtrace_mmap_pages);
337                         rc = -errno;
338                 } else {
339                         pr_err("failed to mmap with %d (%s)\n", errno,
340                                 strerror_r(errno, msg, sizeof(msg)));
341                         if (errno)
342                                 rc = -errno;
343                         else
344                                 rc = -EINVAL;
345                 }
346                 goto out;
347         }
348
349         session->evlist = evlist;
350         perf_session__set_id_hdr_size(session);
351 out:
352         return rc;
353 }
354
355 static 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
368 static int process_buildids(struct record *rec)
369 {
370         struct perf_data_file *file  = &rec->file;
371         struct perf_session *session = rec->session;
372
373         if (file->size == 0)
374                 return 0;
375
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
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
394         return perf_session__process_events(session);
395 }
396
397 static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
398 {
399         int err;
400         struct perf_tool *tool = data;
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          */
409         err = perf_event__synthesize_modules(tool, process_synthesized_event,
410                                              machine);
411         if (err < 0)
412                 pr_err("Couldn't record guest kernel [%d]'s reference"
413                        " relocation symbol.\n", machine->pid);
414
415         /*
416          * We use _stext for guest kernel because guest kernel's /proc/kallsyms
417          * have no _text sometimes.
418          */
419         err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
420                                                  machine);
421         if (err < 0)
422                 pr_err("Couldn't record guest kernel [%d]'s reference"
423                        " relocation symbol.\n", machine->pid);
424 }
425
426 static struct perf_event_header finished_round_event = {
427         .size = sizeof(struct perf_event_header),
428         .type = PERF_RECORD_FINISHED_ROUND,
429 };
430
431 static int record__mmap_read_all(struct record *rec)
432 {
433         u64 bytes_written = rec->bytes_written;
434         int i;
435         int rc = 0;
436
437         for (i = 0; i < rec->evlist->nr_mmaps; i++) {
438                 struct auxtrace_mmap *mm = &rec->evlist->mmap[i].auxtrace_mmap;
439
440                 if (rec->evlist->mmap[i].base) {
441                         if (record__mmap_read(rec, i) != 0) {
442                                 rc = -1;
443                                 goto out;
444                         }
445                 }
446
447                 if (mm->base && !rec->opts.auxtrace_snapshot_mode &&
448                     record__auxtrace_mmap_read(rec, mm) != 0) {
449                         rc = -1;
450                         goto out;
451                 }
452         }
453
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));
460
461 out:
462         return rc;
463 }
464
465 static void record__init_features(struct record *rec)
466 {
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
476         if (!have_tracepoints(&rec->evlist->entries))
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);
481
482         if (!rec->opts.full_auxtrace)
483                 perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
484
485         perf_header__clear_feat(&session->header, HEADER_STAT);
486 }
487
488 static void
489 record__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
511 static 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
528 static int record__synthesize(struct record *rec);
529
530 static int
531 record__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);
558
559         /* Output tracking events */
560         if (!at_exit) {
561                 record__synthesize(rec);
562
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         }
575         return fd;
576 }
577
578 static 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  */
585 static void workload_exec_failed_signal(int signo __maybe_unused,
586                                         siginfo_t *info,
587                                         void *ucontext __maybe_unused)
588 {
589         workload_exec_errno = info->si_value.sival_int;
590         done = 1;
591         child_finished = 1;
592 }
593
594 static void snapshot_sig_handler(int sig);
595
596 int __weak
597 perf_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
605 static 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
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
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);
674 out:
675         return err;
676 }
677
678 static int __cmd_record(struct record *rec, int argc, const char **argv)
679 {
680         int err;
681         int status = 0;
682         unsigned long waking = 0;
683         const bool forks = argc > 0;
684         struct machine *machine;
685         struct perf_tool *tool = &rec->tool;
686         struct record_opts *opts = &rec->opts;
687         struct perf_data_file *file = &rec->file;
688         struct perf_session *session;
689         bool disabled = false, draining = false;
690         int fd;
691
692         rec->progname = argv[0];
693
694         atexit(record__sig_exit);
695         signal(SIGCHLD, sig_handler);
696         signal(SIGINT, sig_handler);
697         signal(SIGTERM, sig_handler);
698
699         if (rec->opts.auxtrace_snapshot_mode || rec->switch_output) {
700                 signal(SIGUSR2, snapshot_sig_handler);
701                 if (rec->opts.auxtrace_snapshot_mode)
702                         trigger_on(&auxtrace_snapshot_trigger);
703                 if (rec->switch_output)
704                         trigger_on(&switch_output_trigger);
705         } else {
706                 signal(SIGUSR2, SIG_IGN);
707         }
708
709         session = perf_session__new(file, false, tool);
710         if (session == NULL) {
711                 pr_err("Perf session creation failed.\n");
712                 return -1;
713         }
714
715         fd = perf_data_file__fd(file);
716         rec->session = session;
717
718         record__init_features(rec);
719
720         if (forks) {
721                 err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
722                                                     argv, file->is_pipe,
723                                                     workload_exec_failed_signal);
724                 if (err < 0) {
725                         pr_err("Couldn't run the workload!\n");
726                         status = err;
727                         goto out_delete_session;
728                 }
729         }
730
731         if (record__open(rec) != 0) {
732                 err = -1;
733                 goto out_child;
734         }
735
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
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
755         if (!rec->evlist->nr_groups)
756                 perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
757
758         if (file->is_pipe) {
759                 err = perf_header__write_pipe(fd);
760                 if (err < 0)
761                         goto out_child;
762         } else {
763                 err = perf_session__write_header(session, rec->evlist, fd, false);
764                 if (err < 0)
765                         goto out_child;
766         }
767
768         if (!rec->no_buildid
769             && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
770                 pr_err("Couldn't generate buildids. "
771                        "Use --no-buildid to profile anyway.\n");
772                 err = -1;
773                 goto out_child;
774         }
775
776         machine = &session->machines.host;
777
778         err = record__synthesize(rec);
779         if (err < 0)
780                 goto out_child;
781
782         if (rec->realtime_prio) {
783                 struct sched_param param;
784
785                 param.sched_priority = rec->realtime_prio;
786                 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
787                         pr_err("Could not set realtime priority.\n");
788                         err = -1;
789                         goto out_child;
790                 }
791         }
792
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          */
798         if (!target__none(&opts->target) && !opts->initial_delay)
799                 perf_evlist__enable(rec->evlist);
800
801         /*
802          * Let the child rip
803          */
804         if (forks) {
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
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                  */
819                 perf_event__synthesize_comm(tool, event,
820                                             rec->evlist->workload.pid,
821                                             process_synthesized_event,
822                                             machine);
823                 free(event);
824
825                 perf_evlist__start_workload(rec->evlist);
826         }
827
828         if (opts->initial_delay) {
829                 usleep(opts->initial_delay * 1000);
830                 perf_evlist__enable(rec->evlist);
831         }
832
833         trigger_ready(&auxtrace_snapshot_trigger);
834         trigger_ready(&switch_output_trigger);
835         for (;;) {
836                 unsigned long long hits = rec->samples;
837
838                 if (record__mmap_read_all(rec) < 0) {
839                         trigger_error(&auxtrace_snapshot_trigger);
840                         trigger_error(&switch_output_trigger);
841                         err = -1;
842                         goto out_child;
843                 }
844
845                 if (auxtrace_record__snapshot_started) {
846                         auxtrace_record__snapshot_started = 0;
847                         if (!trigger_is_error(&auxtrace_snapshot_trigger))
848                                 record__read_auxtrace_snapshot(rec);
849                         if (trigger_is_error(&auxtrace_snapshot_trigger)) {
850                                 pr_err("AUX area tracing snapshot failed\n");
851                                 err = -1;
852                                 goto out_child;
853                         }
854                 }
855
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
872                 if (hits == rec->samples) {
873                         if (done || draining)
874                                 break;
875                         err = perf_evlist__poll(rec->evlist, -1);
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))
881                                 err = 0;
882                         waking++;
883
884                         if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
885                                 draining = true;
886                 }
887
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                  */
893                 if (done && !disabled && !target__none(&opts->target)) {
894                         trigger_off(&auxtrace_snapshot_trigger);
895                         perf_evlist__disable(rec->evlist);
896                         disabled = true;
897                 }
898         }
899         trigger_off(&auxtrace_snapshot_trigger);
900         trigger_off(&switch_output_trigger);
901
902         if (forks && workload_exec_errno) {
903                 char msg[STRERR_BUFSIZE];
904                 const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
905                 pr_err("Workload failed: %s\n", emsg);
906                 err = -1;
907                 goto out_child;
908         }
909
910         if (!quiet)
911                 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
912
913 out_child:
914         if (forks) {
915                 int exit_status;
916
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
931         /* this will be recalculated during process_buildids() */
932         rec->samples = 0;
933
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         }
945
946         if (!err && !quiet) {
947                 char samples[128];
948                 const char *postfix = rec->timestamp_filename ?
949                                         ".<timestamp>" : "";
950
951                 if (rec->samples && !rec->opts.full_auxtrace)
952                         scnprintf(samples, sizeof(samples),
953                                   " (%" PRIu64 " samples)", rec->samples);
954                 else
955                         samples[0] = '\0';
956
957                 fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
958                         perf_data_file__size(file) / 1024.0 / 1024.0,
959                         file->path, postfix, samples);
960         }
961
962 out_delete_session:
963         perf_session__delete(session);
964         return status;
965 }
966
967 static void callchain_debug(struct callchain_param *callchain)
968 {
969         static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
970
971         pr_debug("callchain: type %s\n", str[callchain->record_mode]);
972
973         if (callchain->record_mode == CALLCHAIN_DWARF)
974                 pr_debug("callchain: stack dump size %d\n",
975                          callchain->dump_size);
976 }
977
978 int record_opts__parse_callchain(struct record_opts *record,
979                                  struct callchain_param *callchain,
980                                  const char *arg, bool unset)
981 {
982         int ret;
983         callchain->enabled = !unset;
984
985         /* --no-call-graph */
986         if (unset) {
987                 callchain->record_mode = CALLCHAIN_NONE;
988                 pr_debug("callchain: disabled\n");
989                 return 0;
990         }
991
992         ret = parse_callchain_record_opt(arg, callchain);
993         if (!ret) {
994                 /* Enable data address sampling for DWARF unwind. */
995                 if (callchain->record_mode == CALLCHAIN_DWARF)
996                         record->sample_address = true;
997                 callchain_debug(callchain);
998         }
999
1000         return ret;
1001 }
1002
1003 int 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
1010 int record_callchain_opt(const struct option *opt,
1011                          const char *arg __maybe_unused,
1012                          int unset __maybe_unused)
1013 {
1014         struct callchain_param *callchain = opt->value;
1015
1016         callchain->enabled = true;
1017
1018         if (callchain->record_mode == CALLCHAIN_NONE)
1019                 callchain->record_mode = CALLCHAIN_FP;
1020
1021         callchain_debug(callchain);
1022         return 0;
1023 }
1024
1025 static int perf_record_config(const char *var, const char *value, void *cb)
1026 {
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         }
1040         if (!strcmp(var, "record.call-graph"))
1041                 var = "call-graph.record-mode"; /* fall-through */
1042
1043         return perf_default_config(var, value, cb);
1044 }
1045
1046 struct 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
1070 static 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
1089 static 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
1130 static 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
1168 out_free:
1169         free(s);
1170         return ret;
1171 }
1172
1173 static const char * const __record_usage[] = {
1174         "perf record [<options>] [<command>]",
1175         "perf record [<options>] -- <command> [<options>]",
1176         NULL
1177 };
1178 const char * const *record_usage = __record_usage;
1179
1180 /*
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
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  */
1190 static struct record record = {
1191         .opts = {
1192                 .sample_time         = true,
1193                 .mmap_pages          = UINT_MAX,
1194                 .user_freq           = UINT_MAX,
1195                 .user_interval       = ULLONG_MAX,
1196                 .freq                = 4000,
1197                 .target              = {
1198                         .uses_mmap   = true,
1199                         .default_per_cpu = true,
1200                 },
1201                 .proc_map_timeout     = 500,
1202         },
1203         .tool = {
1204                 .sample         = process_sample_event,
1205                 .fork           = perf_event__process_fork,
1206                 .exit           = perf_event__process_exit,
1207                 .comm           = perf_event__process_comm,
1208                 .mmap           = perf_event__process_mmap,
1209                 .mmap2          = perf_event__process_mmap2,
1210                 .ordered_events = true,
1211         },
1212 };
1213
1214 const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
1215         "\n\t\t\t\tDefault: fp";
1216
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
1220  * from builtin-record.c, i.e. use record_opts,
1221  * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record',
1222  * using pipes, etc.
1223  */
1224 struct option __record_options[] = {
1225         OPT_CALLBACK('e', "event", &record.evlist, "event",
1226                      "event selector. use 'perf list' to list available events",
1227                      parse_events_option),
1228         OPT_CALLBACK(0, "filter", &record.evlist, "filter",
1229                      "event filter", parse_filter),
1230         OPT_CALLBACK_NOOPT(0, "exclude-perf", &record.evlist,
1231                            NULL, "don't record events from perf itself",
1232                            exclude_perf),
1233         OPT_STRING('p', "pid", &record.opts.target.pid, "pid",
1234                     "record events on existing process id"),
1235         OPT_STRING('t', "tid", &record.opts.target.tid, "tid",
1236                     "record events on existing thread id"),
1237         OPT_INTEGER('r', "realtime", &record.realtime_prio,
1238                     "collect data with this RT SCHED_FIFO priority"),
1239         OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
1240                     "collect data without buffering"),
1241         OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
1242                     "collect raw sample records from all opened counters"),
1243         OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
1244                             "system-wide collection from all CPUs"),
1245         OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
1246                     "list of cpus to monitor"),
1247         OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
1248         OPT_STRING('o', "output", &record.file.path, "file",
1249                     "output file name"),
1250         OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
1251                         &record.opts.no_inherit_set,
1252                         "child tasks do not inherit counters"),
1253         OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
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),
1257         OPT_BOOLEAN(0, "group", &record.opts.group,
1258                     "put the counters into a counter group"),
1259         OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
1260                            NULL, "enables call-graph recording" ,
1261                            &record_callchain_opt),
1262         OPT_CALLBACK(0, "call-graph", &record.opts,
1263                      "record_mode[,record_size]", record_callchain_help,
1264                      &record_parse_callchain_opt),
1265         OPT_INCR('v', "verbose", &verbose,
1266                     "be more verbose (show counter open errors, etc)"),
1267         OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
1268         OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
1269                     "per thread counts"),
1270         OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
1271         OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
1272                         &record.opts.sample_time_set,
1273                         "Record the sample timestamps"),
1274         OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
1275         OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
1276                     "don't sample"),
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"),
1283         OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
1284                      "monitor event in cgroup name only",
1285                      parse_cgroups),
1286         OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
1287                   "ms to wait before starting measurement after program start"),
1288         OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
1289                    "user to profile"),
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",
1297                      parse_branch_stack),
1298         OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
1299                     "sample by weight (on special events only)"),
1300         OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
1301                     "sample transaction flags (special events only)"),
1302         OPT_BOOLEAN(0, "per-thread", &record.opts.target.per_thread,
1303                     "use per-thread mmaps"),
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),
1307         OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
1308                     "Record running/enabled time of read (:S) events"),
1309         OPT_CALLBACK('k', "clockid", &record.opts,
1310         "clockid", "clockid to use for events, see clock_gettime()",
1311         parse_clockid),
1312         OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
1313                           "opts", "AUX area tracing Snapshot Mode", ""),
1314         OPT_UINTEGER(0, "proc-map-timeout", &record.opts.proc_map_timeout,
1315                         "per thread proc mmap processing timeout in ms"),
1316         OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1317                     "Record context switch events"),
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),
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"),
1328         OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
1329                    "file", "vmlinux pathname"),
1330         OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
1331                     "Record build-id of all DSOs regardless of hits"),
1332         OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
1333                     "append timestamp to output filename"),
1334         OPT_BOOLEAN(0, "switch-output", &record.switch_output,
1335                     "Switch output when receive SIGUSR2"),
1336         OPT_END()
1337 };
1338
1339 struct option *record_options = __record_options;
1340
1341 int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
1342 {
1343         int err;
1344         struct record *rec = &record;
1345         char errbuf[BUFSIZ];
1346
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
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
1366 #endif
1367
1368         rec->evlist = perf_evlist__new();
1369         if (rec->evlist == NULL)
1370                 return -ENOMEM;
1371
1372         perf_config(perf_record_config, rec);
1373
1374         argc = parse_options(argc, argv, record_options, record_usage,
1375                             PARSE_OPT_STOP_AT_NON_OPTION);
1376         if (!argc && target__none(&rec->opts.target))
1377                 usage_with_options(record_usage, record_options);
1378
1379         if (nr_cgroups && !rec->opts.target.system_wide) {
1380                 usage_with_options_msg(record_usage, record_options,
1381                         "cgroup monitoring only available in system-wide mode");
1382
1383         }
1384         if (rec->opts.record_switch_events &&
1385             !perf_can_record_switch_events()) {
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;
1389         }
1390
1391         if (rec->switch_output)
1392                 rec->timestamp_filename = true;
1393
1394         if (!rec->itr) {
1395                 rec->itr = auxtrace_record__init(rec->evlist, &err);
1396                 if (err)
1397                         return err;
1398         }
1399
1400         err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
1401                                               rec->opts.auxtrace_snapshot_opts);
1402         if (err)
1403                 return err;
1404
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
1413         err = -ENOMEM;
1414
1415         symbol__init(NULL);
1416
1417         if (symbol_conf.kptr_restrict)
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");
1426
1427         if (rec->no_buildid_cache || rec->no_buildid) {
1428                 disable_buildid_cache();
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         }
1457
1458         if (rec->evlist->nr_entries == 0 &&
1459             perf_evlist__add_default(rec->evlist) < 0) {
1460                 pr_err("Not enough memory for event selector list\n");
1461                 goto out_symbol_exit;
1462         }
1463
1464         if (rec->opts.target.tid && !rec->opts.no_inherit_set)
1465                 rec->opts.no_inherit = true;
1466
1467         err = target__validate(&rec->opts.target);
1468         if (err) {
1469                 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
1470                 ui__warning("%s", errbuf);
1471         }
1472
1473         err = target__parse_uid(&rec->opts.target);
1474         if (err) {
1475                 int saved_errno = errno;
1476
1477                 target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
1478                 ui__error("%s", errbuf);
1479
1480                 err = -saved_errno;
1481                 goto out_symbol_exit;
1482         }
1483
1484         err = -ENOMEM;
1485         if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
1486                 usage_with_options(record_usage, record_options);
1487
1488         err = auxtrace_record__options(rec->itr, rec->evlist, &rec->opts);
1489         if (err)
1490                 goto out_symbol_exit;
1491
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
1500         if (record_opts__config(&rec->opts)) {
1501                 err = -EINVAL;
1502                 goto out_symbol_exit;
1503         }
1504
1505         err = __cmd_record(&record, argc, argv);
1506 out_symbol_exit:
1507         perf_evlist__delete(rec->evlist);
1508         symbol__exit();
1509         auxtrace_record__free(rec->itr);
1510         return err;
1511 }
1512
1513 static void snapshot_sig_handler(int sig __maybe_unused)
1514 {
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         }
1521
1522         if (trigger_is_ready(&switch_output_trigger))
1523                 trigger_hit(&switch_output_trigger);
1524 }