1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef SUBCOMMAND_REPORT_H 17 #define SUBCOMMAND_REPORT_H 18 19 #include <algorithm> 20 #include <cstdio> 21 #include <cstdlib> 22 #include <functional> 23 #include <map> 24 #include <optional> 25 #include <set> 26 #include <tuple> 27 #include <linux/perf_event.h> 28 29 #include "perf_file_reader.h" 30 #if defined(HAVE_PROTOBUF) && HAVE_PROTOBUF 31 #include "report_protobuf_file.h" 32 #endif 33 #include "debug_logger.h" 34 #include "option.h" 35 #include "perf_event_record.h" 36 #include "report.h" 37 #include "report_json_file.h" 38 #include "subcommand.h" 39 #include "symbols_file.h" 40 #include "utilities.h" 41 #include "virtual_runtime.h" 42 43 namespace OHOS { 44 namespace Developtools { 45 namespace HiPerf { 46 class SubCommandReport : public SubCommand { 47 public: SubCommandReport()48 SubCommandReport() 49 // clang-format off 50 : SubCommand("report", "report sampling information from perf.data format file", 51 "Usage: hiperf report [options]\n" 52 " The default options are same as :\n" 53 " -i perf.data --sort comm,pid,tid,dso,func\n" 54 " --symbol-dir <dir>\n" 55 " use symbols path to find symbols.\n" 56 " separate the paths with commas.\n" 57 " --limit-percent <number>\n" 58 " only show heat percent limit content.\n" 59 " -s / --call-stack\n" 60 " show the unwind callstack\n" 61 " --call-stack-limit-percent <number>\n" 62 " only show the callstack heat percent limit content.\n" 63 " --proto\n" 64 " show protobuf content in the save file name.\n" 65 " default file name is perf.data.\n" 66 " --json\n" 67 " report in json format.\n" 68 " default file name is perf.data.\n" 69 " --diff <target file>\n" 70 " show the diff result from -i to -diff .\n" 71 " example: \"report -i a.data --diff b.data\"\n" 72 " --branch\n" 73 " show the branch from address instead of ip address\n" 74 " --<keys> <keyname1>[,keyname2][,...]\n" 75 " select able keys: comms,pids,tids,dsos,funcs,from_dsos,from_funcs\n" 76 " example: --comms hiperf\n" 77 " --sort <key1>[,key2][,...]\n" 78 " Choose some keywords.\n" 79 " These keywords will be used for sorting.\n" 80 " Only selected keywords will appear in the report.\n" 81 "\n" 82 " pid -- process id\n" 83 " tid -- thread id\n" 84 " comm -- thread name (can be changed for same thread)\n" 85 " dso -- like dso name , or elf path\n" 86 " func -- function name in the symbols\n" 87 "\n" 88 " in branch mode:\n" 89 " from_dso -- branched from dso or elf\n" 90 " from_func -- branched from function\n" 91 " dso -- means branched to dso or elf\n" 92 " func -- means branched to function\n" 93 " -i <filename>\n" 94 " perf data file to report, default is perf.data\n" 95 " -o <filename>\n" 96 " report file name. if empty will use stdout print\n" 97 " --hide_count\n" 98 " will not show count in report\n" 99 " --dumpoptions\n" 100 " Dump command options.\n" 101 "\n" 102 ), recordFile_ {"perf.data", ""} // default file path is perf.data 103 // clang-format on 104 { 105 } 106 bool OnSubCommand(std::vector<std::string> &args) override; 107 bool ParseOption(std::vector<std::string> &args) override; 108 void DumpOptions(void) const override; 109 static bool RegisterSubCommandReport(void); 110 bool RecordCallBack(std::unique_ptr<PerfEventRecord> record); 111 112 ~SubCommandReport(); 113 114 private: 115 void ProcessSample(std::unique_ptr<PerfRecordSample> &); 116 void BroadcastSample(std::unique_ptr<PerfRecordSample> &); 117 118 bool VerifyOption(); 119 bool VerifyDisplayOption(); 120 121 // load 122 bool PrepareOutput(); 123 bool LoadPerfData(); 124 void ProcessFeaturesData(); 125 void LoadEventConfigData(); 126 void LoadAttrSection(); 127 void LoadEventDesc(); 128 void ProcessSymbolsData(); 129 void LoadPerfDataCompleted(); 130 void ProcessUniStackTableData(); 131 132 bool OutputReport(); 133 bool OutputStd(); 134 135 // prefdata 136 bool showCallStack_ = false; 137 bool diffMode_ = false; 138 139 // create record file reader pointer 140 std::unique_ptr<PerfFileReader> recordFileReader_; 141 std::vector<std::string> symbolsPaths_; 142 143 // report file name , if empty will use stdout 144 std::string reportFile_; 145 146 // for diff report 147 enum RecordIndex { FIRST = 0, SECOND = 1, MAX = 2, CURRENT = -1 } index_ = FIRST; 148 std::string recordFile_[MAX]; 149 ReportOption reportOption_; 150 Report report_[MAX] = {reportOption_, reportOption_}; GetReport(RecordIndex index = CURRENT, int configId = 0)151 inline Report &GetReport(RecordIndex index = CURRENT, int configId = 0) 152 { 153 if (index == CURRENT) { 154 return report_[index_]; 155 } else { 156 return report_[index]; 157 } 158 } 159 160 std::vector<std::string> configNames_; 161 std::set<uint64_t> cpuOffids_; 162 163 const std::string cpuOffEventName = "sched:sched_switch"; 164 bool cpuOffMode_ = false; 165 std::map<pid_t, std::unique_ptr<PerfRecordSample>> prevSampleCache_; 166 void FlushCacheRecord(); 167 168 // in debug mode we will output some more debug info 169 bool debug_ = false; 170 bool branch_ = false; 171 bool jsonFormat_ = false; 172 173 FILE *output_ = nullptr; 174 175 std::unique_ptr<ReportJsonFile> reportJsonFile_ = nullptr; 176 177 bool protobufFormat_ = false; 178 #if defined(HAVE_PROTOBUF) && HAVE_PROTOBUF 179 std::unique_ptr<ReportProtobufFileWriter> protobufOutputFileWriter_ = nullptr; 180 void UpdateReportInfo(); 181 #endif 182 friend class SubCommandReportTest; 183 FRIEND_TEST(SubCommandReportTest, TestLoadPerfData); 184 FRIEND_TEST(SubCommandReportTest, TestOutputReport); 185 FRIEND_TEST(SubCommandReportTest, TestOutputStd); 186 FRIEND_TEST(SubCommandReportTest, TestVerifyOption); 187 FRIEND_TEST(SubCommandReportTest, TestVerifyDisplayOption); 188 FRIEND_TEST(SubCommandReportTest, TestPrepareConsole); 189 FRIEND_TEST(SubCommandReportTest, TestPrepareConsole); 190 191 void SetHM(); 192 }; 193 } // namespace HiPerf 194 } // namespace Developtools 195 } // namespace OHOS 196 #endif // SUBCOMMAND_REPORT_H 197