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