blob: f1a3425fcac8ef2f0361d74110c31078d6311517 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/performance/bin/ktrace_provider/reader.h"
#include <lib/syslog/cpp/macros.h>
#include <lib/zircon-internal/ktrace.h>
#include <zircon/assert.h>
namespace ktrace_provider {
Reader::Reader(const char* buffer, size_t buffer_size)
: current_(buffer), marker_(buffer), end_(buffer + buffer_size) {
// Ensure initial buffer is correctly aligned.
ZX_ASSERT(reinterpret_cast<uintptr_t>(buffer) % alignof(ktrace_header_t) == 0);
}
const ktrace_header_t* Reader::ReadNextRecord() {
if (AvailableBytes() < sizeof(ktrace_header_t)) {
ReadMoreData();
}
if (AvailableBytes() < sizeof(ktrace_header_t)) {
FX_VLOGS(10) << "No more records";
return nullptr;
}
auto record = reinterpret_cast<const ktrace_header_t*>(current_);
if (AvailableBytes() < KTRACE_LEN(record->tag)) {
ReadMoreData();
}
if (AvailableBytes() < KTRACE_LEN(record->tag)) {
FX_VLOGS(10) << "No more records, incomplete last record";
return nullptr;
}
record = reinterpret_cast<const ktrace_header_t*>(current_);
uint32_t len = KTRACE_LEN(record->tag);
// A record with a length of zero is illegal. If we encounter such a thing,
// we are in trouble. Either the buffer coming from the kernel is corrupt, or
// we have lost sync with the record stream somehow. Either way, we cannot
// make any more progress if we don't know how far to advance. Report a
// warning and get out.
if (!len) {
FX_LOGS(WARNING) << "Found 0-length record. Reading cannot continue.";
return nullptr;
}
current_ += len;
number_bytes_read_ += len;
number_records_read_ += 1;
FX_VLOGS(10) << "Importing ktrace event 0x" << std::hex << KTRACE_EVENT(record->tag) << ", size "
<< std::dec << KTRACE_LEN(record->tag);
return record;
}
} // namespace ktrace_provider