• 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 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