static int __cmd_record(int argc, const char **argv) { int i, counter; struct stat st; pid_t pid = 0; int flags; int err; unsigned long waking = 0; page_size = sysconf(_SC_PAGE_SIZE); nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); assert(nr_cpus <= MAX_NR_CPUS); assert(nr_cpus >= 0); atexit(sig_atexit); signal(SIGCHLD, sig_handler); signal(SIGINT, sig_handler); if (!stat(output_name, &st) && st.st_size) { if (!force && !append_file) { fprintf(stderr, "Error, output file %s exists, use -A to append or -f to overwrite.\n", output_name); exit(-1); } } else { append_file = 0; } flags = O_CREAT|O_RDWR; if (append_file) file_new = 0; else flags |= O_TRUNC; output = open(output_name, flags, S_IRUSR|S_IWUSR); if (output < 0) { perror("failed to create output file"); exit(-1); } session = perf_session__new(output_name, O_WRONLY, force); if (session == NULL) { pr_err("Not enough memory for reading perf file header\n"); return -1; } if (!file_new) { err = perf_header__read(&session->header, output); if (err < 0) return err; } if (raw_samples) { perf_header__set_feat(&session->header, HEADER_TRACE_INFO); } else { for (i = 0; i < nr_counters; i++) { if (attrs[i].sample_type & PERF_SAMPLE_RAW) { perf_header__set_feat(&session->header, HEADER_TRACE_INFO); break; } } } atexit(atexit_header); if (!system_wide) { pid = target_pid; if (pid == -1) pid = getpid(); open_counters(profile_cpu, pid); } else { if (profile_cpu != -1) { open_counters(profile_cpu, target_pid); } else { for (i = 0; i < nr_cpus; i++) open_counters(i, target_pid); } } if (file_new) { err = perf_header__write(&session->header, output, false); if (err < 0) return err; } if (!system_wide) event__synthesize_thread(pid, process_synthesized_event); else event__synthesize_threads(process_synthesized_event); if (target_pid == -1 && argc) { pid = fork(); if (pid < 0) die("failed to fork"); if (!pid) { if (execvp(argv[0], (char **)argv)) { perror(argv[0]); exit(-1); } } else { /* * Wait a bit for the execv'ed child to appear * and be updated in /proc * FIXME: Do you know a less heuristical solution? */ usleep(1000); event__synthesize_thread(pid, process_synthesized_event); } child_pid = pid; } if (realtime_prio) { struct sched_param param; param.sched_priority = realtime_prio; if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { pr_err("Could not set realtime priority.\n"); exit(-1); } } for (;;) { int hits = samples; for (i = 0; i < nr_cpu; i++) { for (counter = 0; counter < nr_counters; counter++) { if (mmap_array[i][counter].base) mmap_read(&mmap_array[i][counter]); } } if (hits == samples) { if (done) break; err = poll(event_array, nr_poll, -1); waking++; } if (done) { for (i = 0; i < nr_cpu; i++) { for (counter = 0; counter < nr_counters; counter++) ioctl(fd[i][counter], PERF_EVENT_IOC_DISABLE); } } } fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); /* * Approximate RIP event size: 24 bytes. */ fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s (~%lld samples) ]\n", (double)bytes_written / 1024.0 / 1024.0, output_name, bytes_written / 24); return 0; }
static int __cmd_record(int argc, const char **argv) { int i, counter; struct stat st; pid_t pid = 0; int flags; int ret; unsigned long waking = 0; page_size = sysconf(_SC_PAGE_SIZE); nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); assert(nr_cpus <= MAX_NR_CPUS); assert(nr_cpus >= 0); atexit(sig_atexit); signal(SIGCHLD, sig_handler); signal(SIGINT, sig_handler); if (!stat(output_name, &st) && st.st_size) { if (!force && !append_file) { fprintf(stderr, "Error, output file %s exists, use -A to append or -f to overwrite.\n", output_name); exit(-1); } } else { append_file = 0; } flags = O_CREAT|O_RDWR; if (append_file) file_new = 0; else flags |= O_TRUNC; output = open(output_name, flags, S_IRUSR|S_IWUSR); if (output < 0) { perror("failed to create output file"); exit(-1); } if (!file_new) header = perf_header__read(output); else header = perf_header__new(); if (raw_samples) { read_tracing_data(attrs, nr_counters); } else { for (i = 0; i < nr_counters; i++) { if (attrs[i].sample_type & PERF_SAMPLE_RAW) { read_tracing_data(attrs, nr_counters); break; } } } atexit(atexit_header); if (!system_wide) { pid = target_pid; if (pid == -1) pid = getpid(); open_counters(profile_cpu, pid); } else { if (profile_cpu != -1) { open_counters(profile_cpu, target_pid); } else { for (i = 0; i < nr_cpus; i++) open_counters(i, target_pid); } } if (file_new) perf_header__write(header, output); if (!system_wide) { pid_t tgid = pid_synthesize_comm_event(pid, 0); pid_synthesize_mmap_samples(pid, tgid); } else synthesize_all(); if (target_pid == -1 && argc) { pid = fork(); if (pid < 0) perror("failed to fork"); if (!pid) { if (execvp(argv[0], (char **)argv)) { perror(argv[0]); exit(-1); } } child_pid = pid; } if (realtime_prio) { struct sched_param param; param.sched_priority = realtime_prio; if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { printf("Could not set realtime priority.\n"); exit(-1); } } for (;;) { int hits = samples; for (i = 0; i < nr_cpu; i++) { for (counter = 0; counter < nr_counters; counter++) { if (mmap_array[i][counter].base) mmap_read(&mmap_array[i][counter]); } } if (hits == samples) { if (done) break; ret = poll(event_array, nr_poll, -1); waking++; } if (done) { for (i = 0; i < nr_cpu; i++) { for (counter = 0; counter < nr_counters; counter++) ioctl(fd[i][counter], PERF_EVENT_IOC_DISABLE); } } } fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); /* * Approximate RIP event size: 24 bytes. */ fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s (~%lld samples) ]\n", (double)bytes_written / 1024.0 / 1024.0, output_name, bytes_written / 24); return 0; }
static void atexit_header(void) { session->header.data_size += bytes_written; perf_header__write(&session->header, output, true); }
static void atexit_header(void) { header->data_size += bytes_written; perf_header__write(header, output); }