summaryrefslogtreecommitdiff
path: root/simpleperf/cmd_dumprecord.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2015-04-28 15:54:13 -0700
committerYabin Cui <yabinc@google.com>2015-05-04 14:32:32 -0700
commit9759e1b1ce76185aa539aeea2fb1cbd8382156e7 (patch)
tree69196161e28ebe74fb27093e026983fd98b004da /simpleperf/cmd_dumprecord.cpp
parent249518de7cb7ddb1c066b3bb8b10bc0f66222f7d (diff)
downloadextras-9759e1b1ce76185aa539aeea2fb1cbd8382156e7.tar.gz
Implement simpleperf record/dumprecord subcommands.
Bug: 19483574 Change-Id: Id879713a75c2d3a6289d8847b95ee0bb4a2cc8a0
Diffstat (limited to 'simpleperf/cmd_dumprecord.cpp')
-rw-r--r--simpleperf/cmd_dumprecord.cpp179
1 files changed, 179 insertions, 0 deletions
diff --git a/simpleperf/cmd_dumprecord.cpp b/simpleperf/cmd_dumprecord.cpp
new file mode 100644
index 00000000..4ee93942
--- /dev/null
+++ b/simpleperf/cmd_dumprecord.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <inttypes.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <base/logging.h>
+#include <base/stringprintf.h>
+
+#include "command.h"
+#include "event_attr.h"
+#include "record.h"
+#include "record_file.h"
+
+using namespace PerfFileFormat;
+
+class DumpRecordCommandImpl {
+ public:
+ DumpRecordCommandImpl() : record_filename_("perf.data") {
+ }
+
+ bool Run(const std::vector<std::string>& args);
+
+ private:
+ bool ParseOptions(const std::vector<std::string>& args);
+ void DumpFileHeader();
+ void DumpAttrSection();
+ void DumpDataSection();
+
+ std::string record_filename_;
+ std::unique_ptr<RecordFileReader> record_file_reader_;
+
+ std::vector<int> features_;
+};
+
+bool DumpRecordCommandImpl::Run(const std::vector<std::string>& args) {
+ if (!ParseOptions(args)) {
+ return false;
+ }
+ record_file_reader_ = RecordFileReader::CreateInstance(record_filename_);
+ if (record_file_reader_ == nullptr) {
+ return false;
+ }
+ DumpFileHeader();
+ DumpAttrSection();
+ DumpDataSection();
+
+ return true;
+}
+
+bool DumpRecordCommandImpl::ParseOptions(const std::vector<std::string>& args) {
+ if (args.size() == 2) {
+ record_filename_ = args[1];
+ }
+ return true;
+}
+
+static const std::string GetFeatureName(int feature);
+
+void DumpRecordCommandImpl::DumpFileHeader() {
+ const FileHeader* header = record_file_reader_->FileHeader();
+ printf("magic: ");
+ for (size_t i = 0; i < 8; ++i) {
+ printf("%c", header->magic[i]);
+ }
+ printf("\n");
+ printf("header_size: %" PRId64 "\n", header->header_size);
+ if (header->header_size != sizeof(*header)) {
+ PLOG(WARNING) << "record file header size doesn't match expected header size "
+ << sizeof(*header);
+ }
+ printf("attr_size: %" PRId64 "\n", header->attr_size);
+ if (header->attr_size != sizeof(FileAttr)) {
+ PLOG(WARNING) << "record file attr size doesn't match expected attr size " << sizeof(FileAttr);
+ }
+ printf("attrs[file section]: offset %" PRId64 ", size %" PRId64 "\n", header->attrs.offset,
+ header->attrs.size);
+ printf("data[file section]: offset %" PRId64 ", size %" PRId64 "\n", header->data.offset,
+ header->data.size);
+ printf("event_types[file section]: offset %" PRId64 ", size %" PRId64 "\n",
+ header->event_types.offset, header->event_types.size);
+
+ features_.clear();
+ for (size_t i = 0; i < FEAT_MAX_NUM; ++i) {
+ size_t j = i / 8;
+ size_t k = i % 8;
+ if ((header->features[j] & (1 << k)) != 0) {
+ features_.push_back(i);
+ }
+ }
+ for (auto& feature : features_) {
+ printf("feature: %s\n", GetFeatureName(feature).c_str());
+ }
+}
+
+static const std::string GetFeatureName(int feature) {
+ static std::map<int, std::string> feature_name_map = {
+ {FEAT_TRACING_DATA, "tracing_data"},
+ {FEAT_BUILD_ID, "build_id"},
+ {FEAT_HOSTNAME, "hostname"},
+ {FEAT_OSRELEASE, "osrelease"},
+ {FEAT_VERSION, "version"},
+ {FEAT_ARCH, "arch"},
+ {FEAT_NRCPUS, "nrcpus"},
+ {FEAT_CPUDESC, "cpudesc"},
+ {FEAT_CPUID, "cpuid"},
+ {FEAT_TOTAL_MEM, "total_mem"},
+ {FEAT_CMDLINE, "cmdline"},
+ {FEAT_EVENT_DESC, "event_desc"},
+ {FEAT_CPU_TOPOLOGY, "cpu_topology"},
+ {FEAT_NUMA_TOPOLOGY, "numa_topology"},
+ {FEAT_BRANCH_STACK, "branck_stack"},
+ {FEAT_PMU_MAPPINGS, "pmu_mappings"},
+ {FEAT_GROUP_DESC, "group_desc"},
+ };
+ auto it = feature_name_map.find(feature);
+ if (it != feature_name_map.end()) {
+ return it->second;
+ }
+ return android::base::StringPrintf("unknown_feature(%d)", feature);
+}
+
+void DumpRecordCommandImpl::DumpAttrSection() {
+ std::vector<const FileAttr*> attrs = record_file_reader_->AttrSection();
+ for (size_t i = 0; i < attrs.size(); ++i) {
+ auto& attr = attrs[i];
+ printf("file_attr %zu:\n", i + 1);
+ DumpPerfEventAttr(attr->attr, 1);
+ printf(" ids[file_section]: offset %" PRId64 ", size %" PRId64 "\n", attr->ids.offset,
+ attr->ids.size);
+ std::vector<uint64_t> ids = record_file_reader_->IdsForAttr(attr);
+ if (ids.size() > 0) {
+ printf(" ids:");
+ for (auto& id : ids) {
+ printf(" %" PRId64, id);
+ }
+ printf("\n");
+ }
+ }
+}
+
+void DumpRecordCommandImpl::DumpDataSection() {
+ std::vector<std::unique_ptr<const Record>> records = record_file_reader_->DataSection();
+ for (auto& record : records) {
+ record->Dump();
+ }
+}
+
+class DumpRecordCommand : public Command {
+ public:
+ DumpRecordCommand()
+ : Command("dump", "dump perf record file",
+ "Usage: simpleperf dumprecord [options] [perf_record_file]\n"
+ " Dump different parts of a perf record file. Default file is perf.data.\n") {
+ }
+
+ bool Run(const std::vector<std::string>& args) override {
+ DumpRecordCommandImpl impl;
+ return impl.Run(args);
+ }
+};
+
+DumpRecordCommand dumprecord_cmd;