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