]> bbs.cooldavid.org Git - net-next-2.6.git/blob - tools/perf/builtin-record.c
perf: Make the trace events sample period default to 1
[net-next-2.6.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 #define _FILE_OFFSET_BITS 64
9
10 #include "builtin.h"
11
12 #include "perf.h"
13
14 #include "util/build-id.h"
15 #include "util/util.h"
16 #include "util/parse-options.h"
17 #include "util/parse-events.h"
18
19 #include "util/header.h"
20 #include "util/event.h"
21 #include "util/debug.h"
22 #include "util/session.h"
23 #include "util/symbol.h"
24 #include "util/cpumap.h"
25
26 #include <unistd.h>
27 #include <sched.h>
28
29 enum write_mode_t {
30         WRITE_FORCE,
31         WRITE_APPEND
32 };
33
34 static int                      *fd[MAX_NR_CPUS][MAX_COUNTERS];
35
36 static unsigned int             user_interval                   = UINT_MAX;
37 static long                     default_interval                =      0;
38
39 static int                      nr_cpus                         =      0;
40 static unsigned int             page_size;
41 static unsigned int             mmap_pages                      =    128;
42 static unsigned int             user_freq                       = UINT_MAX;
43 static int                      freq                            =   1000;
44 static int                      output;
45 static const char               *output_name                    = "perf.data";
46 static int                      group                           =      0;
47 static unsigned int             realtime_prio                   =      0;
48 static bool                     raw_samples                     =  false;
49 static bool                     system_wide                     =  false;
50 static int                      profile_cpu                     =     -1;
51 static pid_t                    target_pid                      =     -1;
52 static pid_t                    target_tid                      =     -1;
53 static pid_t                    *all_tids                       =      NULL;
54 static int                      thread_num                      =      0;
55 static pid_t                    child_pid                       =     -1;
56 static bool                     inherit                         =   true;
57 static enum write_mode_t        write_mode                      = WRITE_FORCE;
58 static bool                     call_graph                      =  false;
59 static bool                     inherit_stat                    =  false;
60 static bool                     no_samples                      =  false;
61 static bool                     sample_address                  =  false;
62 static bool                     multiplex                       =  false;
63 static int                      multiplex_fd                    =     -1;
64
65 static long                     samples                         =      0;
66 static struct timeval           last_read;
67 static struct timeval           this_read;
68
69 static u64                      bytes_written                   =      0;
70
71 static struct pollfd            *event_array;
72
73 static int                      nr_poll                         =      0;
74 static int                      nr_cpu                          =      0;
75
76 static int                      file_new                        =      1;
77 static off_t                    post_processing_offset;
78
79 static struct perf_session      *session;
80
81 struct mmap_data {
82         int                     counter;
83         void                    *base;
84         unsigned int            mask;
85         unsigned int            prev;
86 };
87
88 static struct mmap_data         *mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
89
90 static unsigned long mmap_read_head(struct mmap_data *md)
91 {
92         struct perf_event_mmap_page *pc = md->base;
93         long head;
94
95         head = pc->data_head;
96         rmb();
97
98         return head;
99 }
100
101 static void mmap_write_tail(struct mmap_data *md, unsigned long tail)
102 {
103         struct perf_event_mmap_page *pc = md->base;
104
105         /*
106          * ensure all reads are done before we write the tail out.
107          */
108         /* mb(); */
109         pc->data_tail = tail;
110 }
111
112 static void write_output(void *buf, size_t size)
113 {
114         while (size) {
115                 int ret = write(output, buf, size);
116
117                 if (ret < 0)
118                         die("failed to write");
119
120                 size -= ret;
121                 buf += ret;
122
123                 bytes_written += ret;
124         }
125 }
126
127 static int process_synthesized_event(event_t *event,
128                                      struct perf_session *self __used)
129 {
130         write_output(event, event->header.size);
131         return 0;
132 }
133
134 static void mmap_read(struct mmap_data *md)
135 {
136         unsigned int head = mmap_read_head(md);
137         unsigned int old = md->prev;
138         unsigned char *data = md->base + page_size;
139         unsigned long size;
140         void *buf;
141         int diff;
142
143         gettimeofday(&this_read, NULL);
144
145         /*
146          * If we're further behind than half the buffer, there's a chance
147          * the writer will bite our tail and mess up the samples under us.
148          *
149          * If we somehow ended up ahead of the head, we got messed up.
150          *
151          * In either case, truncate and restart at head.
152          */
153         diff = head - old;
154         if (diff < 0) {
155                 struct timeval iv;
156                 unsigned long msecs;
157
158                 timersub(&this_read, &last_read, &iv);
159                 msecs = iv.tv_sec*1000 + iv.tv_usec/1000;
160
161                 fprintf(stderr, "WARNING: failed to keep up with mmap data."
162                                 "  Last read %lu msecs ago.\n", msecs);
163
164                 /*
165                  * head points to a known good entry, start there.
166                  */
167                 old = head;
168         }
169
170         last_read = this_read;
171
172         if (old != head)
173                 samples++;
174
175         size = head - old;
176
177         if ((old & md->mask) + size != (head & md->mask)) {
178                 buf = &data[old & md->mask];
179                 size = md->mask + 1 - (old & md->mask);
180                 old += size;
181
182                 write_output(buf, size);
183         }
184
185         buf = &data[old & md->mask];
186         size = head - old;
187         old += size;
188
189         write_output(buf, size);
190
191         md->prev = old;
192         mmap_write_tail(md, old);
193 }
194
195 static volatile int done = 0;
196 static volatile int signr = -1;
197
198 static void sig_handler(int sig)
199 {
200         done = 1;
201         signr = sig;
202 }
203
204 static void sig_atexit(void)
205 {
206         if (child_pid != -1)
207                 kill(child_pid, SIGTERM);
208
209         if (signr == -1)
210                 return;
211
212         signal(signr, SIG_DFL);
213         kill(getpid(), signr);
214 }
215
216 static int group_fd;
217
218 static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int nr)
219 {
220         struct perf_header_attr *h_attr;
221
222         if (nr < session->header.attrs) {
223                 h_attr = session->header.attr[nr];
224         } else {
225                 h_attr = perf_header_attr__new(a);
226                 if (h_attr != NULL)
227                         if (perf_header__add_attr(&session->header, h_attr) < 0) {
228                                 perf_header_attr__delete(h_attr);
229                                 h_attr = NULL;
230                         }
231         }
232
233         return h_attr;
234 }
235
236 static void create_counter(int counter, int cpu)
237 {
238         char *filter = filters[counter];
239         struct perf_event_attr *attr = attrs + counter;
240         struct perf_header_attr *h_attr;
241         int track = !counter; /* only the first counter needs these */
242         int thread_index;
243         int ret;
244         struct {
245                 u64 count;
246                 u64 time_enabled;
247                 u64 time_running;
248                 u64 id;
249         } read_data;
250
251         attr->read_format       = PERF_FORMAT_TOTAL_TIME_ENABLED |
252                                   PERF_FORMAT_TOTAL_TIME_RUNNING |
253                                   PERF_FORMAT_ID;
254
255         attr->sample_type       |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
256
257         if (nr_counters > 1)
258                 attr->sample_type |= PERF_SAMPLE_ID;
259
260         /*
261          * We default some events to a 1 default interval. But keep
262          * it a weak assumption overridable by the user.
263          */
264         if (!attr->sample_period || (user_freq != UINT_MAX &&
265                                      user_interval != UINT_MAX)) {
266                 if (freq) {
267                         attr->sample_type       |= PERF_SAMPLE_PERIOD;
268                         attr->freq              = 1;
269                         attr->sample_freq       = freq;
270                 } else {
271                         attr->sample_period = default_interval;
272                 }
273         }
274
275         if (no_samples)
276                 attr->sample_freq = 0;
277
278         if (inherit_stat)
279                 attr->inherit_stat = 1;
280
281         if (sample_address)
282                 attr->sample_type       |= PERF_SAMPLE_ADDR;
283
284         if (call_graph)
285                 attr->sample_type       |= PERF_SAMPLE_CALLCHAIN;
286
287         if (raw_samples) {
288                 attr->sample_type       |= PERF_SAMPLE_TIME;
289                 attr->sample_type       |= PERF_SAMPLE_RAW;
290                 attr->sample_type       |= PERF_SAMPLE_CPU;
291         }
292
293         attr->mmap              = track;
294         attr->comm              = track;
295         attr->inherit           = inherit;
296         if (target_pid == -1 && !system_wide) {
297                 attr->disabled = 1;
298                 attr->enable_on_exec = 1;
299         }
300
301         for (thread_index = 0; thread_index < thread_num; thread_index++) {
302 try_again:
303                 fd[nr_cpu][counter][thread_index] = sys_perf_event_open(attr,
304                                 all_tids[thread_index], cpu, group_fd, 0);
305
306                 if (fd[nr_cpu][counter][thread_index] < 0) {
307                         int err = errno;
308
309                         if (err == EPERM || err == EACCES)
310                                 die("Permission error - are you root?\n"
311                                         "\t Consider tweaking"
312                                         " /proc/sys/kernel/perf_event_paranoid.\n");
313                         else if (err ==  ENODEV && profile_cpu != -1) {
314                                 die("No such device - did you specify"
315                                         " an out-of-range profile CPU?\n");
316                         }
317
318                         /*
319                          * If it's cycles then fall back to hrtimer
320                          * based cpu-clock-tick sw counter, which
321                          * is always available even if no PMU support:
322                          */
323                         if (attr->type == PERF_TYPE_HARDWARE
324                                         && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
325
326                                 if (verbose)
327                                         warning(" ... trying to fall back to cpu-clock-ticks\n");
328                                 attr->type = PERF_TYPE_SOFTWARE;
329                                 attr->config = PERF_COUNT_SW_CPU_CLOCK;
330                                 goto try_again;
331                         }
332                         printf("\n");
333                         error("perfcounter syscall returned with %d (%s)\n",
334                                         fd[nr_cpu][counter][thread_index], strerror(err));
335
336 #if defined(__i386__) || defined(__x86_64__)
337                         if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP)
338                                 die("No hardware sampling interrupt available."
339                                     " No APIC? If so then you can boot the kernel"
340                                     " with the \"lapic\" boot parameter to"
341                                     " force-enable it.\n");
342 #endif
343
344                         die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
345                         exit(-1);
346                 }
347
348                 h_attr = get_header_attr(attr, counter);
349                 if (h_attr == NULL)
350                         die("nomem\n");
351
352                 if (!file_new) {
353                         if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
354                                 fprintf(stderr, "incompatible append\n");
355                                 exit(-1);
356                         }
357                 }
358
359                 if (read(fd[nr_cpu][counter][thread_index], &read_data, sizeof(read_data)) == -1) {
360                         perror("Unable to read perf file descriptor\n");
361                         exit(-1);
362                 }
363
364                 if (perf_header_attr__add_id(h_attr, read_data.id) < 0) {
365                         pr_warning("Not enough memory to add id\n");
366                         exit(-1);
367                 }
368
369                 assert(fd[nr_cpu][counter][thread_index] >= 0);
370                 fcntl(fd[nr_cpu][counter][thread_index], F_SETFL, O_NONBLOCK);
371
372                 /*
373                  * First counter acts as the group leader:
374                  */
375                 if (group && group_fd == -1)
376                         group_fd = fd[nr_cpu][counter][thread_index];
377                 if (multiplex && multiplex_fd == -1)
378                         multiplex_fd = fd[nr_cpu][counter][thread_index];
379
380                 if (multiplex && fd[nr_cpu][counter][thread_index] != multiplex_fd) {
381
382                         ret = ioctl(fd[nr_cpu][counter][thread_index], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
383                         assert(ret != -1);
384                 } else {
385                         event_array[nr_poll].fd = fd[nr_cpu][counter][thread_index];
386                         event_array[nr_poll].events = POLLIN;
387                         nr_poll++;
388
389                         mmap_array[nr_cpu][counter][thread_index].counter = counter;
390                         mmap_array[nr_cpu][counter][thread_index].prev = 0;
391                         mmap_array[nr_cpu][counter][thread_index].mask = mmap_pages*page_size - 1;
392                         mmap_array[nr_cpu][counter][thread_index].base = mmap(NULL, (mmap_pages+1)*page_size,
393                                 PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter][thread_index], 0);
394                         if (mmap_array[nr_cpu][counter][thread_index].base == MAP_FAILED) {
395                                 error("failed to mmap with %d (%s)\n", errno, strerror(errno));
396                                 exit(-1);
397                         }
398                 }
399
400                 if (filter != NULL) {
401                         ret = ioctl(fd[nr_cpu][counter][thread_index],
402                                         PERF_EVENT_IOC_SET_FILTER, filter);
403                         if (ret) {
404                                 error("failed to set filter with %d (%s)\n", errno,
405                                                 strerror(errno));
406                                 exit(-1);
407                         }
408                 }
409         }
410 }
411
412 static void open_counters(int cpu)
413 {
414         int counter;
415
416         group_fd = -1;
417         for (counter = 0; counter < nr_counters; counter++)
418                 create_counter(counter, cpu);
419
420         nr_cpu++;
421 }
422
423 static int process_buildids(void)
424 {
425         u64 size = lseek(output, 0, SEEK_CUR);
426
427         if (size == 0)
428                 return 0;
429
430         session->fd = output;
431         return __perf_session__process_events(session, post_processing_offset,
432                                               size - post_processing_offset,
433                                               size, &build_id__mark_dso_hit_ops);
434 }
435
436 static void atexit_header(void)
437 {
438         session->header.data_size += bytes_written;
439
440         process_buildids();
441         perf_header__write(&session->header, output, true);
442 }
443
444 static int __cmd_record(int argc, const char **argv)
445 {
446         int i, counter;
447         struct stat st;
448         pid_t pid = 0;
449         int flags;
450         int err;
451         unsigned long waking = 0;
452         int child_ready_pipe[2], go_pipe[2];
453         const bool forks = argc > 0;
454         char buf;
455
456         page_size = sysconf(_SC_PAGE_SIZE);
457
458         atexit(sig_atexit);
459         signal(SIGCHLD, sig_handler);
460         signal(SIGINT, sig_handler);
461
462         if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
463                 perror("failed to create pipes");
464                 exit(-1);
465         }
466
467         if (!stat(output_name, &st) && st.st_size) {
468                 if (write_mode == WRITE_FORCE) {
469                         char oldname[PATH_MAX];
470                         snprintf(oldname, sizeof(oldname), "%s.old",
471                                  output_name);
472                         unlink(oldname);
473                         rename(output_name, oldname);
474                 }
475         } else if (write_mode == WRITE_APPEND) {
476                 write_mode = WRITE_FORCE;
477         }
478
479         flags = O_CREAT|O_RDWR;
480         if (write_mode == WRITE_APPEND)
481                 file_new = 0;
482         else
483                 flags |= O_TRUNC;
484
485         output = open(output_name, flags, S_IRUSR|S_IWUSR);
486         if (output < 0) {
487                 perror("failed to create output file");
488                 exit(-1);
489         }
490
491         session = perf_session__new(output_name, O_WRONLY,
492                                     write_mode == WRITE_FORCE);
493         if (session == NULL) {
494                 pr_err("Not enough memory for reading perf file header\n");
495                 return -1;
496         }
497
498         if (!file_new) {
499                 err = perf_header__read(&session->header, output);
500                 if (err < 0)
501                         return err;
502         }
503
504         if (raw_samples) {
505                 perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
506         } else {
507                 for (i = 0; i < nr_counters; i++) {
508                         if (attrs[i].sample_type & PERF_SAMPLE_RAW) {
509                                 perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
510                                 break;
511                         }
512                 }
513         }
514
515         atexit(atexit_header);
516
517         if (forks) {
518                 child_pid = fork();
519                 if (pid < 0) {
520                         perror("failed to fork");
521                         exit(-1);
522                 }
523
524                 if (!child_pid) {
525                         close(child_ready_pipe[0]);
526                         close(go_pipe[1]);
527                         fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
528
529                         /*
530                          * Do a dummy execvp to get the PLT entry resolved,
531                          * so we avoid the resolver overhead on the real
532                          * execvp call.
533                          */
534                         execvp("", (char **)argv);
535
536                         /*
537                          * Tell the parent we're ready to go
538                          */
539                         close(child_ready_pipe[1]);
540
541                         /*
542                          * Wait until the parent tells us to go.
543                          */
544                         if (read(go_pipe[0], &buf, 1) == -1)
545                                 perror("unable to read pipe");
546
547                         execvp(argv[0], (char **)argv);
548
549                         perror(argv[0]);
550                         exit(-1);
551                 }
552
553                 if (!system_wide && target_tid == -1 && target_pid == -1)
554                         all_tids[0] = child_pid;
555
556                 close(child_ready_pipe[1]);
557                 close(go_pipe[0]);
558                 /*
559                  * wait for child to settle
560                  */
561                 if (read(child_ready_pipe[0], &buf, 1) == -1) {
562                         perror("unable to read pipe");
563                         exit(-1);
564                 }
565                 close(child_ready_pipe[0]);
566         }
567
568         if ((!system_wide && !inherit) || profile_cpu != -1) {
569                 open_counters(profile_cpu);
570         } else {
571                 nr_cpus = read_cpu_map();
572                 for (i = 0; i < nr_cpus; i++)
573                         open_counters(cpumap[i]);
574         }
575
576         if (file_new) {
577                 err = perf_header__write(&session->header, output, false);
578                 if (err < 0)
579                         return err;
580         }
581
582         post_processing_offset = lseek(output, 0, SEEK_CUR);
583
584         err = event__synthesize_kernel_mmap(process_synthesized_event,
585                                             session, "_text");
586         if (err < 0)
587                 err = event__synthesize_kernel_mmap(process_synthesized_event,
588                                                     session, "_stext");
589         if (err < 0) {
590                 pr_err("Couldn't record kernel reference relocation symbol.\n");
591                 return err;
592         }
593
594         err = event__synthesize_modules(process_synthesized_event, session);
595         if (err < 0) {
596                 pr_err("Couldn't record kernel reference relocation symbol.\n");
597                 return err;
598         }
599
600         if (!system_wide && profile_cpu == -1)
601                 event__synthesize_thread(target_tid, process_synthesized_event,
602                                          session);
603         else
604                 event__synthesize_threads(process_synthesized_event, session);
605
606         if (realtime_prio) {
607                 struct sched_param param;
608
609                 param.sched_priority = realtime_prio;
610                 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
611                         pr_err("Could not set realtime priority.\n");
612                         exit(-1);
613                 }
614         }
615
616         /*
617          * Let the child rip
618          */
619         if (forks)
620                 close(go_pipe[1]);
621
622         for (;;) {
623                 int hits = samples;
624                 int thread;
625
626                 for (i = 0; i < nr_cpu; i++) {
627                         for (counter = 0; counter < nr_counters; counter++) {
628                                 for (thread = 0;
629                                         thread < thread_num; thread++) {
630                                         if (mmap_array[i][counter][thread].base)
631                                                 mmap_read(&mmap_array[i][counter][thread]);
632                                 }
633
634                         }
635                 }
636
637                 if (hits == samples) {
638                         if (done)
639                                 break;
640                         err = poll(event_array, nr_poll, -1);
641                         waking++;
642                 }
643
644                 if (done) {
645                         for (i = 0; i < nr_cpu; i++) {
646                                 for (counter = 0;
647                                         counter < nr_counters;
648                                         counter++) {
649                                         for (thread = 0;
650                                                 thread < thread_num;
651                                                 thread++)
652                                                 ioctl(fd[i][counter][thread],
653                                                         PERF_EVENT_IOC_DISABLE);
654                                 }
655                         }
656                 }
657         }
658
659         fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
660
661         /*
662          * Approximate RIP event size: 24 bytes.
663          */
664         fprintf(stderr,
665                 "[ perf record: Captured and wrote %.3f MB %s (~%lld samples) ]\n",
666                 (double)bytes_written / 1024.0 / 1024.0,
667                 output_name,
668                 bytes_written / 24);
669
670         return 0;
671 }
672
673 static const char * const record_usage[] = {
674         "perf record [<options>] [<command>]",
675         "perf record [<options>] -- <command> [<options>]",
676         NULL
677 };
678
679 static bool force, append_file;
680
681 static const struct option options[] = {
682         OPT_CALLBACK('e', "event", NULL, "event",
683                      "event selector. use 'perf list' to list available events",
684                      parse_events),
685         OPT_CALLBACK(0, "filter", NULL, "filter",
686                      "event filter", parse_filter),
687         OPT_INTEGER('p', "pid", &target_pid,
688                     "record events on existing process id"),
689         OPT_INTEGER('t', "tid", &target_tid,
690                     "record events on existing thread id"),
691         OPT_INTEGER('r', "realtime", &realtime_prio,
692                     "collect data with this RT SCHED_FIFO priority"),
693         OPT_BOOLEAN('R', "raw-samples", &raw_samples,
694                     "collect raw sample records from all opened counters"),
695         OPT_BOOLEAN('a', "all-cpus", &system_wide,
696                             "system-wide collection from all CPUs"),
697         OPT_BOOLEAN('A', "append", &append_file,
698                             "append to the output file to do incremental profiling"),
699         OPT_INTEGER('C', "profile_cpu", &profile_cpu,
700                             "CPU to profile on"),
701         OPT_BOOLEAN('f', "force", &force,
702                         "overwrite existing data file (deprecated)"),
703         OPT_LONG('c', "count", &user_interval,
704                     "event period to sample"),
705         OPT_STRING('o', "output", &output_name, "file",
706                     "output file name"),
707         OPT_BOOLEAN('i', "inherit", &inherit,
708                     "child tasks inherit counters"),
709         OPT_INTEGER('F', "freq", &user_freq,
710                     "profile at this frequency"),
711         OPT_INTEGER('m', "mmap-pages", &mmap_pages,
712                     "number of mmap data pages"),
713         OPT_BOOLEAN('g', "call-graph", &call_graph,
714                     "do call-graph (stack chain/backtrace) recording"),
715         OPT_INCR('v', "verbose", &verbose,
716                     "be more verbose (show counter open errors, etc)"),
717         OPT_BOOLEAN('s', "stat", &inherit_stat,
718                     "per thread counts"),
719         OPT_BOOLEAN('d', "data", &sample_address,
720                     "Sample addresses"),
721         OPT_BOOLEAN('n', "no-samples", &no_samples,
722                     "don't sample"),
723         OPT_BOOLEAN('M', "multiplex", &multiplex,
724                     "multiplex counter output in a single channel"),
725         OPT_END()
726 };
727
728 int cmd_record(int argc, const char **argv, const char *prefix __used)
729 {
730         int i,j;
731
732         argc = parse_options(argc, argv, options, record_usage,
733                             PARSE_OPT_STOP_AT_NON_OPTION);
734         if (!argc && target_pid == -1 && target_tid == -1 &&
735                 !system_wide && profile_cpu == -1)
736                 usage_with_options(record_usage, options);
737
738         if (force && append_file) {
739                 fprintf(stderr, "Can't overwrite and append at the same time."
740                                 " You need to choose between -f and -A");
741                 usage_with_options(record_usage, options);
742         } else if (append_file) {
743                 write_mode = WRITE_APPEND;
744         } else {
745                 write_mode = WRITE_FORCE;
746         }
747
748         symbol__init();
749
750         if (!nr_counters) {
751                 nr_counters     = 1;
752                 attrs[0].type   = PERF_TYPE_HARDWARE;
753                 attrs[0].config = PERF_COUNT_HW_CPU_CYCLES;
754         }
755
756         if (target_pid != -1) {
757                 target_tid = target_pid;
758                 thread_num = find_all_tid(target_pid, &all_tids);
759                 if (thread_num <= 0) {
760                         fprintf(stderr, "Can't find all threads of pid %d\n",
761                                         target_pid);
762                         usage_with_options(record_usage, options);
763                 }
764         } else {
765                 all_tids=malloc(sizeof(pid_t));
766                 if (!all_tids)
767                         return -ENOMEM;
768
769                 all_tids[0] = target_tid;
770                 thread_num = 1;
771         }
772
773         for (i = 0; i < MAX_NR_CPUS; i++) {
774                 for (j = 0; j < MAX_COUNTERS; j++) {
775                         fd[i][j] = malloc(sizeof(int)*thread_num);
776                         mmap_array[i][j] = zalloc(
777                                 sizeof(struct mmap_data)*thread_num);
778                         if (!fd[i][j] || !mmap_array[i][j])
779                                 return -ENOMEM;
780                 }
781         }
782         event_array = malloc(
783                 sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num);
784         if (!event_array)
785                 return -ENOMEM;
786
787         if (user_interval != UINT_MAX)
788                 default_interval = user_interval;
789         if (user_freq != UINT_MAX)
790                 freq = user_freq;
791
792         /*
793          * User specified count overrides default frequency.
794          */
795         if (default_interval)
796                 freq = 0;
797         else if (freq) {
798                 default_interval = freq;
799         } else {
800                 fprintf(stderr, "frequency and count are zero, aborting\n");
801                 exit(EXIT_FAILURE);
802         }
803
804         return __cmd_record(argc, argv);
805 }