1/* 2 * Copyright (c) 2021-2023 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#include "hiperf_libreport.h" 16 17#include "debug_logger.h" 18#include "dfx_elf.h" 19#include "perf_file_reader.h" 20#include "subcommand_dump.h" 21#include "subcommand_report.h" 22#include "utilities.h" 23 24using namespace OHOS::Developtools::HiPerf; 25extern "C" { 26// this is a demo function 27const char *EchoLoopBack(const char *echo) 28{ 29 HLOGD("EchoLoopBack:%s\n", echo); 30 return echo; 31} 32 33int SetDebug(bool enable) 34{ 35#ifdef HIPERF_DEBUG 36 if (enable) { 37 DebugLogger::GetInstance()->SetLogLevel(LEVEL_VERBOSE); 38 DebugLogger::GetInstance()->Disable(false); 39 } else { 40 DebugLogger::GetInstance()->Disable(true); 41 } 42#endif 43 return 0; 44} 45 46int Report(const char *perfFile, const char *reportFile, const char *reportOptions) 47{ 48 std::unique_ptr<SubCommandReport> report = std::make_unique<SubCommandReport>(); 49 HLOGD("report the file %s to %s\n", perfFile, reportFile); 50 if (perfFile != nullptr and reportFile != nullptr) { 51 std::vector<std::string> args; 52 args.emplace_back("-i"); 53 args.emplace_back(perfFile); 54 args.emplace_back("-o"); 55 args.emplace_back(reportFile); 56 if (reportOptions != nullptr) { 57 std::vector<std::string> options = StringSplit(reportOptions); 58 for (std::string &option : options) { 59 args.emplace_back(option); 60 } 61 } 62 if (report->ParseOption(args)) { 63 return report->OnSubCommand(args) ? 0 : -1; 64 } 65 } else { 66 printf("path is nullptr\n"); 67 } 68 return -1; 69} 70 71int ReportJson(const char *perfFile, const char *reportFile) 72{ 73 return ReportUnwindJson(perfFile, reportFile, nullptr); 74} 75 76int ReportUnwindJson(const char *perfFile, const char *reportFile, const char *symbolsDir) 77{ 78 std::unique_ptr<SubCommandReport> report = std::make_unique<SubCommandReport>(); 79 HLOGD("report the file %s to json file %s symbols from %s\n", perfFile, reportFile, symbolsDir); 80 if (perfFile != nullptr and reportFile != nullptr) { 81 std::vector<std::string> args; 82 args.emplace_back("-i"); 83 args.emplace_back(perfFile); 84 args.emplace_back("-o"); 85 args.emplace_back(reportFile); 86 args.emplace_back("--json"); 87 if (symbolsDir != nullptr) { 88 args.emplace_back("--symbol-dir"); 89 args.emplace_back(symbolsDir); 90 } 91 if (report->ParseOption(args)) { 92 return report->OnSubCommand(args) ? 0 : -1; 93 } 94 } 95 return -1; 96} 97 98static std::unique_ptr<PerfFileReader> GetReader(const std::string &fileName) 99{ 100 // check if file exist 101 if (access(fileName.c_str(), F_OK) != 0) { 102 // file not exists 103 printf("Can not access data file %s\n", fileName.c_str()); 104 return nullptr; 105 } 106 107 auto reader = PerfFileReader::Instance(fileName); 108 if (reader == nullptr) { 109 printf("%s format not correct\n", fileName.c_str()); 110 return nullptr; 111 } else { 112 return reader; 113 } 114} 115 116const char *ReportGetSymbolFiles(const char *perfFile) 117{ 118 HLOGD("report the file %s for symbols \n", perfFile); 119 static std::string result; // static for hold the c_str buffer 120 result.clear(); 121 if (perfFile == nullptr) { 122 return result.c_str(); 123 } 124 125 auto reader = GetReader(perfFile); 126 if (reader == nullptr) { 127 return result.c_str(); 128 } 129 // found symbols in file 130 reader->ReadFeatureSection(); 131 for (auto &featureSection : reader->GetFeatureSections()) { 132 if (featureSection->featureId_ == FEATURE::HIPERF_FILES_SYMBOL) { 133 const PerfFileSectionSymbolsFiles *sectionSymbolsFiles = 134 static_cast<const PerfFileSectionSymbolsFiles *>(featureSection.get()); 135 auto it = sectionSymbolsFiles->symbolFileStructs_.begin(); 136 while (it != sectionSymbolsFiles->symbolFileStructs_.end()) { 137 HLOGD("%s buildId:%s\n", it->filePath_.c_str(), it->buildId_.c_str()); 138 result.append("["); 139 result.append(it->filePath_.c_str()); 140 result.append(","); 141 result.append(it->buildId_.c_str()); 142 result.append("]"); 143 result.append(","); 144 it++; 145 } 146 result[result.size() >= 1 ? result.size() - 1 : 0] = '\0'; 147 } 148 } 149 return result.c_str(); 150} 151 152const char *ReportGetBuildId(const char *elfPath) 153{ 154 static std::string buildId; // static for hold the c_str buffer 155 buildId.clear(); 156 std::string path(elfPath); 157 std::shared_ptr<DfxElf> elfFile = std::make_shared<DfxElf>(path); 158 buildId = elfFile->GetBuildId(); 159 return buildId.c_str(); 160} 161 162const char *ReportGetElfArch(const char *elfPath) 163{ 164 std::string path(elfPath); 165 std::shared_ptr<DfxElf> elfFile = std::make_shared<DfxElf>(path); 166 const char *machineName = "unknown"; 167 switch (elfFile->GetArchType()) { 168 case ArchType::ARCH_ARM: 169 machineName = "arm"; 170 break; 171 case ArchType::ARCH_ARM64: 172 machineName = "arm64"; 173 break; 174 case ArchType::ARCH_X86: 175 machineName = "x86"; 176 break; 177 case ArchType::ARCH_X86_64: 178 machineName = "x86_64"; 179 break; 180 default: 181 break; 182 } 183 HLOGD("elf '%s' mache type is %s \n", elfPath, machineName); 184 return machineName; 185} 186 187int Dump(const char *fileName) 188{ 189 std::unique_ptr<SubCommandDump> dump = std::make_unique<SubCommandDump>(); 190 HLOGD("dump the file %s\n", fileName); 191 if (fileName != nullptr) { 192 std::vector<std::string> args; 193 args.emplace_back(fileName); 194 if (dump->ParseOption(args)) { 195 return dump->OnSubCommand(args) ? 0 : -1; 196 } 197 } 198 return -1; 199} 200 201} // extern "C" 202