148f512ceSopenharmony_ci/* 248f512ceSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 448f512ceSopenharmony_ci * you may not use this file except in compliance with the License. 548f512ceSopenharmony_ci * You may obtain a copy of the License at 648f512ceSopenharmony_ci * 748f512ceSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 848f512ceSopenharmony_ci * 948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and 1348f512ceSopenharmony_ci * limitations under the License. 1448f512ceSopenharmony_ci */ 1548f512ceSopenharmony_ci 1648f512ceSopenharmony_ci#ifndef SUBCOMMAND_REPORT_H 1748f512ceSopenharmony_ci#define SUBCOMMAND_REPORT_H 1848f512ceSopenharmony_ci 1948f512ceSopenharmony_ci#include <algorithm> 2048f512ceSopenharmony_ci#include <cstdio> 2148f512ceSopenharmony_ci#include <cstdlib> 2248f512ceSopenharmony_ci#include <functional> 2348f512ceSopenharmony_ci#include <map> 2448f512ceSopenharmony_ci#include <optional> 2548f512ceSopenharmony_ci#include <set> 2648f512ceSopenharmony_ci#include <tuple> 2748f512ceSopenharmony_ci#include <linux/perf_event.h> 2848f512ceSopenharmony_ci 2948f512ceSopenharmony_ci#include "perf_file_reader.h" 3048f512ceSopenharmony_ci#if defined(HAVE_PROTOBUF) && HAVE_PROTOBUF 3148f512ceSopenharmony_ci#include "report_protobuf_file.h" 3248f512ceSopenharmony_ci#endif 3348f512ceSopenharmony_ci#include "debug_logger.h" 3448f512ceSopenharmony_ci#include "option.h" 3548f512ceSopenharmony_ci#include "perf_event_record.h" 3648f512ceSopenharmony_ci#include "report.h" 3748f512ceSopenharmony_ci#include "report_json_file.h" 3848f512ceSopenharmony_ci#include "subcommand.h" 3948f512ceSopenharmony_ci#include "symbols_file.h" 4048f512ceSopenharmony_ci#include "utilities.h" 4148f512ceSopenharmony_ci#include "virtual_runtime.h" 4248f512ceSopenharmony_ci 4348f512ceSopenharmony_cinamespace OHOS { 4448f512ceSopenharmony_cinamespace Developtools { 4548f512ceSopenharmony_cinamespace HiPerf { 4648f512ceSopenharmony_ciclass SubCommandReport : public SubCommand { 4748f512ceSopenharmony_cipublic: 4848f512ceSopenharmony_ci SubCommandReport() 4948f512ceSopenharmony_ci // clang-format off 5048f512ceSopenharmony_ci : SubCommand("report", "report sampling information from perf.data format file", 5148f512ceSopenharmony_ci "Usage: hiperf report [options]\n" 5248f512ceSopenharmony_ci " The default options are same as :\n" 5348f512ceSopenharmony_ci " -i perf.data --sort comm,pid,tid,dso,func\n" 5448f512ceSopenharmony_ci " --symbol-dir <dir>\n" 5548f512ceSopenharmony_ci " use symbols path to find symbols.\n" 5648f512ceSopenharmony_ci " separate the paths with commas.\n" 5748f512ceSopenharmony_ci " --limit-percent <number>\n" 5848f512ceSopenharmony_ci " only show heat percent limit content.\n" 5948f512ceSopenharmony_ci " -s / --call-stack\n" 6048f512ceSopenharmony_ci " show the unwind callstack\n" 6148f512ceSopenharmony_ci " --call-stack-limit-percent <number>\n" 6248f512ceSopenharmony_ci " only show the callstack heat percent limit content.\n" 6348f512ceSopenharmony_ci " --proto\n" 6448f512ceSopenharmony_ci " show protobuf content in the save file name.\n" 6548f512ceSopenharmony_ci " default file name is perf.data.\n" 6648f512ceSopenharmony_ci " --json\n" 6748f512ceSopenharmony_ci " report in json format.\n" 6848f512ceSopenharmony_ci " default file name is perf.data.\n" 6948f512ceSopenharmony_ci " --diff <target file>\n" 7048f512ceSopenharmony_ci " show the diff result from -i to -diff .\n" 7148f512ceSopenharmony_ci " example: \"report -i a.data --diff b.data\"\n" 7248f512ceSopenharmony_ci " --branch\n" 7348f512ceSopenharmony_ci " show the branch from address instead of ip address\n" 7448f512ceSopenharmony_ci " --<keys> <keyname1>[,keyname2][,...]\n" 7548f512ceSopenharmony_ci " select able keys: comms,pids,tids,dsos,funcs,from_dsos,from_funcs\n" 7648f512ceSopenharmony_ci " example: --comms hiperf\n" 7748f512ceSopenharmony_ci " --sort <key1>[,key2][,...]\n" 7848f512ceSopenharmony_ci " Choose some keywords.\n" 7948f512ceSopenharmony_ci " These keywords will be used for sorting.\n" 8048f512ceSopenharmony_ci " Only selected keywords will appear in the report.\n" 8148f512ceSopenharmony_ci "\n" 8248f512ceSopenharmony_ci " pid -- process id\n" 8348f512ceSopenharmony_ci " tid -- thread id\n" 8448f512ceSopenharmony_ci " comm -- thread name (can be changed for same thread)\n" 8548f512ceSopenharmony_ci " dso -- like dso name , or elf path\n" 8648f512ceSopenharmony_ci " func -- function name in the symbols\n" 8748f512ceSopenharmony_ci "\n" 8848f512ceSopenharmony_ci " in branch mode:\n" 8948f512ceSopenharmony_ci " from_dso -- branched from dso or elf\n" 9048f512ceSopenharmony_ci " from_func -- branched from function\n" 9148f512ceSopenharmony_ci " dso -- means branched to dso or elf\n" 9248f512ceSopenharmony_ci " func -- means branched to function\n" 9348f512ceSopenharmony_ci " -i <filename>\n" 9448f512ceSopenharmony_ci " perf data file to report, default is perf.data\n" 9548f512ceSopenharmony_ci " -o <filename>\n" 9648f512ceSopenharmony_ci " report file name. if empty will use stdout print\n" 9748f512ceSopenharmony_ci " --hide_count\n" 9848f512ceSopenharmony_ci " will not show count in report\n" 9948f512ceSopenharmony_ci " --dumpoptions\n" 10048f512ceSopenharmony_ci " Dump command options.\n" 10148f512ceSopenharmony_ci "\n" 10248f512ceSopenharmony_ci ), recordFile_ {"perf.data", ""} // default file path is perf.data 10348f512ceSopenharmony_ci // clang-format on 10448f512ceSopenharmony_ci { 10548f512ceSopenharmony_ci } 10648f512ceSopenharmony_ci bool OnSubCommand(std::vector<std::string> &args) override; 10748f512ceSopenharmony_ci bool ParseOption(std::vector<std::string> &args) override; 10848f512ceSopenharmony_ci void DumpOptions(void) const override; 10948f512ceSopenharmony_ci static bool RegisterSubCommandReport(void); 11048f512ceSopenharmony_ci bool RecordCallBack(std::unique_ptr<PerfEventRecord> record); 11148f512ceSopenharmony_ci 11248f512ceSopenharmony_ci ~SubCommandReport(); 11348f512ceSopenharmony_ci 11448f512ceSopenharmony_ciprivate: 11548f512ceSopenharmony_ci void ProcessSample(std::unique_ptr<PerfRecordSample> &); 11648f512ceSopenharmony_ci void BroadcastSample(std::unique_ptr<PerfRecordSample> &); 11748f512ceSopenharmony_ci 11848f512ceSopenharmony_ci bool VerifyOption(); 11948f512ceSopenharmony_ci bool VerifyDisplayOption(); 12048f512ceSopenharmony_ci 12148f512ceSopenharmony_ci // load 12248f512ceSopenharmony_ci bool PrepareOutput(); 12348f512ceSopenharmony_ci bool LoadPerfData(); 12448f512ceSopenharmony_ci void ProcessFeaturesData(); 12548f512ceSopenharmony_ci void LoadEventConfigData(); 12648f512ceSopenharmony_ci void LoadAttrSection(); 12748f512ceSopenharmony_ci void LoadEventDesc(); 12848f512ceSopenharmony_ci void ProcessSymbolsData(); 12948f512ceSopenharmony_ci void LoadPerfDataCompleted(); 13048f512ceSopenharmony_ci void ProcessUniStackTableData(); 13148f512ceSopenharmony_ci 13248f512ceSopenharmony_ci bool OutputReport(); 13348f512ceSopenharmony_ci bool OutputStd(); 13448f512ceSopenharmony_ci 13548f512ceSopenharmony_ci // prefdata 13648f512ceSopenharmony_ci bool showCallStack_ = false; 13748f512ceSopenharmony_ci bool diffMode_ = false; 13848f512ceSopenharmony_ci 13948f512ceSopenharmony_ci // create record file reader pointer 14048f512ceSopenharmony_ci std::unique_ptr<PerfFileReader> recordFileReader_; 14148f512ceSopenharmony_ci std::vector<std::string> symbolsPaths_; 14248f512ceSopenharmony_ci 14348f512ceSopenharmony_ci // report file name , if empty will use stdout 14448f512ceSopenharmony_ci std::string reportFile_; 14548f512ceSopenharmony_ci 14648f512ceSopenharmony_ci // for diff report 14748f512ceSopenharmony_ci enum RecordIndex { FIRST = 0, SECOND = 1, MAX = 2, CURRENT = -1 } index_ = FIRST; 14848f512ceSopenharmony_ci std::string recordFile_[MAX]; 14948f512ceSopenharmony_ci ReportOption reportOption_; 15048f512ceSopenharmony_ci Report report_[MAX] = {reportOption_, reportOption_}; 15148f512ceSopenharmony_ci inline Report &GetReport(RecordIndex index = CURRENT, int configId = 0) 15248f512ceSopenharmony_ci { 15348f512ceSopenharmony_ci if (index == CURRENT) { 15448f512ceSopenharmony_ci return report_[index_]; 15548f512ceSopenharmony_ci } else { 15648f512ceSopenharmony_ci return report_[index]; 15748f512ceSopenharmony_ci } 15848f512ceSopenharmony_ci } 15948f512ceSopenharmony_ci 16048f512ceSopenharmony_ci std::vector<std::string> configNames_; 16148f512ceSopenharmony_ci std::set<uint64_t> cpuOffids_; 16248f512ceSopenharmony_ci 16348f512ceSopenharmony_ci const std::string cpuOffEventName = "sched:sched_switch"; 16448f512ceSopenharmony_ci bool cpuOffMode_ = false; 16548f512ceSopenharmony_ci std::map<pid_t, std::unique_ptr<PerfRecordSample>> prevSampleCache_; 16648f512ceSopenharmony_ci void FlushCacheRecord(); 16748f512ceSopenharmony_ci 16848f512ceSopenharmony_ci // in debug mode we will output some more debug info 16948f512ceSopenharmony_ci bool debug_ = false; 17048f512ceSopenharmony_ci bool branch_ = false; 17148f512ceSopenharmony_ci bool jsonFormat_ = false; 17248f512ceSopenharmony_ci 17348f512ceSopenharmony_ci FILE *output_ = nullptr; 17448f512ceSopenharmony_ci 17548f512ceSopenharmony_ci std::unique_ptr<ReportJsonFile> reportJsonFile_ = nullptr; 17648f512ceSopenharmony_ci 17748f512ceSopenharmony_ci bool protobufFormat_ = false; 17848f512ceSopenharmony_ci#if defined(HAVE_PROTOBUF) && HAVE_PROTOBUF 17948f512ceSopenharmony_ci std::unique_ptr<ReportProtobufFileWriter> protobufOutputFileWriter_ = nullptr; 18048f512ceSopenharmony_ci void UpdateReportInfo(); 18148f512ceSopenharmony_ci#endif 18248f512ceSopenharmony_ci friend class SubCommandReportTest; 18348f512ceSopenharmony_ci FRIEND_TEST(SubCommandReportTest, TestLoadPerfData); 18448f512ceSopenharmony_ci FRIEND_TEST(SubCommandReportTest, TestOutputReport); 18548f512ceSopenharmony_ci FRIEND_TEST(SubCommandReportTest, TestOutputStd); 18648f512ceSopenharmony_ci FRIEND_TEST(SubCommandReportTest, TestVerifyOption); 18748f512ceSopenharmony_ci FRIEND_TEST(SubCommandReportTest, TestVerifyDisplayOption); 18848f512ceSopenharmony_ci FRIEND_TEST(SubCommandReportTest, TestPrepareConsole); 18948f512ceSopenharmony_ci FRIEND_TEST(SubCommandReportTest, TestPrepareConsole); 19048f512ceSopenharmony_ci 19148f512ceSopenharmony_ci void SetHM(); 19248f512ceSopenharmony_ci}; 19348f512ceSopenharmony_ci} // namespace HiPerf 19448f512ceSopenharmony_ci} // namespace Developtools 19548f512ceSopenharmony_ci} // namespace OHOS 19648f512ceSopenharmony_ci#endif // SUBCOMMAND_REPORT_H 197