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