diff options
-rw-r--r-- | tools/perf/util/session.c | 34 |
1 files changed, 26 insertions, 8 deletions
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; | |||
1098 | static int __perf_session__process_pipe_events(struct perf_session *self, | 1098 | static int __perf_session__process_pipe_events(struct perf_session *self, |
1099 | struct perf_tool *tool) | 1099 | struct perf_tool *tool) |
1100 | { | 1100 | { |
1101 | union perf_event event; | 1101 | union perf_event *event; |
1102 | uint32_t size; | 1102 | uint32_t size, cur_size = 0; |
1103 | void *buf = NULL; | ||
1103 | int skip = 0; | 1104 | int skip = 0; |
1104 | u64 head; | 1105 | u64 head; |
1105 | int err; | 1106 | int err; |
@@ -1108,8 +1109,14 @@ static int __perf_session__process_pipe_events(struct perf_session *self, | |||
1108 | perf_tool__fill_defaults(tool); | 1109 | perf_tool__fill_defaults(tool); |
1109 | 1110 | ||
1110 | head = 0; | 1111 | head = 0; |
1112 | cur_size = sizeof(union perf_event); | ||
1113 | |||
1114 | buf = malloc(cur_size); | ||
1115 | if (!buf) | ||
1116 | return -errno; | ||
1111 | more: | 1117 | more: |
1112 | err = readn(self->fd, &event, sizeof(struct perf_event_header)); | 1118 | event = buf; |
1119 | err = readn(self->fd, event, sizeof(struct perf_event_header)); | ||
1113 | if (err <= 0) { | 1120 | if (err <= 0) { |
1114 | if (err == 0) | 1121 | if (err == 0) |
1115 | goto done; | 1122 | goto done; |
@@ -1119,13 +1126,23 @@ more: | |||
1119 | } | 1126 | } |
1120 | 1127 | ||
1121 | if (self->header.needs_swap) | 1128 | if (self->header.needs_swap) |
1122 | perf_event_header__bswap(&event.header); | 1129 | perf_event_header__bswap(&event->header); |
1123 | 1130 | ||
1124 | size = event.header.size; | 1131 | size = event->header.size; |
1125 | if (size == 0) | 1132 | if (size == 0) |
1126 | size = 8; | 1133 | size = 8; |
1127 | 1134 | ||
1128 | p = &event; | 1135 | if (size > cur_size) { |
1136 | void *new = realloc(buf, size); | ||
1137 | if (!new) { | ||
1138 | pr_err("failed to allocate memory to read event\n"); | ||
1139 | goto out_err; | ||
1140 | } | ||
1141 | buf = new; | ||
1142 | cur_size = size; | ||
1143 | event = buf; | ||
1144 | } | ||
1145 | p = event; | ||
1129 | p += sizeof(struct perf_event_header); | 1146 | p += sizeof(struct perf_event_header); |
1130 | 1147 | ||
1131 | if (size - sizeof(struct perf_event_header)) { | 1148 | if (size - sizeof(struct perf_event_header)) { |
@@ -1141,9 +1158,9 @@ more: | |||
1141 | } | 1158 | } |
1142 | } | 1159 | } |
1143 | 1160 | ||
1144 | if ((skip = perf_session__process_event(self, &event, tool, head)) < 0) { | 1161 | if ((skip = perf_session__process_event(self, event, tool, head)) < 0) { |
1145 | pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", | 1162 | pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", |
1146 | head, event.header.size, event.header.type); | 1163 | head, event->header.size, event->header.type); |
1147 | err = -EINVAL; | 1164 | err = -EINVAL; |
1148 | goto out_err; | 1165 | goto out_err; |
1149 | } | 1166 | } |
@@ -1158,6 +1175,7 @@ more: | |||
1158 | done: | 1175 | done: |
1159 | err = 0; | 1176 | err = 0; |
1160 | out_err: | 1177 | out_err: |
1178 | free(buf); | ||
1161 | perf_session__warn_about_errors(self, tool); | 1179 | perf_session__warn_about_errors(self, tool); |
1162 | perf_session_free_sample_buffers(self); | 1180 | perf_session_free_sample_buffers(self); |
1163 | return err; | 1181 | return err; |