• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 && 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) == HiperfError::NO_ERR ? 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 && 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) == HiperfError::NO_ERR ? 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         HLOGW("perfFile is nullptr.");
123         return result.c_str();
124     }
125 
126     auto reader = GetReader(perfFile);
127     if (reader == nullptr) {
128         HLOGW("reader is nullptr.");
129         return result.c_str();
130     }
131     // found symbols in file
132     reader->ReadFeatureSection();
133     for (auto &featureSection : reader->GetFeatureSections()) {
134         if (featureSection->featureId_ == FEATURE::HIPERF_FILES_SYMBOL) {
135             const PerfFileSectionSymbolsFiles *sectionSymbolsFiles =
136                 static_cast<const PerfFileSectionSymbolsFiles *>(featureSection.get());
137             auto it = sectionSymbolsFiles->symbolFileStructs_.begin();
138             while (it != sectionSymbolsFiles->symbolFileStructs_.end()) {
139                 HLOGD("%s buildId:%s\n", it->filePath_.c_str(), it->buildId_.c_str());
140                 result.append("[");
141                 result.append(it->filePath_.c_str());
142                 result.append(",");
143                 result.append(it->buildId_.c_str());
144                 result.append("]");
145                 result.append(",");
146                 it++;
147             }
148             result[result.size() >= 1 ? result.size() - 1 : 0] = '\0';
149         }
150     }
151     return result.c_str();
152 }
153 
ReportGetBuildId(const char * elfPath)154 const char *ReportGetBuildId(const char *elfPath)
155 {
156     static std::string buildId; // static for hold the c_str buffer
157     buildId.clear();
158     std::string path(elfPath);
159     std::shared_ptr<DfxElf> elfFile = std::make_shared<DfxElf>(path);
160     buildId = elfFile->GetBuildId();
161     return buildId.c_str();
162 }
163 
ReportGetElfArch(const char * elfPath)164 const char *ReportGetElfArch(const char *elfPath)
165 {
166     std::string path(elfPath);
167     std::shared_ptr<DfxElf> elfFile = std::make_shared<DfxElf>(path);
168     const char *machineName = "unknown";
169     switch (elfFile->GetArchType()) {
170         case ArchType::ARCH_ARM:
171             machineName = "arm";
172             break;
173         case ArchType::ARCH_ARM64:
174             machineName = "arm64";
175             break;
176         case ArchType::ARCH_X86:
177             machineName = "x86";
178             break;
179         case ArchType::ARCH_X86_64:
180             machineName = "x86_64";
181             break;
182         default:
183             break;
184     }
185     HLOGD("elf '%s' mache type is %s \n", elfPath, machineName);
186     return machineName;
187 }
188 
Dump(const char * fileName)189 int Dump(const char *fileName)
190 {
191     std::unique_ptr<SubCommandDump> dump = std::make_unique<SubCommandDump>();
192     HLOGD("dump the file %s\n", fileName);
193     if (fileName != nullptr) {
194         std::vector<std::string> args;
195         args.emplace_back(fileName);
196         if (dump->ParseOption(args)) {
197             return dump->OnSubCommand(args) == HiperfError::NO_ERR ? 0 : -1;
198         }
199     }
200     return -1;
201 }
202 
203 } // extern "C"
204