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
24 using namespace OHOS::Developtools::HiPerf;
25 extern "C" {
26 // this is a demo function
EchoLoopBack(const char * echo)27 const char *EchoLoopBack(const char *echo)
28 {
29 HLOGD("EchoLoopBack:%s\n", echo);
30 return echo;
31 }
32
SetDebug(bool enable)33 int 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
Report(const char * perfFile,const char * reportFile,const char * reportOptions)46 int 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
ReportJson(const char * perfFile,const char * reportFile)71 int ReportJson(const char *perfFile, const char *reportFile)
72 {
73 return ReportUnwindJson(perfFile, reportFile, nullptr);
74 }
75
ReportUnwindJson(const char * perfFile,const char * reportFile,const char * symbolsDir)76 int 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
GetReader(const std::string & fileName)98 static 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
ReportGetSymbolFiles(const char * perfFile)116 const 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.get()->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] = '\0';
147 }
148 }
149 return result.c_str();
150 }
151
ReportGetBuildId(const char * elfPath)152 const 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
ReportGetElfArch(const char * elfPath)162 const 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
Dump(const char * fileName)187 int 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