• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 #ifndef HIPERF_UTILITIES_H_
16 #define HIPERF_UTILITIES_H_
17 
18 // for security function
19 #include <securec.h>
20 #include <algorithm>
21 #include <cctype>
22 #include <cinttypes>
23 #include <cstdio>
24 #include <fstream>
25 #include <iomanip>
26 #include <iostream>
27 #include <sstream>
28 #include <string>
29 #include <vector>
30 
31 #include <dirent.h>
32 #include <fcntl.h>
33 #include <file_ex.h>
34 #include <stddef.h>
35 #include <sys/stat.h>
36 #include <unique_fd.h>
37 #include <unistd.h>
38 #if !is_mingw
39 #include <gtest/gtest_prod.h>
40 #include <sys/syscall.h>
41 #endif
42 #include <linux/types.h>
43 #include "debug_logger.h"
44 #include "noncopyable.h"
45 
46 // data and value
47 /*
48 long long always 64 only in ILP64, int is 64 otherwise int is always 32
49 */
50 using s8 = __s8;
51 using u8 = __u8;
52 using s16 = __s16;
53 using u16 = __u16;
54 using s32 = __s32;
55 using u32 = __u32;
56 using s64 = __s64;
57 using u64 = __u64;
58 
59 constexpr const int NUMBER_FORMAT_HEX_BASE = 16;
60 constexpr const int BYTE_PRINT_WIDTH = 2;
61 constexpr const int UINT64_PRINT_WIDTH = BYTE_PRINT_WIDTH * 8;
62 constexpr const int BITS_OF_BYTE = 8;
63 constexpr const int BITS_OF_TWO_BYTE = 2 * BITS_OF_BYTE;
64 constexpr const int BITS_OF_FOUR_BYTE = 4 * BITS_OF_BYTE;
65 constexpr const int FULL_PERCENTAGE = 100;
66 constexpr const int FULL_PERCENTAGE_NUM_LEN = 5;      // 100.00
67 constexpr const int FULL_PERCENTAGE_DIFF_NUM_LEN = 6; // +100.00
68 constexpr const int FULL_PERCENTAGE_LEN = 6;          // 100.00%
69 constexpr const int FULL_PERCENTAGE_DIFF_LEN = 7;     // +100.00%
70 constexpr const int THOUSANDS = 1000;
71 constexpr const int HUNDREDS = 100;
72 constexpr const int DEFAULT_STRING_BUF_SIZE = 4096;
73 constexpr const int FIVE_THOUSANDS = 5000;
74 constexpr const int DATA_MAX_SIZE = 1001;
75 #if !is_mingw
76 #ifndef O_BINARY
77 #define O_BINARY 0
78 #endif
79 #endif
80 
81 constexpr const double MS_DUARTION =
82     static_cast<double>(std::chrono::milliseconds::duration::period::den);
83 
84 constexpr uint64_t KILO = 1024;
85 
86 namespace OHOS {
87 namespace Developtools {
88 namespace HiPerf {
89 std::string CanonicalizeSpecPath(const char* src);
90 const std::string EMPTY_STRING = "";
91 const ssize_t ERRINFOLEN = 512;
92 
93 // string function
94 class MemoryHold {
95 public:
~MemoryHold()96     ~MemoryHold()
97     {
98         Clean();
99     }
100     const char *HoldStringView(std::string_view view);
101     // only use in UT
Clean()102     void Clean()
103     {
104         for (auto &p : holder_) {
105             delete[] p;
106         }
107         holder_.clear();
108     }
Get()109     static MemoryHold &Get()
110     {
111         static MemoryHold instance;
112         return instance;
113     }
114 
115 private:
116     std::vector<char *> holder_;
117 };
118 
119 std::string StringReplace(std::string source, const std::string &from, const std::string &to);
120 
121 template<class T>
VectorToString(const std::vector<T> & items)122 std::string VectorToString(const std::vector<T> &items)
123 {
124     if constexpr (std::is_same<T, std::vector<std::string>>::value) {
125         std::vector<std::string> stringItems;
126         for (auto item : items) {
127             stringItems.push_back("[" + VectorToString(item) + "]");
128         }
129         return VectorToString(stringItems);
130     } else {
131         std::string itemsString;
132         const std::string split = ",";
133         for (auto item : items) {
134             if (!itemsString.empty())
135                 itemsString.append(split);
136             if constexpr (std::is_same<T, std::string>::value) {
137                 itemsString.append(item);
138             } else {
139                 itemsString.append(std::to_string(item));
140             }
141         }
142         if (itemsString.empty())
143             itemsString.append("<empty>");
144         return itemsString;
145     }
146 }
147 
148 std::string BufferToHexString(const std::vector<unsigned char> &vec);
149 std::string BufferToHexString(const unsigned char buf[], size_t size);
150 void HexDump(const void *buf, size_t size, size_t max_size = 0);
151 
152 std::string &StringTrim(std::string &s);
153 
154 std::vector<std::string> StringSplit(std::string source, std::string split = ",");
155 
156 size_t SubStringCount(const std::string &source, const std::string &sub);
157 
158 bool StringStartsWith(const std::string &string, const std::string &with);
159 
160 bool StringEndsWith(const std::string &string, const std::string &with);
161 
162 bool IsSameCommand(const std::string &cmdLine, const std::string &cmdName);
163 
164 std::vector<pid_t> GetSubthreadIDs(const pid_t pid);
165 
166 bool IsDigits(const std::string &str);
167 
168 bool IsHexDigits(const std::string &str);
169 
170 constexpr const int COMPRESS_READ_BUF_SIZE = 4096;
171 // compress specified dataFile into gzip file
172 bool CompressFile(const std::string &dataFile, const std::string &destFile);
173 // uncompress specified gzip file into dataFile
174 bool UncompressFile(const std::string &gzipFile, const std::string &dataFile);
175 
176 template<typename... VA>
StringPrintf(const char * stringFormat,VA...args)177 std::string StringPrintf(const char *stringFormat, VA... args)
178 {
179     // check howmany bytes we need
180     char bytes[DEFAULT_STRING_BUF_SIZE];
181     bytes[DEFAULT_STRING_BUF_SIZE - 1] = '\0';
182 
183     if (stringFormat == nullptr) {
184         return EMPTY_STRING;
185     }
186 
187     // print it to bytes
188     if (snprintf_s(bytes, sizeof(bytes), sizeof(bytes) - 1, stringFormat,
189                    args...) < 0) {
190         return EMPTY_STRING;
191     }
192 
193     // make a string return
194     return std::string(bytes);
195 }
196 
197 // path check
198 std::vector<std::string> GetEntriesInDir(const std::string &basePath);
199 
200 std::vector<std::string> GetSubDirs(const std::string &basePath);
201 
202 bool IsDir(const std::string &path);
203 
204 bool IsPath(const std::string &fileName);
205 
206 #if is_mingw
207 const char PATH_SEPARATOR = '\\';
208 #else
209 const char PATH_SEPARATOR = '/';
210 #endif
211 const std::string PATH_SEPARATOR_STR = std::string(1, PATH_SEPARATOR);
212 
213 std::string PlatformPathConvert(const std::string &path);
214 
215 // attribute
216 #define PACKED __attribute__((packed))
217 
218 // data align
219 
220 // some time u will meet signal 7 (SIGBUS), code 1 (BUS_ADRALN) in 32 or 64 arch cpu
221 #define HIPERF_BUF_ALIGN alignas(64)
222 
223 #define ALIGN(size, align) (((size) + (align) - 1) & (~((align) - 1)))
224 
225 uint32_t RoundUp(uint32_t x, const int align);
226 
227 // data convert function
228 template<class T>
229 std::string ToHex(const T &source, int size = sizeof(T), bool prefix = false)
230 {
231     std::stringstream ss;
232     if (prefix) {
233         ss << "0x";
234     }
235     ss << std::hex << std::setw(BYTE_PRINT_WIDTH * size) << std::setfill('0') << (uint64_t)source;
236     return ss.str();
237 }
238 
239 // data move and copy
240 template<class S, class T>
241 size_t inline CopyFromBufferAndMove(S *&buffer, T *dest, size_t size = 0)
242 {
243     if (size == 0) {
244         size = sizeof(T);
245     }
246     if (memcpy_s(dest, size, buffer, size) != EOK) {
247         return size;
248     }
249     buffer = buffer + size;
250     return size;
251 }
252 
253 // file read write
254 bool ReadIntFromProcFile(const std::string &path, int &value);
255 bool WriteIntToProcFile(const std::string &path, int value);
256 std::string ReadFileToString(const std::string &fileName);
257 bool ReadFileToString(const std::string &fileName, std::string &content, size_t fileSize = 0);
258 bool WriteStringToFile(const std::string &fileName, const std::string &value);
259 
260 // stdout
261 class StdoutRecord {
262 public:
~StdoutRecord()263     ~StdoutRecord()
264     {
265         Stop(); // stdout need restore
266     }
267     StdoutRecord(const std::string &tempFile = EMPTY_STRING,
268                  const std::string &mode = EMPTY_STRING);
269 
270     bool Start();
271     std::string Stop();
272 
273 private:
274     OHOS::UniqueFd stdoutFile_;       // back and restore stdout
275     std::FILE *recordFile_ = nullptr; // save the output
276     bool stop_ = true;
277     std::string content_ = EMPTY_STRING;
278 };
279 
280 // misc
281 template<class T>
Percentage(const T & a,const T & b)282 float Percentage(const T &a, const T &b)
283 {
284     return static_cast<float>(a) / static_cast<float>(b) * FULL_PERCENTAGE;
285 }
286 
287 bool IsRoot();
288 bool PowerOfTwo(uint64_t n);
289 
290 #define INDENT_ONE_LEVEL (indent + 1)
291 #define INDENT_TWO_LEVEL (indent + 2)
292 
293 #define PrintIndent(indent, format, ...)                                                           \
294     if (indent >= 0) {                                                                             \
295         printf("%*s" format, (indent)*2, "", ##__VA_ARGS__);                                       \
296     } else {                                                                                       \
297         HLOGV("%s" format, "", ##__VA_ARGS__);                                                     \
298     }
299 
300 #ifndef MMAP_FAILED
301 #define MMAP_FAILED reinterpret_cast<void *>(-1)
302 #endif
303 #ifndef MAP_FAILED
304 #define MAP_FAILED MMAP_FAILED
305 #endif
306 
307 int GetProcessorNum();  // get number of processors
308 bool IsExistDebugByPid(const std::vector<pid_t> pids);
309 std::string GetProcessName(int pid);
310 bool IsDebugableApp(const std::string& bundleName);
311 } // namespace HiPerf
312 } // namespace Developtools
313 } // namespace OHOS
314 
315 // this will also used for libunwind head (out of namespace)
316 #if is_mingw
317 #if !is_double_framework
318 #define HAVE_MMAP   1
319 #define MAP_PRIVATE 0x02
320 #define PROT_NONE   0
321 #define PROT_READ   1
322 #define PROT_WRITE  2
323 #define PROT_EXEC   4
324 void *mmap(void *addr, size_t length, int prot, int flags, int fd, size_t offset);
325 int munmap(void *addr, size_t);
326 #endif
327 #endif
328 
329 #endif // HIPERF_UTILITIES_H_
330