12672dea3f1112b13678103023011c797ca283bacYabin Cui/* 22672dea3f1112b13678103023011c797ca283bacYabin Cui * Copyright (C) 2015 The Android Open Source Project 32672dea3f1112b13678103023011c797ca283bacYabin Cui * 42672dea3f1112b13678103023011c797ca283bacYabin Cui * Licensed under the Apache License, Version 2.0 (the "License"); 52672dea3f1112b13678103023011c797ca283bacYabin Cui * you may not use this file except in compliance with the License. 62672dea3f1112b13678103023011c797ca283bacYabin Cui * You may obtain a copy of the License at 72672dea3f1112b13678103023011c797ca283bacYabin Cui * 82672dea3f1112b13678103023011c797ca283bacYabin Cui * http://www.apache.org/licenses/LICENSE-2.0 92672dea3f1112b13678103023011c797ca283bacYabin Cui * 102672dea3f1112b13678103023011c797ca283bacYabin Cui * Unless required by applicable law or agreed to in writing, software 112672dea3f1112b13678103023011c797ca283bacYabin Cui * distributed under the License is distributed on an "AS IS" BASIS, 122672dea3f1112b13678103023011c797ca283bacYabin Cui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132672dea3f1112b13678103023011c797ca283bacYabin Cui * See the License for the specific language governing permissions and 142672dea3f1112b13678103023011c797ca283bacYabin Cui * limitations under the License. 152672dea3f1112b13678103023011c797ca283bacYabin Cui */ 162672dea3f1112b13678103023011c797ca283bacYabin Cui 172672dea3f1112b13678103023011c797ca283bacYabin Cui#include <inttypes.h> 18c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui#include <algorithm> 192672dea3f1112b13678103023011c797ca283bacYabin Cui#include <functional> 202672dea3f1112b13678103023011c797ca283bacYabin Cui#include <map> 218a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui#include <set> 222672dea3f1112b13678103023011c797ca283bacYabin Cui#include <string> 232672dea3f1112b13678103023011c797ca283bacYabin Cui#include <unordered_map> 2438e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui#include <unordered_set> 252672dea3f1112b13678103023011c797ca283bacYabin Cui#include <vector> 262672dea3f1112b13678103023011c797ca283bacYabin Cui 2766dd09e8e2407082ce93bf0784de641298131912Elliott Hughes#include <android-base/logging.h> 280bd2a5cef3cf787552c55f643631b6ba77637711Yabin Cui#include <android-base/parseint.h> 2966dd09e8e2407082ce93bf0784de641298131912Elliott Hughes#include <android-base/stringprintf.h> 3066dd09e8e2407082ce93bf0784de641298131912Elliott Hughes#include <android-base/strings.h> 312672dea3f1112b13678103023011c797ca283bacYabin Cui 322672dea3f1112b13678103023011c797ca283bacYabin Cui#include "command.h" 333c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui#include "dwarf_unwind.h" 342672dea3f1112b13678103023011c797ca283bacYabin Cui#include "environment.h" 352672dea3f1112b13678103023011c797ca283bacYabin Cui#include "event_attr.h" 362672dea3f1112b13678103023011c797ca283bacYabin Cui#include "event_type.h" 3776769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui#include "perf_regs.h" 382672dea3f1112b13678103023011c797ca283bacYabin Cui#include "record.h" 392672dea3f1112b13678103023011c797ca283bacYabin Cui#include "record_file.h" 402672dea3f1112b13678103023011c797ca283bacYabin Cui#include "sample_tree.h" 4160a0ea96c0fb9e807c899759256df5e20bd904bdYabin Cui#include "thread_tree.h" 4238e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui#include "utils.h" 432672dea3f1112b13678103023011c797ca283bacYabin Cui 4436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass Displayable { 4536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 4636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui Displayable(const std::string& name) : name_(name), width_(name.size()) { 4736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 482672dea3f1112b13678103023011c797ca283bacYabin Cui 4936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui virtual ~Displayable() { 5036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 512672dea3f1112b13678103023011c797ca283bacYabin Cui 5236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui const std::string& Name() const { 5336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return name_; 5436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 5536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui size_t Width() const { 5636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return width_; 5736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 582672dea3f1112b13678103023011c797ca283bacYabin Cui 5936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui virtual std::string Show(const SampleEntry& sample) const = 0; 6036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui void AdjustWidth(const SampleEntry& sample) { 6136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui size_t size = Show(sample).size(); 6236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui width_ = std::max(width_, size); 6336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 642672dea3f1112b13678103023011c797ca283bacYabin Cui 6536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui private: 6636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui const std::string name_; 6736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui size_t width_; 682672dea3f1112b13678103023011c797ca283bacYabin Cui}; 692672dea3f1112b13678103023011c797ca283bacYabin Cui 7036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass AccumulatedOverheadItem : public Displayable { 7136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 7236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui AccumulatedOverheadItem(const SampleTree& sample_tree) 7336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui : Displayable("Children"), sample_tree_(sample_tree) { 7436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 7541d4ba9f6f2781155a0519a784606d5382cda88fYabin Cui 7636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::string Show(const SampleEntry& sample) const override { 7736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui uint64_t period = sample.period + sample.accumulated_period; 7836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui uint64_t total_period = sample_tree_.TotalPeriod(); 7936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui double percentage = (total_period != 0) ? 100.0 * period / total_period : 0.0; 8036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return android::base::StringPrintf("%.2lf%%", percentage); 8136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 8241d4ba9f6f2781155a0519a784606d5382cda88fYabin Cui 8336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui private: 8436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui const SampleTree& sample_tree_; 8541d4ba9f6f2781155a0519a784606d5382cda88fYabin Cui}; 8641d4ba9f6f2781155a0519a784606d5382cda88fYabin Cui 8736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass SelfOverheadItem : public Displayable { 8836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 8936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui SelfOverheadItem(const SampleTree& sample_tree, const std::string& name = "Self") 9036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui : Displayable(name), sample_tree_(sample_tree) { 9136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 922672dea3f1112b13678103023011c797ca283bacYabin Cui 9336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::string Show(const SampleEntry& sample) const override { 9436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui uint64_t period = sample.period; 9536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui uint64_t total_period = sample_tree_.TotalPeriod(); 9636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui double percentage = (total_period != 0) ? 100.0 * period / total_period : 0.0; 9736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return android::base::StringPrintf("%.2lf%%", percentage); 9836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 992672dea3f1112b13678103023011c797ca283bacYabin Cui 10036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui private: 10136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui const SampleTree& sample_tree_; 1022672dea3f1112b13678103023011c797ca283bacYabin Cui}; 1032672dea3f1112b13678103023011c797ca283bacYabin Cui 10436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass SampleCountItem : public Displayable { 10536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 10636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui SampleCountItem() : Displayable("Sample") { 10736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 1082672dea3f1112b13678103023011c797ca283bacYabin Cui 10936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::string Show(const SampleEntry& sample) const override { 11036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return android::base::StringPrintf("%" PRId64, sample.sample_count); 11136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 11236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui}; 1132672dea3f1112b13678103023011c797ca283bacYabin Cui 11436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass Comparable { 11536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 11636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui virtual ~Comparable() { 1172672dea3f1112b13678103023011c797ca283bacYabin Cui } 1182672dea3f1112b13678103023011c797ca283bacYabin Cui 11936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui virtual int Compare(const SampleEntry& sample1, const SampleEntry& sample2) const = 0; 1202672dea3f1112b13678103023011c797ca283bacYabin Cui}; 1212672dea3f1112b13678103023011c797ca283bacYabin Cui 12236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass PidItem : public Displayable, public Comparable { 12336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 12436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui PidItem() : Displayable("Pid") { 12536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 126ec12ed9010128483993a87d68edc02d3a89d56cfYabin Cui 12736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui int Compare(const SampleEntry& sample1, const SampleEntry& sample2) const override { 12836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return sample1.thread->pid - sample2.thread->pid; 12936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 130ec12ed9010128483993a87d68edc02d3a89d56cfYabin Cui 13136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::string Show(const SampleEntry& sample) const override { 13236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return android::base::StringPrintf("%d", sample.thread->pid); 13336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 134ec12ed9010128483993a87d68edc02d3a89d56cfYabin Cui}; 135ec12ed9010128483993a87d68edc02d3a89d56cfYabin Cui 13636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass TidItem : public Displayable, public Comparable { 13736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 13836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui TidItem() : Displayable("Tid") { 13936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 1408a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 14136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui int Compare(const SampleEntry& sample1, const SampleEntry& sample2) const override { 14236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return sample1.thread->tid - sample2.thread->tid; 14336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 1448a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 14536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::string Show(const SampleEntry& sample) const override { 14636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return android::base::StringPrintf("%d", sample.thread->tid); 14736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 1488a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui}; 1498a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 15036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass CommItem : public Displayable, public Comparable { 15136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 15236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui CommItem() : Displayable("Command") { 15336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 1548a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 15536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui int Compare(const SampleEntry& sample1, const SampleEntry& sample2) const override { 15636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return strcmp(sample1.thread_comm, sample2.thread_comm); 15736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 15836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui 15936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::string Show(const SampleEntry& sample) const override { 16036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return sample.thread_comm; 16136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 1628a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui}; 1638a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 16436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass DsoItem : public Displayable, public Comparable { 16536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 16636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui DsoItem(const std::string& name = "Shared Object") : Displayable(name) { 16736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 1688a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 16936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui int Compare(const SampleEntry& sample1, const SampleEntry& sample2) const override { 170c84856093e8bf4350d30fc521dc0f1c800c5270bYabin Cui return strcmp(sample1.map->dso->Path().c_str(), sample2.map->dso->Path().c_str()); 17136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 1728a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 17336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::string Show(const SampleEntry& sample) const override { 174c84856093e8bf4350d30fc521dc0f1c800c5270bYabin Cui return sample.map->dso->Path(); 17536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 17636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui}; 1778a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 17836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass SymbolItem : public Displayable, public Comparable { 17936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 18036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui SymbolItem(const std::string& name = "Symbol") : Displayable(name) { 18136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 18236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui 18336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui int Compare(const SampleEntry& sample1, const SampleEntry& sample2) const override { 184cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui return strcmp(sample1.symbol->DemangledName(), sample2.symbol->DemangledName()); 18536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 18636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui 18736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::string Show(const SampleEntry& sample) const override { 188cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui return sample.symbol->DemangledName(); 18936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 1908a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui}; 1918a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 19236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass DsoFromItem : public Displayable, public Comparable { 19336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 19436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui DsoFromItem() : Displayable("Source Shared Object") { 19536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 19636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui 19736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui int Compare(const SampleEntry& sample1, const SampleEntry& sample2) const override { 198c84856093e8bf4350d30fc521dc0f1c800c5270bYabin Cui return strcmp(sample1.branch_from.map->dso->Path().c_str(), 199c84856093e8bf4350d30fc521dc0f1c800c5270bYabin Cui sample2.branch_from.map->dso->Path().c_str()); 20036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 2018a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 20236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::string Show(const SampleEntry& sample) const override { 203c84856093e8bf4350d30fc521dc0f1c800c5270bYabin Cui return sample.branch_from.map->dso->Path(); 20436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 2058a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui}; 2068a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 20736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass DsoToItem : public DsoItem { 20836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 20936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui DsoToItem() : DsoItem("Target Shared Object") { 21036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 21136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui}; 2128e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui 21336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass SymbolFromItem : public Displayable, public Comparable { 21436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 21536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui SymbolFromItem() : Displayable("Source Symbol") { 21636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 2178e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui 21836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui int Compare(const SampleEntry& sample1, const SampleEntry& sample2) const override { 219cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui return strcmp(sample1.branch_from.symbol->DemangledName(), 220cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui sample2.branch_from.symbol->DemangledName()); 22136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 22236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui 22336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::string Show(const SampleEntry& sample) const override { 224cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui return sample.branch_from.symbol->DemangledName(); 22536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 2268e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui}; 2278e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui 22836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuiclass SymbolToItem : public SymbolItem { 22936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui public: 23036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui SymbolToItem() : SymbolItem("Target Symbol") { 23136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 23236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui}; 2338a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui 2348a530e3bae0cc031d60e397c347e96f44487e919Yabin Cuistatic std::set<std::string> branch_sort_keys = { 2358a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui "dso_from", "dso_to", "symbol_from", "symbol_to", 2362672dea3f1112b13678103023011c797ca283bacYabin Cui}; 2372672dea3f1112b13678103023011c797ca283bacYabin Cui 2382672dea3f1112b13678103023011c797ca283bacYabin Cuiclass ReportCommand : public Command { 2392672dea3f1112b13678103023011c797ca283bacYabin Cui public: 2402672dea3f1112b13678103023011c797ca283bacYabin Cui ReportCommand() 2418a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui : Command( 2428a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui "report", "report sampling information in perf.data", 2438a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui "Usage: simpleperf report [options]\n" 2448a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui " -b Use the branch-to addresses in sampled take branches instead of\n" 2458a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui " the instruction addresses. Only valid for perf.data recorded with\n" 24636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui " -b/-j option.\n" 24736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui " --children Print the overhead accumulated by appearing in the callchain.\n" 24838e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui " --comms comm1,comm2,...\n" 24938e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui " Report only for selected comms.\n" 25038e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui " --dsos dso1,dso2,...\n" 25138e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui " Report only for selected dsos.\n" 252c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui " -g [callee|caller]\n" 253c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui " Print call graph. If callee mode is used, the graph shows how\n" 254c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui " functions are called from others. Otherwise, the graph shows how\n" 255c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui " functions call others. Default is callee mode.\n" 2568a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui " -i <file> Specify path of record file, default is perf.data.\n" 2578a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui " -n Print the sample count for each item.\n" 2588a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui " --no-demangle Don't demangle symbol names.\n" 2597288501a660ce2616539e8a963185d2f3c679729Yabin Cui " -o report_file_name Set report file name, default is stdout.\n" 26038e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui " --pid pid1,pid2,...\n" 26138e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui " Report only for selected pids.\n" 2628a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui " --sort key1,key2,...\n" 2638a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui " Select the keys to sort and print the report. Possible keys\n" 2648a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui " include pid, tid, comm, dso, symbol, dso_from, dso_to, symbol_from\n" 2658a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui " symbol_to. dso_from, dso_to, symbol_from, symbol_to can only be\n" 2668a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui " used with -b option. Default keys are \"comm,pid,tid,dso,symbol\"\n" 26739d3caeb60a913276a2bbaa35f6a28dc3284eb52Yabin Cui " --symfs <dir> Look for files with symbols relative to this directory.\n" 26838e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui " --tids tid1,tid2,...\n" 26938e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui " Report only for selected tids.\n" 27039d3caeb60a913276a2bbaa35f6a28dc3284eb52Yabin Cui " --vmlinux <file>\n" 27139d3caeb60a913276a2bbaa35f6a28dc3284eb52Yabin Cui " Parse kernel symbols from <file>.\n"), 2728a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui record_filename_("perf.data"), 273e435e7d8706ff234fdc69e9a9424fb2b08806658Yabin Cui record_file_arch_(GetBuildArch()), 27436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui use_branch_address_(false), 275ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui accumulate_callchain_(false), 276c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui print_callgraph_(false), 2777288501a660ce2616539e8a963185d2f3c679729Yabin Cui callgraph_show_callee_(true), 2787288501a660ce2616539e8a963185d2f3c679729Yabin Cui report_fp_(nullptr) { 27936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui compare_sample_func_t compare_sample_callback = std::bind( 28036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui &ReportCommand::CompareSampleEntry, this, std::placeholders::_1, std::placeholders::_2); 28160a0ea96c0fb9e807c899759256df5e20bd904bdYabin Cui sample_tree_ = 28260a0ea96c0fb9e807c899759256df5e20bd904bdYabin Cui std::unique_ptr<SampleTree>(new SampleTree(&thread_tree_, compare_sample_callback)); 2832672dea3f1112b13678103023011c797ca283bacYabin Cui } 2842672dea3f1112b13678103023011c797ca283bacYabin Cui 2852672dea3f1112b13678103023011c797ca283bacYabin Cui bool Run(const std::vector<std::string>& args); 2862672dea3f1112b13678103023011c797ca283bacYabin Cui 2872672dea3f1112b13678103023011c797ca283bacYabin Cui private: 2882672dea3f1112b13678103023011c797ca283bacYabin Cui bool ParseOptions(const std::vector<std::string>& args); 2892672dea3f1112b13678103023011c797ca283bacYabin Cui bool ReadEventAttrFromRecordFile(); 2902672dea3f1112b13678103023011c797ca283bacYabin Cui void ReadSampleTreeFromRecordFile(); 291b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui void ProcessRecord(std::unique_ptr<Record> record); 29236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui void ProcessSampleRecord(const SampleRecord& r); 29376769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui bool ReadFeaturesFromRecordFile(); 2942672dea3f1112b13678103023011c797ca283bacYabin Cui int CompareSampleEntry(const SampleEntry& sample1, const SampleEntry& sample2); 2957288501a660ce2616539e8a963185d2f3c679729Yabin Cui bool PrintReport(); 2962672dea3f1112b13678103023011c797ca283bacYabin Cui void PrintReportContext(); 297589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cui void CollectReportWidth(); 298589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cui void CollectReportEntryWidth(const SampleEntry& sample); 2992672dea3f1112b13678103023011c797ca283bacYabin Cui void PrintReportHeader(); 3002672dea3f1112b13678103023011c797ca283bacYabin Cui void PrintReportEntry(const SampleEntry& sample); 301ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui void PrintCallGraph(const SampleEntry& sample); 3027288501a660ce2616539e8a963185d2f3c679729Yabin Cui void PrintCallGraphEntry(size_t depth, std::string prefix, const std::unique_ptr<CallChainNode>& node, 3037288501a660ce2616539e8a963185d2f3c679729Yabin Cui uint64_t parent_period, bool last); 3042672dea3f1112b13678103023011c797ca283bacYabin Cui 3052672dea3f1112b13678103023011c797ca283bacYabin Cui std::string record_filename_; 306e435e7d8706ff234fdc69e9a9424fb2b08806658Yabin Cui ArchType record_file_arch_; 3072672dea3f1112b13678103023011c797ca283bacYabin Cui std::unique_ptr<RecordFileReader> record_file_reader_; 3082672dea3f1112b13678103023011c797ca283bacYabin Cui perf_event_attr event_attr_; 30936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::vector<std::unique_ptr<Displayable>> displayable_items_; 31036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::vector<Comparable*> comparable_items_; 31160a0ea96c0fb9e807c899759256df5e20bd904bdYabin Cui ThreadTree thread_tree_; 3122672dea3f1112b13678103023011c797ca283bacYabin Cui std::unique_ptr<SampleTree> sample_tree_; 3138a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui bool use_branch_address_; 314d713f959ec1fe07ed993e2c9f4166b52aa98a58cYabin Cui std::string record_cmdline_; 31536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui bool accumulate_callchain_; 316ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui bool print_callgraph_; 317c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui bool callgraph_show_callee_; 3187288501a660ce2616539e8a963185d2f3c679729Yabin Cui 3197288501a660ce2616539e8a963185d2f3c679729Yabin Cui std::string report_filename_; 3207288501a660ce2616539e8a963185d2f3c679729Yabin Cui FILE* report_fp_; 3212672dea3f1112b13678103023011c797ca283bacYabin Cui}; 3222672dea3f1112b13678103023011c797ca283bacYabin Cui 3232672dea3f1112b13678103023011c797ca283bacYabin Cuibool ReportCommand::Run(const std::vector<std::string>& args) { 3242672dea3f1112b13678103023011c797ca283bacYabin Cui // 1. Parse options. 3252672dea3f1112b13678103023011c797ca283bacYabin Cui if (!ParseOptions(args)) { 3262672dea3f1112b13678103023011c797ca283bacYabin Cui return false; 3272672dea3f1112b13678103023011c797ca283bacYabin Cui } 3282672dea3f1112b13678103023011c797ca283bacYabin Cui 3292672dea3f1112b13678103023011c797ca283bacYabin Cui // 2. Read record file and build SampleTree. 3302672dea3f1112b13678103023011c797ca283bacYabin Cui record_file_reader_ = RecordFileReader::CreateInstance(record_filename_); 3312672dea3f1112b13678103023011c797ca283bacYabin Cui if (record_file_reader_ == nullptr) { 3322672dea3f1112b13678103023011c797ca283bacYabin Cui return false; 3332672dea3f1112b13678103023011c797ca283bacYabin Cui } 3342672dea3f1112b13678103023011c797ca283bacYabin Cui if (!ReadEventAttrFromRecordFile()) { 3352672dea3f1112b13678103023011c797ca283bacYabin Cui return false; 3362672dea3f1112b13678103023011c797ca283bacYabin Cui } 337638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui // Read features first to prepare build ids used when building SampleTree. 33876769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui if (!ReadFeaturesFromRecordFile()) { 33976769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui return false; 34076769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui } 341e435e7d8706ff234fdc69e9a9424fb2b08806658Yabin Cui ScopedCurrentArch scoped_arch(record_file_arch_); 342638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui ReadSampleTreeFromRecordFile(); 3432672dea3f1112b13678103023011c797ca283bacYabin Cui 3448a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui // 3. Show collected information. 3457288501a660ce2616539e8a963185d2f3c679729Yabin Cui if (!PrintReport()) { 3467288501a660ce2616539e8a963185d2f3c679729Yabin Cui return false; 3477288501a660ce2616539e8a963185d2f3c679729Yabin Cui } 3482672dea3f1112b13678103023011c797ca283bacYabin Cui 3492672dea3f1112b13678103023011c797ca283bacYabin Cui return true; 3502672dea3f1112b13678103023011c797ca283bacYabin Cui} 3512672dea3f1112b13678103023011c797ca283bacYabin Cui 3522672dea3f1112b13678103023011c797ca283bacYabin Cuibool ReportCommand::ParseOptions(const std::vector<std::string>& args) { 353638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui bool demangle = true; 354638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui std::string symfs_dir; 35539d3caeb60a913276a2bbaa35f6a28dc3284eb52Yabin Cui std::string vmlinux; 3568e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui bool print_sample_count = false; 3578a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui std::vector<std::string> sort_keys = {"comm", "pid", "tid", "dso", "symbol"}; 35838e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui std::unordered_set<std::string> comm_filter; 35938e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui std::unordered_set<std::string> dso_filter; 36038e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui std::unordered_set<int> pid_filter; 36138e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui std::unordered_set<int> tid_filter; 36238e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui 3632672dea3f1112b13678103023011c797ca283bacYabin Cui for (size_t i = 0; i < args.size(); ++i) { 3648a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui if (args[i] == "-b") { 3658a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui use_branch_address_ = true; 36636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else if (args[i] == "--children") { 36736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui accumulate_callchain_ = true; 36838e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui } else if (args[i] == "--comms" || args[i] == "--dsos") { 3694a6c58dba06a907c2d687ff0983469c6abe640a7Yabin Cui std::unordered_set<std::string>& filter = (args[i] == "--comms" ? comm_filter : dso_filter); 37038e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui if (!NextArgumentOrError(args, &i)) { 37138e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui return false; 37238e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui } 37338e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui std::vector<std::string> strs = android::base::Split(args[i], ","); 37438e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui filter.insert(strs.begin(), strs.end()); 37538e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui 376ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } else if (args[i] == "-g") { 377ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui print_callgraph_ = true; 378ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui accumulate_callchain_ = true; 379c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui if (i + 1 < args.size() && args[i + 1][0] != '-') { 380c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui ++i; 381c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui if (args[i] == "callee") { 382c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui callgraph_show_callee_ = true; 383c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui } else if (args[i] == "caller") { 384c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui callgraph_show_callee_ = false; 385c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui } else { 386c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui LOG(ERROR) << "Unknown argument with -g option: " << args[i]; 387c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui return false; 388c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui } 389c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui } 3908a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui } else if (args[i] == "-i") { 3912672dea3f1112b13678103023011c797ca283bacYabin Cui if (!NextArgumentOrError(args, &i)) { 3922672dea3f1112b13678103023011c797ca283bacYabin Cui return false; 3932672dea3f1112b13678103023011c797ca283bacYabin Cui } 3942672dea3f1112b13678103023011c797ca283bacYabin Cui record_filename_ = args[i]; 3958e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui 3968e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui } else if (args[i] == "-n") { 3978e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui print_sample_count = true; 3988e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui 399b378355f34b2b585eaf2be262bcd9baae9f3d36aYabin Cui } else if (args[i] == "--no-demangle") { 400638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui demangle = false; 4017288501a660ce2616539e8a963185d2f3c679729Yabin Cui } else if (args[i] == "-o") { 4027288501a660ce2616539e8a963185d2f3c679729Yabin Cui if (!NextArgumentOrError(args, &i)) { 4037288501a660ce2616539e8a963185d2f3c679729Yabin Cui return false; 4047288501a660ce2616539e8a963185d2f3c679729Yabin Cui } 4057288501a660ce2616539e8a963185d2f3c679729Yabin Cui report_filename_ = args[i]; 4068e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui 40738e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui } else if (args[i] == "--pids" || args[i] == "--tids") { 40838e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui if (!NextArgumentOrError(args, &i)) { 40938e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui return false; 41038e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui } 41138e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui std::vector<std::string> strs = android::base::Split(args[i], ","); 41238e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui std::vector<int> ids; 4130bd2a5cef3cf787552c55f643631b6ba77637711Yabin Cui for (const auto& s : strs) { 41438e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui int id; 4150bd2a5cef3cf787552c55f643631b6ba77637711Yabin Cui if (!android::base::ParseInt(s.c_str(), &id, 0)) { 41638e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui LOG(ERROR) << "invalid id in " << args[i] << " option: " << s; 41738e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui return false; 41838e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui } 41938e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui ids.push_back(id); 42038e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui } 42138e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui std::unordered_set<int>& filter = (args[i] == "--pids" ? pid_filter : tid_filter); 42238e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui filter.insert(ids.begin(), ids.end()); 42338e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui 4242672dea3f1112b13678103023011c797ca283bacYabin Cui } else if (args[i] == "--sort") { 4252672dea3f1112b13678103023011c797ca283bacYabin Cui if (!NextArgumentOrError(args, &i)) { 4262672dea3f1112b13678103023011c797ca283bacYabin Cui return false; 4272672dea3f1112b13678103023011c797ca283bacYabin Cui } 4288a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui sort_keys = android::base::Split(args[i], ","); 429b378355f34b2b585eaf2be262bcd9baae9f3d36aYabin Cui } else if (args[i] == "--symfs") { 430b378355f34b2b585eaf2be262bcd9baae9f3d36aYabin Cui if (!NextArgumentOrError(args, &i)) { 431b378355f34b2b585eaf2be262bcd9baae9f3d36aYabin Cui return false; 432b378355f34b2b585eaf2be262bcd9baae9f3d36aYabin Cui } 433638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui symfs_dir = args[i]; 43438e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui 43539d3caeb60a913276a2bbaa35f6a28dc3284eb52Yabin Cui } else if (args[i] == "--vmlinux") { 43639d3caeb60a913276a2bbaa35f6a28dc3284eb52Yabin Cui if (!NextArgumentOrError(args, &i)) { 43739d3caeb60a913276a2bbaa35f6a28dc3284eb52Yabin Cui return false; 43839d3caeb60a913276a2bbaa35f6a28dc3284eb52Yabin Cui } 43939d3caeb60a913276a2bbaa35f6a28dc3284eb52Yabin Cui vmlinux = args[i]; 4402672dea3f1112b13678103023011c797ca283bacYabin Cui } else { 4412672dea3f1112b13678103023011c797ca283bacYabin Cui ReportUnknownOption(args, i); 4422672dea3f1112b13678103023011c797ca283bacYabin Cui return false; 4432672dea3f1112b13678103023011c797ca283bacYabin Cui } 4442672dea3f1112b13678103023011c797ca283bacYabin Cui } 4452672dea3f1112b13678103023011c797ca283bacYabin Cui 446c84856093e8bf4350d30fc521dc0f1c800c5270bYabin Cui Dso::SetDemangle(demangle); 447c84856093e8bf4350d30fc521dc0f1c800c5270bYabin Cui if (!Dso::SetSymFsDir(symfs_dir)) { 448638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui return false; 449638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui } 45039d3caeb60a913276a2bbaa35f6a28dc3284eb52Yabin Cui if (!vmlinux.empty()) { 451c84856093e8bf4350d30fc521dc0f1c800c5270bYabin Cui Dso::SetVmlinux(vmlinux); 45239d3caeb60a913276a2bbaa35f6a28dc3284eb52Yabin Cui } 453638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui 45436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui if (!accumulate_callchain_) { 45536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back( 45636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::unique_ptr<Displayable>(new SelfOverheadItem(*sample_tree_, "Overhead"))); 45736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else { 45836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back( 45936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::unique_ptr<Displayable>(new AccumulatedOverheadItem(*sample_tree_))); 46036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back(std::unique_ptr<Displayable>(new SelfOverheadItem(*sample_tree_))); 46136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 4628e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui if (print_sample_count) { 46336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back(std::unique_ptr<Displayable>(new SampleCountItem)); 4648a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui } 4658a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui for (auto& key : sort_keys) { 4668a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui if (!use_branch_address_ && branch_sort_keys.find(key) != branch_sort_keys.end()) { 4678a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui LOG(ERROR) << "sort key '" << key << "' can only be used with -b option."; 4688a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui return false; 4698a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui } 47036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui if (key == "pid") { 47136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui PidItem* item = new PidItem; 47236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back(std::unique_ptr<Displayable>(item)); 47336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui comparable_items_.push_back(item); 47436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else if (key == "tid") { 47536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui TidItem* item = new TidItem; 47636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back(std::unique_ptr<Displayable>(item)); 47736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui comparable_items_.push_back(item); 47836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else if (key == "comm") { 47936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui CommItem* item = new CommItem; 48036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back(std::unique_ptr<Displayable>(item)); 48136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui comparable_items_.push_back(item); 48236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else if (key == "dso") { 48336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui DsoItem* item = new DsoItem; 48436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back(std::unique_ptr<Displayable>(item)); 48536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui comparable_items_.push_back(item); 48636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else if (key == "symbol") { 48736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui SymbolItem* item = new SymbolItem; 48836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back(std::unique_ptr<Displayable>(item)); 48936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui comparable_items_.push_back(item); 49036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else if (key == "dso_from") { 49136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui DsoFromItem* item = new DsoFromItem; 49236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back(std::unique_ptr<Displayable>(item)); 49336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui comparable_items_.push_back(item); 49436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else if (key == "dso_to") { 49536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui DsoToItem* item = new DsoToItem; 49636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back(std::unique_ptr<Displayable>(item)); 49736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui comparable_items_.push_back(item); 49836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else if (key == "symbol_from") { 49936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui SymbolFromItem* item = new SymbolFromItem; 50036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back(std::unique_ptr<Displayable>(item)); 50136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui comparable_items_.push_back(item); 50236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else if (key == "symbol_to") { 50336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui SymbolToItem* item = new SymbolToItem; 50436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui displayable_items_.push_back(std::unique_ptr<Displayable>(item)); 50536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui comparable_items_.push_back(item); 5068a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui } else { 5078a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui LOG(ERROR) << "Unknown sort key: " << key; 5088a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui return false; 5098a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui } 5108e27740e1a28633b3a6cd017997b4d4daa5c1a25Yabin Cui } 51138e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui sample_tree_->SetFilters(pid_filter, tid_filter, comm_filter, dso_filter); 5122672dea3f1112b13678103023011c797ca283bacYabin Cui return true; 5132672dea3f1112b13678103023011c797ca283bacYabin Cui} 5142672dea3f1112b13678103023011c797ca283bacYabin Cui 5152672dea3f1112b13678103023011c797ca283bacYabin Cuibool ReportCommand::ReadEventAttrFromRecordFile() { 516b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui const std::vector<PerfFileFormat::FileAttr>& attrs = record_file_reader_->AttrSection(); 5172672dea3f1112b13678103023011c797ca283bacYabin Cui if (attrs.size() != 1) { 5182672dea3f1112b13678103023011c797ca283bacYabin Cui LOG(ERROR) << "record file contains " << attrs.size() << " attrs"; 5192672dea3f1112b13678103023011c797ca283bacYabin Cui return false; 5202672dea3f1112b13678103023011c797ca283bacYabin Cui } 521b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui event_attr_ = attrs[0].attr; 5228a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui if (use_branch_address_ && (event_attr_.sample_type & PERF_SAMPLE_BRANCH_STACK) == 0) { 5238a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui LOG(ERROR) << record_filename_ << " is not recorded with branch stack sampling option."; 5248a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui return false; 5258a530e3bae0cc031d60e397c347e96f44487e919Yabin Cui } 5262672dea3f1112b13678103023011c797ca283bacYabin Cui return true; 5272672dea3f1112b13678103023011c797ca283bacYabin Cui} 5282672dea3f1112b13678103023011c797ca283bacYabin Cui 5292672dea3f1112b13678103023011c797ca283bacYabin Cuivoid ReportCommand::ReadSampleTreeFromRecordFile() { 53060a0ea96c0fb9e807c899759256df5e20bd904bdYabin Cui thread_tree_.AddThread(0, 0, "swapper"); 531b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui record_file_reader_->ReadDataSection([this](std::unique_ptr<Record> record) { 532b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui ProcessRecord(std::move(record)); 533b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui return true; 534b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui }); 535b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui} 536b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui 537b7f481f59126456b0e708a76f40fa88224f3531bYabin Cuivoid ReportCommand::ProcessRecord(std::unique_ptr<Record> record) { 538b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui BuildThreadTree(*record, &thread_tree_); 539b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui if (record->header.type == PERF_RECORD_SAMPLE) { 540b7f481f59126456b0e708a76f40fa88224f3531bYabin Cui ProcessSampleRecord(*static_cast<const SampleRecord*>(record.get())); 5412672dea3f1112b13678103023011c797ca283bacYabin Cui } 5422672dea3f1112b13678103023011c797ca283bacYabin Cui} 5432672dea3f1112b13678103023011c797ca283bacYabin Cui 54436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cuivoid ReportCommand::ProcessSampleRecord(const SampleRecord& r) { 54536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui if (use_branch_address_ && (r.sample_type & PERF_SAMPLE_BRANCH_STACK)) { 54636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui for (auto& item : r.branch_stack_data.stack) { 54736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui if (item.from != 0 && item.to != 0) { 54836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui sample_tree_->AddBranchSample(r.tid_data.pid, r.tid_data.tid, item.from, item.to, 54936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui item.flags, r.time_data.time, r.period_data.period); 55036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 55136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 55236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else { 55336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui bool in_kernel = (r.header.misc & PERF_RECORD_MISC_CPUMODE_MASK) == PERF_RECORD_MISC_KERNEL; 55436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui SampleEntry* sample = sample_tree_->AddSample(r.tid_data.pid, r.tid_data.tid, r.ip_data.ip, 55536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui r.time_data.time, r.period_data.period, in_kernel); 55638e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui if (sample == nullptr) { 55738e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui return; 55838e573ee1958959253ba8f3af7567adb4cbeea55Yabin Cui } 5593c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui if (accumulate_callchain_) { 5603c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui std::vector<uint64_t> ips; 5613c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui if (r.sample_type & PERF_SAMPLE_CALLCHAIN) { 5623c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui ips.insert(ips.end(), r.callchain_data.ips.begin(), r.callchain_data.ips.end()); 5633c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui } 5643c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui // Use stack_user_data.data.size() instead of stack_user_data.dyn_size, to make up for 5653c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui // the missing kernel patch in N9. See b/22612370. 5663c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui if ((r.sample_type & PERF_SAMPLE_REGS_USER) && (r.regs_user_data.reg_mask != 0) && 5673c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui (r.sample_type & PERF_SAMPLE_STACK_USER) && (!r.stack_user_data.data.empty())) { 5683c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui RegSet regs = CreateRegSet(r.regs_user_data.reg_mask, r.regs_user_data.regs); 5693c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui std::vector<char> stack(r.stack_user_data.data.begin(), 5703c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui r.stack_user_data.data.begin() + r.stack_user_data.data.size()); 571e435e7d8706ff234fdc69e9a9424fb2b08806658Yabin Cui std::vector<uint64_t> unwind_ips = 572e435e7d8706ff234fdc69e9a9424fb2b08806658Yabin Cui UnwindCallChain(ScopedCurrentArch::GetCurrentArch(), *sample->thread, regs, stack); 5733c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui if (!unwind_ips.empty()) { 5743c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui ips.push_back(PERF_CONTEXT_USER); 5753c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui ips.insert(ips.end(), unwind_ips.begin(), unwind_ips.end()); 5763c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui } 5773c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui } 5783c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 57936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui std::vector<SampleEntry*> callchain; 58036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui callchain.push_back(sample); 5813c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 582ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui bool first_ip = true; 58336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui for (auto& ip : ips) { 58436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui if (ip >= PERF_CONTEXT_MAX) { 58536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui switch (ip) { 58636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui case PERF_CONTEXT_KERNEL: 58736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui in_kernel = true; 58836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui break; 58936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui case PERF_CONTEXT_USER: 59036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui in_kernel = false; 59136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui break; 59236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui default: 59336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui LOG(ERROR) << "Unexpected perf_context in callchain: " << ip; 59436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 59536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else { 596ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui if (first_ip) { 5973c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui first_ip = false; 598ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui // Remove duplication with sampled ip. 599ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui if (ip == r.ip_data.ip) { 600ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui continue; 601ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } 602ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } 603ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui SampleEntry* sample = 60436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui sample_tree_->AddCallChainSample(r.tid_data.pid, r.tid_data.tid, ip, r.time_data.time, 60536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui r.period_data.period, in_kernel, callchain); 60636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui callchain.push_back(sample); 60736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 60836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 6093c8c21345478816dd0c70c096090b564c91bd9d2Yabin Cui 610ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui if (print_callgraph_) { 611ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui std::set<SampleEntry*> added_set; 612c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui if (!callgraph_show_callee_) { 613c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui std::reverse(callchain.begin(), callchain.end()); 614c42867e0c65569906002e7cdc87161a972b292b7Yabin Cui } 615ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui while (callchain.size() >= 2) { 616ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui SampleEntry* sample = callchain[0]; 617ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui callchain.erase(callchain.begin()); 618ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui // Add only once for recursive calls on callchain. 619ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui if (added_set.find(sample) != added_set.end()) { 620ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui continue; 621ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } 622ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui added_set.insert(sample); 623ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui sample_tree_->InsertCallChainForSample(sample, callchain, r.period_data.period); 624ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } 625ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } 62636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 62736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 62836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui} 62936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui 63076769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cuibool ReportCommand::ReadFeaturesFromRecordFile() { 631638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui std::vector<BuildIdRecord> records = record_file_reader_->ReadBuildIdFeature(); 632638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui std::vector<std::pair<std::string, BuildId>> build_ids; 633638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui for (auto& r : records) { 634638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui build_ids.push_back(std::make_pair(r.filename, r.build_id)); 635638c558339b7f1ae0ed95f64bcf7dbc5b238ed83Yabin Cui } 636c84856093e8bf4350d30fc521dc0f1c800c5270bYabin Cui Dso::SetBuildIds(build_ids); 63776769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui 63876769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui std::string arch = record_file_reader_->ReadFeatureString(PerfFileFormat::FEAT_ARCH); 63976769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui if (!arch.empty()) { 640e435e7d8706ff234fdc69e9a9424fb2b08806658Yabin Cui record_file_arch_ = GetArchType(arch); 641e435e7d8706ff234fdc69e9a9424fb2b08806658Yabin Cui if (record_file_arch_ == ARCH_UNSUPPORTED) { 64276769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui return false; 64376769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui } 64476769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui } 64576769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui 646d713f959ec1fe07ed993e2c9f4166b52aa98a58cYabin Cui std::vector<std::string> cmdline = record_file_reader_->ReadCmdlineFeature(); 647d713f959ec1fe07ed993e2c9f4166b52aa98a58cYabin Cui if (!cmdline.empty()) { 648d713f959ec1fe07ed993e2c9f4166b52aa98a58cYabin Cui record_cmdline_ = android::base::Join(cmdline, ' '); 649d713f959ec1fe07ed993e2c9f4166b52aa98a58cYabin Cui } 65076769e502d8f0ebf5d2c81b00246727fb0a59925Yabin Cui return true; 651d713f959ec1fe07ed993e2c9f4166b52aa98a58cYabin Cui} 652d713f959ec1fe07ed993e2c9f4166b52aa98a58cYabin Cui 6532672dea3f1112b13678103023011c797ca283bacYabin Cuiint ReportCommand::CompareSampleEntry(const SampleEntry& sample1, const SampleEntry& sample2) { 65436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui for (auto& item : comparable_items_) { 65536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui int result = item->Compare(sample1, sample2); 65636c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui if (result != 0) { 65736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui return result; 6582672dea3f1112b13678103023011c797ca283bacYabin Cui } 6592672dea3f1112b13678103023011c797ca283bacYabin Cui } 6602672dea3f1112b13678103023011c797ca283bacYabin Cui return 0; 6612672dea3f1112b13678103023011c797ca283bacYabin Cui} 6622672dea3f1112b13678103023011c797ca283bacYabin Cui 6637288501a660ce2616539e8a963185d2f3c679729Yabin Cuibool ReportCommand::PrintReport() { 6647288501a660ce2616539e8a963185d2f3c679729Yabin Cui std::unique_ptr<FILE, decltype(&fclose)> file_handler(nullptr, fclose); 6657288501a660ce2616539e8a963185d2f3c679729Yabin Cui if (report_filename_.empty()) { 6667288501a660ce2616539e8a963185d2f3c679729Yabin Cui report_fp_ = stdout; 6677288501a660ce2616539e8a963185d2f3c679729Yabin Cui } else { 6687288501a660ce2616539e8a963185d2f3c679729Yabin Cui report_fp_ = fopen(report_filename_.c_str(), "w"); 6697288501a660ce2616539e8a963185d2f3c679729Yabin Cui if (report_fp_ == nullptr) { 6707288501a660ce2616539e8a963185d2f3c679729Yabin Cui PLOG(ERROR) << "failed to open file " << report_filename_; 6717288501a660ce2616539e8a963185d2f3c679729Yabin Cui return false; 6727288501a660ce2616539e8a963185d2f3c679729Yabin Cui } 6737288501a660ce2616539e8a963185d2f3c679729Yabin Cui file_handler.reset(report_fp_); 6747288501a660ce2616539e8a963185d2f3c679729Yabin Cui } 6752672dea3f1112b13678103023011c797ca283bacYabin Cui PrintReportContext(); 676589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cui CollectReportWidth(); 6772672dea3f1112b13678103023011c797ca283bacYabin Cui PrintReportHeader(); 6782672dea3f1112b13678103023011c797ca283bacYabin Cui sample_tree_->VisitAllSamples( 6792672dea3f1112b13678103023011c797ca283bacYabin Cui std::bind(&ReportCommand::PrintReportEntry, this, std::placeholders::_1)); 6807288501a660ce2616539e8a963185d2f3c679729Yabin Cui fflush(report_fp_); 6817288501a660ce2616539e8a963185d2f3c679729Yabin Cui if (ferror(report_fp_) != 0) { 6827288501a660ce2616539e8a963185d2f3c679729Yabin Cui PLOG(ERROR) << "print report failed"; 6837288501a660ce2616539e8a963185d2f3c679729Yabin Cui return false; 6847288501a660ce2616539e8a963185d2f3c679729Yabin Cui } 6857288501a660ce2616539e8a963185d2f3c679729Yabin Cui return true; 6862672dea3f1112b13678103023011c797ca283bacYabin Cui} 6872672dea3f1112b13678103023011c797ca283bacYabin Cui 6882672dea3f1112b13678103023011c797ca283bacYabin Cuivoid ReportCommand::PrintReportContext() { 689d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui const EventType* event_type = FindEventTypeByConfig(event_attr_.type, event_attr_.config); 6902672dea3f1112b13678103023011c797ca283bacYabin Cui std::string event_type_name; 6912672dea3f1112b13678103023011c797ca283bacYabin Cui if (event_type != nullptr) { 6922672dea3f1112b13678103023011c797ca283bacYabin Cui event_type_name = event_type->name; 6932672dea3f1112b13678103023011c797ca283bacYabin Cui } else { 6942672dea3f1112b13678103023011c797ca283bacYabin Cui event_type_name = 6952672dea3f1112b13678103023011c797ca283bacYabin Cui android::base::StringPrintf("(type %u, config %llu)", event_attr_.type, event_attr_.config); 6962672dea3f1112b13678103023011c797ca283bacYabin Cui } 697d713f959ec1fe07ed993e2c9f4166b52aa98a58cYabin Cui if (!record_cmdline_.empty()) { 6987288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "Cmdline: %s\n", record_cmdline_.c_str()); 699d713f959ec1fe07ed993e2c9f4166b52aa98a58cYabin Cui } 7007288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "Samples: %" PRIu64 " of event '%s'\n", sample_tree_->TotalSamples(), 7017288501a660ce2616539e8a963185d2f3c679729Yabin Cui event_type_name.c_str()); 7027288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "Event count: %" PRIu64 "\n\n", sample_tree_->TotalPeriod()); 7032672dea3f1112b13678103023011c797ca283bacYabin Cui} 7042672dea3f1112b13678103023011c797ca283bacYabin Cui 705589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cuivoid ReportCommand::CollectReportWidth() { 706589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cui sample_tree_->VisitAllSamples( 707589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cui std::bind(&ReportCommand::CollectReportEntryWidth, this, std::placeholders::_1)); 708589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cui} 709589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cui 710589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cuivoid ReportCommand::CollectReportEntryWidth(const SampleEntry& sample) { 71136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui for (auto& item : displayable_items_) { 71236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui item->AdjustWidth(sample); 713589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cui } 714589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cui} 715589b82fd6c0bf421ca09bc60b03333ad22fd3ee7Yabin Cui 7162672dea3f1112b13678103023011c797ca283bacYabin Cuivoid ReportCommand::PrintReportHeader() { 71736c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui for (size_t i = 0; i < displayable_items_.size(); ++i) { 71836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui auto& item = displayable_items_[i]; 71936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui if (i != displayable_items_.size() - 1) { 7207288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "%-*s ", static_cast<int>(item->Width()), item->Name().c_str()); 72136c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else { 7227288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "%s\n", item->Name().c_str()); 72336c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 72436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 7252672dea3f1112b13678103023011c797ca283bacYabin Cui} 7262672dea3f1112b13678103023011c797ca283bacYabin Cui 7272672dea3f1112b13678103023011c797ca283bacYabin Cuivoid ReportCommand::PrintReportEntry(const SampleEntry& sample) { 72836c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui for (size_t i = 0; i < displayable_items_.size(); ++i) { 72936c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui auto& item = displayable_items_[i]; 73036c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui if (i != displayable_items_.size() - 1) { 7317288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "%-*s ", static_cast<int>(item->Width()), item->Show(sample).c_str()); 73236c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } else { 7337288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "%s\n", item->Show(sample).c_str()); 73436c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 73536c662b538bd89e591b1bfcbce59fc0de3602bf6Yabin Cui } 736ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui if (print_callgraph_) { 737ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui PrintCallGraph(sample); 738ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } 739ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui} 740ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui 7417288501a660ce2616539e8a963185d2f3c679729Yabin Cuivoid ReportCommand::PrintCallGraph(const SampleEntry& sample) { 7427288501a660ce2616539e8a963185d2f3c679729Yabin Cui std::string prefix = " "; 7437288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "%s|\n", prefix.c_str()); 7447288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "%s-- %s\n", prefix.c_str(), sample.symbol->DemangledName()); 7457288501a660ce2616539e8a963185d2f3c679729Yabin Cui prefix.append(3, ' '); 7467288501a660ce2616539e8a963185d2f3c679729Yabin Cui for (size_t i = 0; i < sample.callchain.children.size(); ++i) { 7477288501a660ce2616539e8a963185d2f3c679729Yabin Cui PrintCallGraphEntry(1, prefix, sample.callchain.children[i], sample.callchain.children_period, 7487288501a660ce2616539e8a963185d2f3c679729Yabin Cui (i + 1 == sample.callchain.children.size())); 7497288501a660ce2616539e8a963185d2f3c679729Yabin Cui } 7507288501a660ce2616539e8a963185d2f3c679729Yabin Cui} 7517288501a660ce2616539e8a963185d2f3c679729Yabin Cui 7527288501a660ce2616539e8a963185d2f3c679729Yabin Cuivoid ReportCommand::PrintCallGraphEntry(size_t depth, std::string prefix, 7537288501a660ce2616539e8a963185d2f3c679729Yabin Cui const std::unique_ptr<CallChainNode>& node, 7547288501a660ce2616539e8a963185d2f3c679729Yabin Cui uint64_t parent_period, bool last) { 755ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui if (depth > 20) { 756ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui LOG(WARNING) << "truncated callgraph at depth " << depth; 757ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui return; 758ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } 759ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui prefix += "|"; 7607288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "%s\n", prefix.c_str()); 761ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui if (last) { 762ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui prefix.back() = ' '; 763ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } 764ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui std::string percentage_s = "-- "; 765ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui if (node->period + node->children_period != parent_period) { 766ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui double percentage = 100.0 * (node->period + node->children_period) / parent_period; 767ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui percentage_s = android::base::StringPrintf("--%.2lf%%-- ", percentage); 768ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } 7697288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "%s%s%s\n", prefix.c_str(), percentage_s.c_str(), node->chain[0]->symbol->DemangledName()); 770ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui prefix.append(percentage_s.size(), ' '); 771ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui for (size_t i = 1; i < node->chain.size(); ++i) { 7727288501a660ce2616539e8a963185d2f3c679729Yabin Cui fprintf(report_fp_, "%s%s\n", prefix.c_str(), node->chain[i]->symbol->DemangledName()); 773ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } 774ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui 775ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui for (size_t i = 0; i < node->children.size(); ++i) { 776ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui PrintCallGraphEntry(depth + 1, prefix, node->children[i], node->children_period, 777ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui (i + 1 == node->children.size())); 778ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui } 779ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui} 780ecb9a302b52b034610efb85bd73cb473e7c4ddb2Yabin Cui 78108663eb56b17e5ce1a9b0030d5a965306de0e3aeYabin Cuivoid RegisterReportCommand() { 7822672dea3f1112b13678103023011c797ca283bacYabin Cui RegisterCommand("report", [] { return std::unique_ptr<Command>(new ReportCommand()); }); 7832672dea3f1112b13678103023011c797ca283bacYabin Cui} 784