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 <cstdlib> 21 #include <functional> 22 #include <map> 23 #include <optional> 24 #include <set> 25 #include <stdio.h> 26 #include <tuple> 27 #include <linux/perf_event.h> 28 29 #include "perf_file_reader.h" 30 #if 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 "\n" 100 ), recordFile_ {"perf.data", ""} // default file path is perf.data 101 // clang-format on 102 { 103 } 104 bool OnSubCommand(std::vector<std::string> &args) override; 105 bool ParseOption(std::vector<std::string> &args) override; 106 void DumpOptions(void) const override; 107 static bool RegisterSubCommandReport(void); 108 bool RecordCallBack(std::unique_ptr<PerfEventRecord> record); 109 110 ~SubCommandReport(); 111 112 private: 113 void ProcessSample(std::unique_ptr<PerfRecordSample> &); 114 void BroadcastSample(std::unique_ptr<PerfRecordSample> &); 115 116 bool VerifyOption(); 117 bool VerifyDisplayOption(); 118 119 // load 120 bool PrepareOutput(); 121 bool LoadPerfData(); 122 void ProcessFeaturesData(); 123 void LoadEventConfigData(); 124 void LoadAttrSection(); 125 void LoadEventDesc(); 126 void ProcessSymbolsData(); 127 void LoadPerfDataCompleted(); 128 129 bool OutputReport(); 130 bool OutputStd(); 131 132 // prefdata 133 bool showCallStack_ = false; 134 bool diffMode_ = false; 135 136 // create record file reader pointer 137 std::unique_ptr<PerfFileReader> recordFileReader_; 138 std::vector<std::string> symbolsPaths_; 139 140 // report file name , if empty will use stdout 141 std::string reportFile_; 142 143 // for diff report 144 enum RecordIndex { FIRST = 0, SECOND = 1, MAX = 2, CURRENT = -1 } index_ = FIRST; 145 std::string recordFile_[MAX]; 146 ReportOption reportOption_; 147 Report report_[MAX] = {reportOption_, reportOption_}; 148 inline Report &GetReport(RecordIndex index = CURRENT, int configId = 0) 149 { 150 if (index == CURRENT) { 151 return report_[index_]; 152 } else { 153 return report_[index]; 154 } 155 } 156 157 std::vector<std::string> configNames_; 158 std::set<uint64_t> cpuOffids_; 159 160 const std::string cpuOffEventName = "sched:sched_switch"; 161 bool cpuOffMode_ = false; 162 std::map<pid_t, std::unique_ptr<PerfRecordSample>> prevSampleCache_; 163 void FlushCacheRecord(); 164 165 // in debug mode we will output some more debug info 166 bool debug_ = false; 167 bool branch_ = false; 168 bool jsonFormat_ = false; 169 170 FILE *output_ = nullptr; 171 172 std::unique_ptr<ReportJsonFile> reportJsonFile_ = nullptr; 173 174 bool protobufFormat_ = false; 175 #if HAVE_PROTOBUF 176 std::unique_ptr<ReportProtobufFileWriter> protobufOutputFileWriter_ = nullptr; 177 void UpdateReportInfo(); 178 #endif 179 friend class SubCommandReportTest; 180 FRIEND_TEST(SubCommandReportTest, TestLoadPerfData); 181 FRIEND_TEST(SubCommandReportTest, TestOutputReport); 182 FRIEND_TEST(SubCommandReportTest, TestOutputStd); 183 FRIEND_TEST(SubCommandReportTest, TestVerifyOption); 184 FRIEND_TEST(SubCommandReportTest, TestVerifyDisplayOption); 185 FRIEND_TEST(SubCommandReportTest, TestPrepareConsole); 186 FRIEND_TEST(SubCommandReportTest, TestPrepareConsole); 187 }; 188 } // namespace HiPerf 189 } // namespace Developtools 190 } // namespace OHOS 191 #endif // SUBCOMMAND_REPORT_H 192