106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci#ifndef HIPERF_UTILITIES_H_ 1606f6ba60Sopenharmony_ci#define HIPERF_UTILITIES_H_ 1706f6ba60Sopenharmony_ci 1806f6ba60Sopenharmony_ci// for security function 1906f6ba60Sopenharmony_ci#include <securec.h> 2006f6ba60Sopenharmony_ci 2106f6ba60Sopenharmony_ci#include <algorithm> 2206f6ba60Sopenharmony_ci#include <cctype> 2306f6ba60Sopenharmony_ci#include <cinttypes> 2406f6ba60Sopenharmony_ci#include <cstdio> 2506f6ba60Sopenharmony_ci#include <fstream> 2606f6ba60Sopenharmony_ci#include <iomanip> 2706f6ba60Sopenharmony_ci#include <iostream> 2806f6ba60Sopenharmony_ci#include <sstream> 2906f6ba60Sopenharmony_ci#include <string> 3006f6ba60Sopenharmony_ci#include <vector> 3106f6ba60Sopenharmony_ci#include <unordered_set> 3206f6ba60Sopenharmony_ci 3306f6ba60Sopenharmony_ci#include <dirent.h> 3406f6ba60Sopenharmony_ci#include <fcntl.h> 3506f6ba60Sopenharmony_ci#include <file_ex.h> 3606f6ba60Sopenharmony_ci#include <stddef.h> 3706f6ba60Sopenharmony_ci#include <sys/stat.h> 3806f6ba60Sopenharmony_ci#include <unique_fd.h> 3906f6ba60Sopenharmony_ci#include <unistd.h> 4006f6ba60Sopenharmony_ci#if !is_mingw 4106f6ba60Sopenharmony_ci#include <sys/syscall.h> 4206f6ba60Sopenharmony_ci#endif 4306f6ba60Sopenharmony_ci#include <linux/types.h> 4406f6ba60Sopenharmony_ci 4506f6ba60Sopenharmony_ci#include "debug_logger.h" 4606f6ba60Sopenharmony_ci#include "noncopyable.h" 4706f6ba60Sopenharmony_ci 4806f6ba60Sopenharmony_ci// data and value 4906f6ba60Sopenharmony_ci/* 5006f6ba60Sopenharmony_cilong long always 64 only in ILP64, int is 64 otherwise int is always 32 5106f6ba60Sopenharmony_ci*/ 5206f6ba60Sopenharmony_ciusing s8 = __s8; 5306f6ba60Sopenharmony_ciusing u8 = __u8; 5406f6ba60Sopenharmony_ciusing s16 = __s16; 5506f6ba60Sopenharmony_ciusing u16 = __u16; 5606f6ba60Sopenharmony_ciusing s32 = __s32; 5706f6ba60Sopenharmony_ciusing u32 = __u32; 5806f6ba60Sopenharmony_ciusing s64 = __s64; 5906f6ba60Sopenharmony_ciusing u64 = __u64; 6006f6ba60Sopenharmony_ci 6106f6ba60Sopenharmony_ciconstexpr const int NUMBER_FORMAT_HEX_BASE = 16; 6206f6ba60Sopenharmony_ciconstexpr const int BYTE_PRINT_WIDTH = 2; 6306f6ba60Sopenharmony_ciconstexpr const int UINT64_PRINT_WIDTH = BYTE_PRINT_WIDTH * 8; 6406f6ba60Sopenharmony_ciconstexpr const int BITS_OF_BYTE = 8; 6506f6ba60Sopenharmony_ciconstexpr const int BITS_OF_TWO_BYTE = 2 * BITS_OF_BYTE; 6606f6ba60Sopenharmony_ciconstexpr const int BITS_OF_FOUR_BYTE = 4 * BITS_OF_BYTE; 6706f6ba60Sopenharmony_ciconstexpr const int FULL_PERCENTAGE = 100; 6806f6ba60Sopenharmony_ciconstexpr const int FULL_PERCENTAGE_NUM_LEN = 5; // 100.00 6906f6ba60Sopenharmony_ciconstexpr const int FULL_PERCENTAGE_DIFF_NUM_LEN = 6; // +100.00 7006f6ba60Sopenharmony_ciconstexpr const int FULL_PERCENTAGE_LEN = 6; // 100.00% 7106f6ba60Sopenharmony_ciconstexpr const int FULL_PERCENTAGE_DIFF_LEN = 7; // +100.00% 7206f6ba60Sopenharmony_ciconstexpr const int THOUSANDS = 1000; 7306f6ba60Sopenharmony_ciconstexpr const int HUNDREDS = 100; 7406f6ba60Sopenharmony_ciconstexpr const int DEFAULT_STRING_BUF_SIZE = 4096; 7506f6ba60Sopenharmony_ciconstexpr const int FIVE_THOUSANDS = 5000; 7606f6ba60Sopenharmony_ci#if !is_mingw 7706f6ba60Sopenharmony_ci#ifndef O_BINARY 7806f6ba60Sopenharmony_ci#define O_BINARY 0 7906f6ba60Sopenharmony_ci#endif 8006f6ba60Sopenharmony_ci#endif 8106f6ba60Sopenharmony_ci 8206f6ba60Sopenharmony_ciconstexpr const double MS_DUARTION = 8306f6ba60Sopenharmony_ci static_cast<double>(std::chrono::milliseconds::duration::period::den); 8406f6ba60Sopenharmony_ci 8506f6ba60Sopenharmony_ciconstexpr uint64_t KILO = 1024; 8606f6ba60Sopenharmony_ci 8706f6ba60Sopenharmony_cinamespace OHOS { 8806f6ba60Sopenharmony_cinamespace Developtools { 8906f6ba60Sopenharmony_cinamespace NativeDaemon { 9006f6ba60Sopenharmony_cinamespace { 9106f6ba60Sopenharmony_ciconst std::string EMPTY_STRING = ""; 9206f6ba60Sopenharmony_ciconstexpr int32_t STRING_POOL_SIZE = 4000; 9306f6ba60Sopenharmony_ci} 9406f6ba60Sopenharmony_ci 9506f6ba60Sopenharmony_ci// string function 9606f6ba60Sopenharmony_ciclass StringViewMemoryHold { 9706f6ba60Sopenharmony_cipublic: 9806f6ba60Sopenharmony_ci const char *HoldStringView(const std::string& view) 9906f6ba60Sopenharmony_ci { 10006f6ba60Sopenharmony_ci pthread_spin_lock(&spin_lock_); 10106f6ba60Sopenharmony_ci const char* str = stringSet_.emplace(view).first->data(); 10206f6ba60Sopenharmony_ci pthread_spin_unlock(&spin_lock_); 10306f6ba60Sopenharmony_ci return str; 10406f6ba60Sopenharmony_ci }; 10506f6ba60Sopenharmony_ci 10606f6ba60Sopenharmony_ci static StringViewMemoryHold& GetInstance() 10706f6ba60Sopenharmony_ci { 10806f6ba60Sopenharmony_ci static StringViewMemoryHold s; 10906f6ba60Sopenharmony_ci return s; 11006f6ba60Sopenharmony_ci } 11106f6ba60Sopenharmony_ci 11206f6ba60Sopenharmony_ci void Clear() 11306f6ba60Sopenharmony_ci { 11406f6ba60Sopenharmony_ci pthread_spin_lock(&spin_lock_); 11506f6ba60Sopenharmony_ci stringSet_.clear(); 11606f6ba60Sopenharmony_ci pthread_spin_unlock(&spin_lock_); 11706f6ba60Sopenharmony_ci } 11806f6ba60Sopenharmony_ci 11906f6ba60Sopenharmony_ciprivate: 12006f6ba60Sopenharmony_ci StringViewMemoryHold() 12106f6ba60Sopenharmony_ci { 12206f6ba60Sopenharmony_ci pthread_spin_init(&spin_lock_, PTHREAD_PROCESS_PRIVATE); 12306f6ba60Sopenharmony_ci } 12406f6ba60Sopenharmony_ci ~StringViewMemoryHold() 12506f6ba60Sopenharmony_ci { 12606f6ba60Sopenharmony_ci pthread_spin_destroy(&spin_lock_); 12706f6ba60Sopenharmony_ci } 12806f6ba60Sopenharmony_ci std::unordered_set<std::string> stringSet_{STRING_POOL_SIZE}; 12906f6ba60Sopenharmony_ci pthread_spinlock_t spin_lock_; 13006f6ba60Sopenharmony_ci}; 13106f6ba60Sopenharmony_ci 13206f6ba60Sopenharmony_cistd::string StringReplace(std::string source, const std::string &from, const std::string &to); 13306f6ba60Sopenharmony_ci 13406f6ba60Sopenharmony_citemplate<class T> 13506f6ba60Sopenharmony_cistd::string VectorToString(const std::vector<T> &items) 13606f6ba60Sopenharmony_ci{ 13706f6ba60Sopenharmony_ci if constexpr (std::is_same<T, std::vector<std::string>>::value) { 13806f6ba60Sopenharmony_ci std::vector<std::string> stringItems; 13906f6ba60Sopenharmony_ci for (auto item : items) { 14006f6ba60Sopenharmony_ci stringItems.push_back("[" + VectorToString(item) + "]"); 14106f6ba60Sopenharmony_ci } 14206f6ba60Sopenharmony_ci return VectorToString(stringItems); 14306f6ba60Sopenharmony_ci } else { 14406f6ba60Sopenharmony_ci std::string itemsString; 14506f6ba60Sopenharmony_ci const std::string split = ","; 14606f6ba60Sopenharmony_ci for (auto& item : items) { 14706f6ba60Sopenharmony_ci if (!itemsString.empty()) 14806f6ba60Sopenharmony_ci itemsString.append(split); 14906f6ba60Sopenharmony_ci if constexpr (std::is_same<T, std::string>::value) { 15006f6ba60Sopenharmony_ci itemsString.append(item); 15106f6ba60Sopenharmony_ci } else { 15206f6ba60Sopenharmony_ci itemsString.append(std::to_string(item)); 15306f6ba60Sopenharmony_ci } 15406f6ba60Sopenharmony_ci } 15506f6ba60Sopenharmony_ci if (itemsString.empty()) 15606f6ba60Sopenharmony_ci itemsString.append("<empty>"); 15706f6ba60Sopenharmony_ci return itemsString; 15806f6ba60Sopenharmony_ci } 15906f6ba60Sopenharmony_ci} 16006f6ba60Sopenharmony_ci 16106f6ba60Sopenharmony_cistd::string BufferToHexString(const std::vector<unsigned char> &vec); 16206f6ba60Sopenharmony_cistd::string BufferToHexString(const unsigned char buf[], size_t size); 16306f6ba60Sopenharmony_civoid HexDump(const uint8_t *buf, size_t size, size_t max_size = 0); 16406f6ba60Sopenharmony_ci 16506f6ba60Sopenharmony_cistd::string &StringTrim(std::string &s); 16606f6ba60Sopenharmony_ci 16706f6ba60Sopenharmony_cistd::vector<std::string> StringSplit(std::string source, std::string split = ","); 16806f6ba60Sopenharmony_ci 16906f6ba60Sopenharmony_civoid AdvancedSplitString(const std::string_view& str, const std::string& delimiters, std::vector<std::string>& elems); 17006f6ba60Sopenharmony_ci 17106f6ba60Sopenharmony_cisize_t SubStringCount(const std::string &source, const std::string &sub); 17206f6ba60Sopenharmony_ci 17306f6ba60Sopenharmony_cibool StringStartsWith(const std::string &string, const std::string &with); 17406f6ba60Sopenharmony_ci 17506f6ba60Sopenharmony_cibool StringEndsWith(const std::string &string, const std::string &with); 17606f6ba60Sopenharmony_ci 17706f6ba60Sopenharmony_cibool IsSameCommand(std::string cmdLine, std::string cmdName); 17806f6ba60Sopenharmony_ci 17906f6ba60Sopenharmony_cistd::vector<pid_t> GetSubthreadIDs(const pid_t pid); 18006f6ba60Sopenharmony_ci 18106f6ba60Sopenharmony_cibool IsDigits(const std::string &str); 18206f6ba60Sopenharmony_ci 18306f6ba60Sopenharmony_cibool IsHexDigits(const std::string &str); 18406f6ba60Sopenharmony_ci 18506f6ba60Sopenharmony_ciconstexpr const int COMPRESS_READ_BUF_SIZE = 4096; 18606f6ba60Sopenharmony_ci// compress specified dataFile into gzip file 18706f6ba60Sopenharmony_cibool CompressFile(const std::string &dataFile, const std::string &destFile); 18806f6ba60Sopenharmony_ci// uncompress specified gzip file into dataFile 18906f6ba60Sopenharmony_cibool UncompressFile(const std::string &gzipFile, const std::string &dataFile); 19006f6ba60Sopenharmony_ci 19106f6ba60Sopenharmony_citemplate<typename... VA> 19206f6ba60Sopenharmony_cistd::string StringPrintf(const char *stringFormat, VA... args) 19306f6ba60Sopenharmony_ci{ 19406f6ba60Sopenharmony_ci // check howmany bytes we need 19506f6ba60Sopenharmony_ci char bytes[DEFAULT_STRING_BUF_SIZE]; 19606f6ba60Sopenharmony_ci bytes[DEFAULT_STRING_BUF_SIZE - 1] = '\0'; 19706f6ba60Sopenharmony_ci 19806f6ba60Sopenharmony_ci if (stringFormat == nullptr) { 19906f6ba60Sopenharmony_ci return EMPTY_STRING; 20006f6ba60Sopenharmony_ci } 20106f6ba60Sopenharmony_ci 20206f6ba60Sopenharmony_ci // print it to bytes 20306f6ba60Sopenharmony_ci if (snprintf_s(bytes, sizeof(bytes), DEFAULT_STRING_BUF_SIZE - 1, stringFormat, args...) < 0) { 20406f6ba60Sopenharmony_ci return EMPTY_STRING; 20506f6ba60Sopenharmony_ci } 20606f6ba60Sopenharmony_ci 20706f6ba60Sopenharmony_ci // make a string return 20806f6ba60Sopenharmony_ci return std::string(bytes); 20906f6ba60Sopenharmony_ci} 21006f6ba60Sopenharmony_ci 21106f6ba60Sopenharmony_ci// path check 21206f6ba60Sopenharmony_cistd::vector<std::string> GetEntriesInDir(const std::string &basePath); 21306f6ba60Sopenharmony_ci 21406f6ba60Sopenharmony_cistd::vector<std::string> GetSubDirs(const std::string &basePath); 21506f6ba60Sopenharmony_ci 21606f6ba60Sopenharmony_cibool IsDir(const std::string &path); 21706f6ba60Sopenharmony_ci 21806f6ba60Sopenharmony_cibool IsPath(const std::string &fileName); 21906f6ba60Sopenharmony_ci 22006f6ba60Sopenharmony_ci#if is_mingw 22106f6ba60Sopenharmony_ciconst char PATH_SEPARATOR = '\\'; 22206f6ba60Sopenharmony_ci#else 22306f6ba60Sopenharmony_ciconst char PATH_SEPARATOR = '/'; 22406f6ba60Sopenharmony_ci#endif 22506f6ba60Sopenharmony_ciconst std::string PATH_SEPARATOR_STR = std::string(1, PATH_SEPARATOR); 22606f6ba60Sopenharmony_ci 22706f6ba60Sopenharmony_cistd::string PlatformPathConvert(const std::string &path); 22806f6ba60Sopenharmony_ci 22906f6ba60Sopenharmony_ci// attribute 23006f6ba60Sopenharmony_ci#define PACKED __attribute__((packed)) 23106f6ba60Sopenharmony_ci 23206f6ba60Sopenharmony_ci// data align 23306f6ba60Sopenharmony_ci 23406f6ba60Sopenharmony_ci// some time u will meet signal 7 (SIGBUS), code 1 (BUS_ADRALN) in 32 or 64 arch cpu 23506f6ba60Sopenharmony_ci#define HIPERF_BUF_ALIGN alignas(64) 23606f6ba60Sopenharmony_ci 23706f6ba60Sopenharmony_ciuint32_t RoundUp(uint32_t x, const int align); 23806f6ba60Sopenharmony_ci 23906f6ba60Sopenharmony_ci// data convert funcion 24006f6ba60Sopenharmony_citemplate<class T> 24106f6ba60Sopenharmony_cistd::string ToHex(const T &source, int size = sizeof(T), bool perfix = false) 24206f6ba60Sopenharmony_ci{ 24306f6ba60Sopenharmony_ci std::stringstream ss; 24406f6ba60Sopenharmony_ci if (perfix) { 24506f6ba60Sopenharmony_ci ss << "0x"; 24606f6ba60Sopenharmony_ci } 24706f6ba60Sopenharmony_ci ss << std::hex << std::setw(BYTE_PRINT_WIDTH * size) << std::setfill('0') << (uint64_t)source; 24806f6ba60Sopenharmony_ci return ss.str(); 24906f6ba60Sopenharmony_ci} 25006f6ba60Sopenharmony_ci 25106f6ba60Sopenharmony_ci// data move and copy 25206f6ba60Sopenharmony_citemplate<class S, class T> 25306f6ba60Sopenharmony_cisize_t inline CopyFromBufferAndMove(S *&buffer, T *dest, size_t size = 0) 25406f6ba60Sopenharmony_ci{ 25506f6ba60Sopenharmony_ci if (size == 0) { 25606f6ba60Sopenharmony_ci size = sizeof(T); 25706f6ba60Sopenharmony_ci } 25806f6ba60Sopenharmony_ci if (memcpy_s(dest, size, buffer, size) != EOK) { 25906f6ba60Sopenharmony_ci return size; 26006f6ba60Sopenharmony_ci } 26106f6ba60Sopenharmony_ci buffer = buffer + size; 26206f6ba60Sopenharmony_ci return size; 26306f6ba60Sopenharmony_ci} 26406f6ba60Sopenharmony_ci 26506f6ba60Sopenharmony_ci// file read write 26606f6ba60Sopenharmony_cibool ReadIntFromProcFile(const std::string &path, int &value); 26706f6ba60Sopenharmony_cibool WriteIntToProcFile(const std::string &path, int value); 26806f6ba60Sopenharmony_cistd::string ReadFileToString(const std::string &fileName); 26906f6ba60Sopenharmony_cibool ReadFileToString(const std::string &fileName, std::string &content, size_t fileSize = 0); 27006f6ba60Sopenharmony_cibool WriteStringToFile(const std::string &fileName, const std::string &value); 27106f6ba60Sopenharmony_ci 27206f6ba60Sopenharmony_ci// stdout 27306f6ba60Sopenharmony_ciclass StdoutRecord { 27406f6ba60Sopenharmony_cipublic: 27506f6ba60Sopenharmony_ci ~StdoutRecord() 27606f6ba60Sopenharmony_ci { 27706f6ba60Sopenharmony_ci Stop(); // stdout need restore 27806f6ba60Sopenharmony_ci } 27906f6ba60Sopenharmony_ci StdoutRecord(const std::string &tempFile = EMPTY_STRING, 28006f6ba60Sopenharmony_ci const std::string &mode = EMPTY_STRING); 28106f6ba60Sopenharmony_ci 28206f6ba60Sopenharmony_ci bool Start(); 28306f6ba60Sopenharmony_ci std::string Stop(); 28406f6ba60Sopenharmony_ci 28506f6ba60Sopenharmony_ciprivate: 28606f6ba60Sopenharmony_ci OHOS::UniqueFd stdoutFile_; // back and restore stdout 28706f6ba60Sopenharmony_ci std::FILE *recordFile_ = nullptr; // save the output 28806f6ba60Sopenharmony_ci bool stop_ = true; 28906f6ba60Sopenharmony_ci std::string content_ = EMPTY_STRING; 29006f6ba60Sopenharmony_ci}; 29106f6ba60Sopenharmony_ci 29206f6ba60Sopenharmony_ci// misc 29306f6ba60Sopenharmony_citemplate<class T> 29406f6ba60Sopenharmony_cifloat Percentage(const T &a, const T &b) 29506f6ba60Sopenharmony_ci{ 29606f6ba60Sopenharmony_ci return static_cast<float>(a) / static_cast<float>(b) * FULL_PERCENTAGE; 29706f6ba60Sopenharmony_ci} 29806f6ba60Sopenharmony_ci 29906f6ba60Sopenharmony_cibool IsRoot(); 30006f6ba60Sopenharmony_cibool PowerOfTwo(int n); 30106f6ba60Sopenharmony_ci 30206f6ba60Sopenharmony_ci#define INDENT_ONE_LEVEL (indent + 1) 30306f6ba60Sopenharmony_ci#define INDENT_TWO_LEVEL (indent + 2) 30406f6ba60Sopenharmony_ci 30506f6ba60Sopenharmony_ci#define PrintIndent(indent, format, ...) \ 30606f6ba60Sopenharmony_ci if (indent >= 0) { \ 30706f6ba60Sopenharmony_ci printf("%*s" format, (indent)*2, "", ##__VA_ARGS__); \ 30806f6ba60Sopenharmony_ci } else { \ 30906f6ba60Sopenharmony_ci HLOGV("%s" format, "", ##__VA_ARGS__); \ 31006f6ba60Sopenharmony_ci } 31106f6ba60Sopenharmony_ci 31206f6ba60Sopenharmony_ci#ifndef MMAP_FAILED 31306f6ba60Sopenharmony_ci#define MMAP_FAILED (reinterpret_cast<void *>(-1)) 31406f6ba60Sopenharmony_ci#endif 31506f6ba60Sopenharmony_ci#ifndef MAP_FAILED 31606f6ba60Sopenharmony_ci#define MAP_FAILED MMAP_FAILED 31706f6ba60Sopenharmony_ci#endif 31806f6ba60Sopenharmony_ciint32_t GetProcessPid(const std::string& processName); 31906f6ba60Sopenharmony_cibool IsArkJsFile(const std::string& filepath); 32006f6ba60Sopenharmony_ci} // namespace NativeDaemon 32106f6ba60Sopenharmony_ci} // namespace Developtools 32206f6ba60Sopenharmony_ci} // namespace OHOS 32306f6ba60Sopenharmony_ci 32406f6ba60Sopenharmony_ci// this will also used for libunwind head (out of namespace) 32506f6ba60Sopenharmony_ci#if is_mingw 32606f6ba60Sopenharmony_ci#define HAVE_MMAP 1 32706f6ba60Sopenharmony_ci#define MAP_PRIVATE 0x02 32806f6ba60Sopenharmony_ci#define PROT_NONE 0 32906f6ba60Sopenharmony_ci#define PROT_READ 1 33006f6ba60Sopenharmony_ci#define PROT_WRITE 2 33106f6ba60Sopenharmony_ci#define PROT_EXEC 4 33206f6ba60Sopenharmony_civoid *mmap(void *addr, size_t length, int prot, int flags, int fd, size_t offset); 33306f6ba60Sopenharmony_ciint munmap(void *addr, size_t); 33406f6ba60Sopenharmony_ci#endif 33506f6ba60Sopenharmony_ci 33606f6ba60Sopenharmony_ci#endif 337