diff options
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r-- | tools/perf/util/session.c | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index caa224522fea..f5a8fbdd3f76 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -58,6 +58,16 @@ static int perf_session__open(struct perf_session *self, bool force) | |||
58 | goto out_close; | 58 | goto out_close; |
59 | } | 59 | } |
60 | 60 | ||
61 | if (!perf_evlist__valid_sample_type(self->evlist)) { | ||
62 | pr_err("non matching sample_type"); | ||
63 | goto out_close; | ||
64 | } | ||
65 | |||
66 | if (!perf_evlist__valid_sample_id_all(self->evlist)) { | ||
67 | pr_err("non matching sample_id_all"); | ||
68 | goto out_close; | ||
69 | } | ||
70 | |||
61 | self->size = input_stat.st_size; | 71 | self->size = input_stat.st_size; |
62 | return 0; | 72 | return 0; |
63 | 73 | ||
@@ -97,6 +107,7 @@ out: | |||
97 | void perf_session__update_sample_type(struct perf_session *self) | 107 | void perf_session__update_sample_type(struct perf_session *self) |
98 | { | 108 | { |
99 | self->sample_type = perf_evlist__sample_type(self->evlist); | 109 | self->sample_type = perf_evlist__sample_type(self->evlist); |
110 | self->sample_size = __perf_evsel__sample_size(self->sample_type); | ||
100 | self->sample_id_all = perf_evlist__sample_id_all(self->evlist); | 111 | self->sample_id_all = perf_evlist__sample_id_all(self->evlist); |
101 | perf_session__id_header_size(self); | 112 | perf_session__id_header_size(self); |
102 | } | 113 | } |
@@ -479,6 +490,7 @@ static void flush_sample_queue(struct perf_session *s, | |||
479 | struct perf_sample sample; | 490 | struct perf_sample sample; |
480 | u64 limit = os->next_flush; | 491 | u64 limit = os->next_flush; |
481 | u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL; | 492 | u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL; |
493 | int ret; | ||
482 | 494 | ||
483 | if (!ops->ordered_samples || !limit) | 495 | if (!ops->ordered_samples || !limit) |
484 | return; | 496 | return; |
@@ -487,9 +499,12 @@ static void flush_sample_queue(struct perf_session *s, | |||
487 | if (iter->timestamp > limit) | 499 | if (iter->timestamp > limit) |
488 | break; | 500 | break; |
489 | 501 | ||
490 | perf_session__parse_sample(s, iter->event, &sample); | 502 | ret = perf_session__parse_sample(s, iter->event, &sample); |
491 | perf_session_deliver_event(s, iter->event, &sample, ops, | 503 | if (ret) |
492 | iter->file_offset); | 504 | pr_err("Can't parse sample, err = %d\n", ret); |
505 | else | ||
506 | perf_session_deliver_event(s, iter->event, &sample, ops, | ||
507 | iter->file_offset); | ||
493 | 508 | ||
494 | os->last_flush = iter->timestamp; | 509 | os->last_flush = iter->timestamp; |
495 | list_del(&iter->list); | 510 | list_del(&iter->list); |
@@ -805,7 +820,9 @@ static int perf_session__process_event(struct perf_session *session, | |||
805 | /* | 820 | /* |
806 | * For all kernel events we get the sample data | 821 | * For all kernel events we get the sample data |
807 | */ | 822 | */ |
808 | perf_session__parse_sample(session, event, &sample); | 823 | ret = perf_session__parse_sample(session, event, &sample); |
824 | if (ret) | ||
825 | return ret; | ||
809 | 826 | ||
810 | /* Preprocess sample records - precheck callchains */ | 827 | /* Preprocess sample records - precheck callchains */ |
811 | if (perf_session__preprocess_sample(session, event, &sample)) | 828 | if (perf_session__preprocess_sample(session, event, &sample)) |
@@ -953,6 +970,30 @@ out_err: | |||
953 | return err; | 970 | return err; |
954 | } | 971 | } |
955 | 972 | ||
973 | static union perf_event * | ||
974 | fetch_mmaped_event(struct perf_session *session, | ||
975 | u64 head, size_t mmap_size, char *buf) | ||
976 | { | ||
977 | union perf_event *event; | ||
978 | |||
979 | /* | ||
980 | * Ensure we have enough space remaining to read | ||
981 | * the size of the event in the headers. | ||
982 | */ | ||
983 | if (head + sizeof(event->header) > mmap_size) | ||
984 | return NULL; | ||
985 | |||
986 | event = (union perf_event *)(buf + head); | ||
987 | |||
988 | if (session->header.needs_swap) | ||
989 | perf_event_header__bswap(&event->header); | ||
990 | |||
991 | if (head + event->header.size > mmap_size) | ||
992 | return NULL; | ||
993 | |||
994 | return event; | ||
995 | } | ||
996 | |||
956 | int __perf_session__process_events(struct perf_session *session, | 997 | int __perf_session__process_events(struct perf_session *session, |
957 | u64 data_offset, u64 data_size, | 998 | u64 data_offset, u64 data_size, |
958 | u64 file_size, struct perf_event_ops *ops) | 999 | u64 file_size, struct perf_event_ops *ops) |
@@ -1007,15 +1048,8 @@ remap: | |||
1007 | file_pos = file_offset + head; | 1048 | file_pos = file_offset + head; |
1008 | 1049 | ||
1009 | more: | 1050 | more: |
1010 | event = (union perf_event *)(buf + head); | 1051 | event = fetch_mmaped_event(session, head, mmap_size, buf); |
1011 | 1052 | if (!event) { | |
1012 | if (session->header.needs_swap) | ||
1013 | perf_event_header__bswap(&event->header); | ||
1014 | size = event->header.size; | ||
1015 | if (size == 0) | ||
1016 | size = 8; | ||
1017 | |||
1018 | if (head + event->header.size > mmap_size) { | ||
1019 | if (mmaps[map_idx]) { | 1053 | if (mmaps[map_idx]) { |
1020 | munmap(mmaps[map_idx], mmap_size); | 1054 | munmap(mmaps[map_idx], mmap_size); |
1021 | mmaps[map_idx] = NULL; | 1055 | mmaps[map_idx] = NULL; |
@@ -1156,6 +1190,18 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) | |||
1156 | return ret; | 1190 | return ret; |
1157 | } | 1191 | } |
1158 | 1192 | ||
1193 | struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | ||
1194 | unsigned int type) | ||
1195 | { | ||
1196 | struct perf_evsel *pos; | ||
1197 | |||
1198 | list_for_each_entry(pos, &session->evlist->entries, node) { | ||
1199 | if (pos->attr.type == type) | ||
1200 | return pos; | ||
1201 | } | ||
1202 | return NULL; | ||
1203 | } | ||
1204 | |||
1159 | void perf_session__print_symbols(union perf_event *event, | 1205 | void perf_session__print_symbols(union perf_event *event, |
1160 | struct perf_sample *sample, | 1206 | struct perf_sample *sample, |
1161 | struct perf_session *session) | 1207 | struct perf_session *session) |