struct perf_session *perf_session__new(const char *filename, int mode, bool force) { size_t len = filename ? strlen(filename) + 1 : 0; struct perf_session *self = zalloc(sizeof(*self) + len); if (self == NULL) goto out; if (perf_header__init(&self->header) < 0) goto out_free; memcpy(self->filename, filename, len); self->threads = RB_ROOT; self->last_match = NULL; self->mmap_window = 32; self->cwd = NULL; self->cwdlen = 0; self->unknown_events = 0; map_groups__init(&self->kmaps); if (mode == O_RDONLY) { if (perf_session__open(self, force) < 0) goto out_delete; } else if (mode == O_WRONLY) { /* * In O_RDONLY mode this will be performed when reading the * kernel MMAP event, in event__process_mmap(). */ if (perf_session__create_kernel_maps(self) < 0) goto out_delete; } self->sample_type = perf_header__sample_type(&self->header); out: return self; out_free: free(self); return NULL; out_delete: perf_session__delete(self); return NULL; }
static int __cmd_trace(void) { int ret, rc = EXIT_FAILURE; unsigned long offset = 0; unsigned long head = 0; struct stat perf_stat; event_t *event; uint32_t size; char *buf; trace_report(); register_idle_thread(&threads, &last_match); input = open(input_name, O_RDONLY); if (input < 0) { perror("failed to open file"); exit(-1); } ret = fstat(input, &perf_stat); if (ret < 0) { perror("failed to stat file"); exit(-1); } if (!perf_stat.st_size) { fprintf(stderr, "zero-sized file, nothing to do!\n"); exit(0); } header = perf_header__read(input); head = header->data_offset; sample_type = perf_header__sample_type(header); if (!(sample_type & PERF_SAMPLE_RAW)) die("No trace sample to read. Did you call perf record " "without -R?"); if (load_kernel() < 0) { perror("failed to load kernel symbols"); return EXIT_FAILURE; } remap: buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ, MAP_SHARED, input, offset); if (buf == MAP_FAILED) { perror("failed to mmap file"); exit(-1); } more: event = (event_t *)(buf + head); if (head + event->header.size >= page_size * mmap_window) { unsigned long shift = page_size * (head / page_size); int res; res = munmap(buf, page_size * mmap_window); assert(res == 0); offset += shift; head -= shift; goto remap; } size = event->header.size; if (!size || process_event(event, offset, head) < 0) { /* * assume we lost track of the stream, check alignment, and * increment a single u64 in the hope to catch on again 'soon'. */ if (unlikely(head & 7)) head &= ~7ULL; size = 8; } head += size; if (offset + head < (unsigned long)perf_stat.st_size) goto more; rc = EXIT_SUCCESS; close(input); return rc; }