diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 17c9ace445c4..93d355d27109 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1098,8 +1098,9 @@ volatile int session_done; static int __perf_session__process_pipe_events(struct perf_session *self, struct perf_tool *tool) { - union perf_event event; - uint32_t size; + union perf_event *event; + uint32_t size, cur_size = 0; + void *buf = NULL; int skip = 0; u64 head; int err; @@ -1108,8 +1109,14 @@ static int __perf_session__process_pipe_events(struct perf_session *self, perf_tool__fill_defaults(tool); head = 0; + cur_size = sizeof(union perf_event); + + buf = malloc(cur_size); + if (!buf) + return -errno; more: - err = readn(self->fd, &event, sizeof(struct perf_event_header)); + event = buf; + err = readn(self->fd, event, sizeof(struct perf_event_header)); if (err <= 0) { if (err == 0) goto done; @@ -1119,13 +1126,23 @@ static int __perf_session__process_pipe_events(struct perf_session *self, } if (self->header.needs_swap) - perf_event_header__bswap(&event.header); + perf_event_header__bswap(&event->header); - size = event.header.size; + size = event->header.size; if (size == 0) size = 8; - p = &event; + if (size > cur_size) { + void *new = realloc(buf, size); + if (!new) { + pr_err("failed to allocate memory to read event\n"); + goto out_err; + } + buf = new; + cur_size = size; + event = buf; + } + p = event; p += sizeof(struct perf_event_header); if (size - sizeof(struct perf_event_header)) { @@ -1141,9 +1158,9 @@ static int __perf_session__process_pipe_events(struct perf_session *self, } } - if ((skip = perf_session__process_event(self, &event, tool, head)) < 0) { + if ((skip = perf_session__process_event(self, event, tool, head)) < 0) { pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", - head, event.header.size, event.header.type); + head, event->header.size, event->header.type); err = -EINVAL; goto out_err; } @@ -1158,6 +1175,7 @@ static int __perf_session__process_pipe_events(struct perf_session *self, done: err = 0; out_err: + free(buf); perf_session__warn_about_errors(self, tool); perf_session_free_sample_buffers(self); return err;