summaryrefslogtreecommitdiff
path: root/simpleperf/record_file_reader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'simpleperf/record_file_reader.cpp')
-rw-r--r--simpleperf/record_file_reader.cpp52
1 files changed, 33 insertions, 19 deletions
diff --git a/simpleperf/record_file_reader.cpp b/simpleperf/record_file_reader.cpp
index 1165494c..9b97936f 100644
--- a/simpleperf/record_file_reader.cpp
+++ b/simpleperf/record_file_reader.cpp
@@ -213,29 +213,40 @@ std::unique_ptr<Record> RecordFileReader::ReadRecord() {
PLOG(ERROR) << "failed to read file " << filename_;
return nullptr;
}
- perf_event_header* header = reinterpret_cast<perf_event_header*>(&buf[0]);
- if (buf.size() < header->size) {
- buf.resize(header->size);
- header = reinterpret_cast<perf_event_header*>(&buf[0]);
- }
- if (fread(&buf[sizeof(perf_event_header)], buf.size() - sizeof(perf_event_header), 1, record_fp_) != 1) {
- PLOG(ERROR) << "failed to read file " << filename_;
- return nullptr;
+ perf_event_header* pheader = reinterpret_cast<perf_event_header*>(&buf[0]);
+ if (buf.size() < pheader->size) {
+ buf.resize(pheader->size);
+ pheader = reinterpret_cast<perf_event_header*>(&buf[0]);
+ }
+ if (buf.size() > sizeof(perf_event_header)) {
+ if (fread(&buf[sizeof(perf_event_header)], pheader->size - sizeof(perf_event_header), 1, record_fp_) != 1) {
+ PLOG(ERROR) << "failed to read file " << filename_;
+ return nullptr;
+ }
}
const perf_event_attr* attr = &file_attrs_[0].attr;
- if (file_attrs_.size() > 1) {
+ if (file_attrs_.size() > 1 && pheader->type < PERF_RECORD_USER_DEFINED_TYPE_START) {
+ bool has_event_id = false;
uint64_t event_id;
- if (header->type == PERF_RECORD_SAMPLE) {
- event_id = *reinterpret_cast<uint64_t*>(&buf[event_id_pos_in_sample_records_]);
+ if (pheader->type == PERF_RECORD_SAMPLE) {
+ if (pheader->size > event_id_pos_in_sample_records_ + sizeof(uint64_t)) {
+ has_event_id = true;
+ event_id = *reinterpret_cast<uint64_t*>(&buf[event_id_pos_in_sample_records_]);
+ }
} else {
- event_id = *reinterpret_cast<uint64_t*>(
- &buf[header->size - event_id_reverse_pos_in_non_sample_records_]);
+ if (pheader->size > event_id_reverse_pos_in_non_sample_records_) {
+ has_event_id = true;
+ event_id = *reinterpret_cast<uint64_t*>(&buf[pheader->size - event_id_reverse_pos_in_non_sample_records_]);
+ }
+ }
+ if (has_event_id) {
+ auto it = event_id_to_attr_map_.find(event_id);
+ if (it != event_id_to_attr_map_.end()) {
+ attr = it->second;
+ }
}
- auto it = event_id_to_attr_map_.find(event_id);
- CHECK(it != event_id_to_attr_map_.end());
- attr = it->second;
}
- return ReadRecordFromBuffer(*attr, header);
+ return ReadRecordFromBuffer(*attr, pheader);
}
bool RecordFileReader::ReadFeatureSection(int feature, std::vector<char>* data) {
@@ -246,6 +257,9 @@ bool RecordFileReader::ReadFeatureSection(int feature, std::vector<char>* data)
}
SectionDesc section = it->second;
data->resize(section.size);
+ if (section.size == 0) {
+ return true;
+ }
if (fseek(record_fp_, section.offset, SEEK_SET) != 0) {
PLOG(ERROR) << "failed to fseek()";
return false;
@@ -291,9 +305,9 @@ std::vector<BuildIdRecord> RecordFileReader::ReadBuildIdFeature() {
CHECK_LE(p + header->size, end);
BuildIdRecord record(header);
// Set type explicitly as the perf.data produced by perf doesn't set it.
- record.header.type = PERF_RECORD_BUILD_ID;
+ record.SetTypeAndMisc(PERF_RECORD_BUILD_ID, record.misc());
result.push_back(record);
- p += header->size;
+ p += record.size();
}
return result;
}