1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#include "dfx_util.h" 17800b99b8Sopenharmony_ci 18800b99b8Sopenharmony_ci#if defined(is_mingw) && is_mingw 19800b99b8Sopenharmony_ci#include <memoryapi.h> 20800b99b8Sopenharmony_ci#include <windows.h> 21800b99b8Sopenharmony_ci#endif 22800b99b8Sopenharmony_ci#ifndef is_host 23800b99b8Sopenharmony_ci#include <cctype> 24800b99b8Sopenharmony_ci#include <climits> 25800b99b8Sopenharmony_ci#include <cstdio> 26800b99b8Sopenharmony_ci#include <cstdlib> 27800b99b8Sopenharmony_ci#include <cstring> 28800b99b8Sopenharmony_ci#include <ctime> 29800b99b8Sopenharmony_ci#include <securec.h> 30800b99b8Sopenharmony_ci#include <sys/types.h> 31800b99b8Sopenharmony_ci#include <sys/time.h> 32800b99b8Sopenharmony_ci#include <fcntl.h> 33800b99b8Sopenharmony_ci#include <pthread.h> 34800b99b8Sopenharmony_ci#include <unistd.h> 35800b99b8Sopenharmony_ci#include <dirent.h> 36800b99b8Sopenharmony_ci#endif 37800b99b8Sopenharmony_ci#include <sys/stat.h> 38800b99b8Sopenharmony_ci 39800b99b8Sopenharmony_ci#include "dfx_log.h" 40800b99b8Sopenharmony_ci 41800b99b8Sopenharmony_ci#ifdef LOG_DOMAIN 42800b99b8Sopenharmony_ci#undef LOG_DOMAIN 43800b99b8Sopenharmony_ci#define LOG_DOMAIN 0xD002D11 44800b99b8Sopenharmony_ci#endif 45800b99b8Sopenharmony_ci 46800b99b8Sopenharmony_ci#ifdef LOG_TAG 47800b99b8Sopenharmony_ci#undef LOG_TAG 48800b99b8Sopenharmony_ci#define LOG_TAG "DfxUtil" 49800b99b8Sopenharmony_ci#endif 50800b99b8Sopenharmony_ci 51800b99b8Sopenharmony_cinamespace OHOS { 52800b99b8Sopenharmony_cinamespace HiviewDFX { 53800b99b8Sopenharmony_ci#ifndef is_host 54800b99b8Sopenharmony_cibool TrimAndDupStr(const std::string &source, std::string &str) 55800b99b8Sopenharmony_ci{ 56800b99b8Sopenharmony_ci if (source.empty()) { 57800b99b8Sopenharmony_ci return false; 58800b99b8Sopenharmony_ci } 59800b99b8Sopenharmony_ci 60800b99b8Sopenharmony_ci const char *begin = source.data(); 61800b99b8Sopenharmony_ci const char *end = begin + source.size(); 62800b99b8Sopenharmony_ci if (begin == end) { 63800b99b8Sopenharmony_ci DFXLOGE("Source is empty"); 64800b99b8Sopenharmony_ci return false; 65800b99b8Sopenharmony_ci } 66800b99b8Sopenharmony_ci 67800b99b8Sopenharmony_ci while ((begin < end) && isspace(*begin)) { 68800b99b8Sopenharmony_ci begin++; 69800b99b8Sopenharmony_ci } 70800b99b8Sopenharmony_ci 71800b99b8Sopenharmony_ci while ((begin < end) && isspace(*(end - 1))) { 72800b99b8Sopenharmony_ci end--; 73800b99b8Sopenharmony_ci } 74800b99b8Sopenharmony_ci 75800b99b8Sopenharmony_ci if (begin == end) { 76800b99b8Sopenharmony_ci return false; 77800b99b8Sopenharmony_ci } 78800b99b8Sopenharmony_ci 79800b99b8Sopenharmony_ci uint32_t maxStrLen = NAME_BUF_LEN; 80800b99b8Sopenharmony_ci uint32_t offset = static_cast<uint32_t>(end - begin); 81800b99b8Sopenharmony_ci if (maxStrLen > offset) { 82800b99b8Sopenharmony_ci maxStrLen = offset; 83800b99b8Sopenharmony_ci } 84800b99b8Sopenharmony_ci 85800b99b8Sopenharmony_ci str.assign(begin, maxStrLen); 86800b99b8Sopenharmony_ci return true; 87800b99b8Sopenharmony_ci} 88800b99b8Sopenharmony_ci 89800b99b8Sopenharmony_ciuint64_t GetTimeMilliSeconds(void) 90800b99b8Sopenharmony_ci{ 91800b99b8Sopenharmony_ci struct timespec ts; 92800b99b8Sopenharmony_ci (void)clock_gettime(CLOCK_REALTIME, &ts); 93800b99b8Sopenharmony_ci return ((uint64_t)ts.tv_sec * NUMBER_ONE_THOUSAND) + // 1000 : second to millisecond convert ratio 94800b99b8Sopenharmony_ci (((uint64_t)ts.tv_nsec) / NUMBER_ONE_MILLION); // 1000000 : nanosecond to millisecond convert ratio 95800b99b8Sopenharmony_ci} 96800b99b8Sopenharmony_ci 97800b99b8Sopenharmony_ciuint64_t GetAbsTimeMilliSeconds(void) 98800b99b8Sopenharmony_ci{ 99800b99b8Sopenharmony_ci struct timespec ts; 100800b99b8Sopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC, &ts); 101800b99b8Sopenharmony_ci return (static_cast<uint64_t>(ts.tv_sec) * NUMBER_ONE_THOUSAND) + 102800b99b8Sopenharmony_ci (static_cast<uint64_t>(ts.tv_nsec) / NUMBER_ONE_MILLION); 103800b99b8Sopenharmony_ci} 104800b99b8Sopenharmony_ci 105800b99b8Sopenharmony_cistd::string GetCurrentTimeStr(uint64_t current) 106800b99b8Sopenharmony_ci{ 107800b99b8Sopenharmony_ci time_t now = time(nullptr); 108800b99b8Sopenharmony_ci uint64_t millsecond = 0; 109800b99b8Sopenharmony_ci const uint64_t ratio = NUMBER_ONE_THOUSAND; 110800b99b8Sopenharmony_ci if (current > static_cast<uint64_t>(now)) { 111800b99b8Sopenharmony_ci millsecond = current % ratio; 112800b99b8Sopenharmony_ci now = static_cast<time_t>(current / ratio); 113800b99b8Sopenharmony_ci } 114800b99b8Sopenharmony_ci 115800b99b8Sopenharmony_ci auto tm = std::localtime(&now); 116800b99b8Sopenharmony_ci char seconds[128] = {0}; // 128 : time buffer size 117800b99b8Sopenharmony_ci if (tm == nullptr || strftime(seconds, sizeof(seconds) - 1, "%Y-%m-%d %H:%M:%S", tm) == 0) { 118800b99b8Sopenharmony_ci return "invalid timestamp\n"; 119800b99b8Sopenharmony_ci } 120800b99b8Sopenharmony_ci 121800b99b8Sopenharmony_ci char millBuf[256] = {0}; // 256 : milliseconds buffer size 122800b99b8Sopenharmony_ci int ret = snprintf_s(millBuf, sizeof(millBuf), sizeof(millBuf) - 1, 123800b99b8Sopenharmony_ci "%s.%03u\n", seconds, millsecond); 124800b99b8Sopenharmony_ci if (ret <= 0) { 125800b99b8Sopenharmony_ci return "invalid timestamp\n"; 126800b99b8Sopenharmony_ci } 127800b99b8Sopenharmony_ci return std::string(millBuf, strlen(millBuf)); 128800b99b8Sopenharmony_ci} 129800b99b8Sopenharmony_ci 130800b99b8Sopenharmony_cibool ReadDirFiles(const std::string& path, std::vector<std::string>& files) 131800b99b8Sopenharmony_ci{ 132800b99b8Sopenharmony_ci DIR *dir = opendir(path.c_str()); 133800b99b8Sopenharmony_ci if (dir == nullptr) { 134800b99b8Sopenharmony_ci return false; 135800b99b8Sopenharmony_ci } 136800b99b8Sopenharmony_ci 137800b99b8Sopenharmony_ci struct dirent *ent; 138800b99b8Sopenharmony_ci while ((ent = readdir(dir)) != nullptr) { 139800b99b8Sopenharmony_ci // current dir OR parent dir 140800b99b8Sopenharmony_ci if ((strcmp(ent->d_name, ".") == 0) || (strcmp(ent->d_name, "..") == 0)) { 141800b99b8Sopenharmony_ci continue; 142800b99b8Sopenharmony_ci } 143800b99b8Sopenharmony_ci files.emplace_back(std::string(ent->d_name)); 144800b99b8Sopenharmony_ci } 145800b99b8Sopenharmony_ci (void)closedir(dir); 146800b99b8Sopenharmony_ci return (files.size() > 0); 147800b99b8Sopenharmony_ci} 148800b99b8Sopenharmony_ci 149800b99b8Sopenharmony_cibool VerifyFilePath(const std::string& filePath, const std::vector<const std::string>& validPaths) 150800b99b8Sopenharmony_ci{ 151800b99b8Sopenharmony_ci if (validPaths.size() == 0) { 152800b99b8Sopenharmony_ci return true; 153800b99b8Sopenharmony_ci } 154800b99b8Sopenharmony_ci 155800b99b8Sopenharmony_ci for (auto validPath : validPaths) { 156800b99b8Sopenharmony_ci if (filePath.find(validPath) == 0) { 157800b99b8Sopenharmony_ci return true; 158800b99b8Sopenharmony_ci } 159800b99b8Sopenharmony_ci } 160800b99b8Sopenharmony_ci return false; 161800b99b8Sopenharmony_ci} 162800b99b8Sopenharmony_ci 163800b99b8Sopenharmony_civoid ParseSiValue(siginfo_t& si, uint64_t& endTime, int& tid) 164800b99b8Sopenharmony_ci{ 165800b99b8Sopenharmony_ci const int flagOffset = 63; 166800b99b8Sopenharmony_ci if ((reinterpret_cast<uint64_t>(si.si_value.sival_ptr) & (1ULL << flagOffset)) != 0) { 167800b99b8Sopenharmony_ci endTime = reinterpret_cast<uint64_t>(si.si_value.sival_ptr) & (~(1ULL << flagOffset)); 168800b99b8Sopenharmony_ci tid = 0; 169800b99b8Sopenharmony_ci } else { 170800b99b8Sopenharmony_ci endTime = 0; 171800b99b8Sopenharmony_ci tid = si.si_value.sival_int; 172800b99b8Sopenharmony_ci } 173800b99b8Sopenharmony_ci} 174800b99b8Sopenharmony_ci#endif 175800b99b8Sopenharmony_ci 176800b99b8Sopenharmony_cioff_t GetFileSize(const int& fd) 177800b99b8Sopenharmony_ci{ 178800b99b8Sopenharmony_ci off_t fileSize = 0; 179800b99b8Sopenharmony_ci if (fd >= 0) { 180800b99b8Sopenharmony_ci struct stat fileStat; 181800b99b8Sopenharmony_ci if (fstat(fd, &fileStat) == 0) { 182800b99b8Sopenharmony_ci fileSize = fileStat.st_size; 183800b99b8Sopenharmony_ci } 184800b99b8Sopenharmony_ci } 185800b99b8Sopenharmony_ci return fileSize; 186800b99b8Sopenharmony_ci} 187800b99b8Sopenharmony_ci 188800b99b8Sopenharmony_cibool ReadFdToString(int fd, std::string& content) 189800b99b8Sopenharmony_ci{ 190800b99b8Sopenharmony_ci content.clear(); 191800b99b8Sopenharmony_ci struct stat sb; 192800b99b8Sopenharmony_ci if (fstat(fd, &sb) != -1 && sb.st_size > 0) { 193800b99b8Sopenharmony_ci content.reserve(sb.st_size); 194800b99b8Sopenharmony_ci } 195800b99b8Sopenharmony_ci 196800b99b8Sopenharmony_ci char buf[BUFSIZ] __attribute__((__uninitialized__)); 197800b99b8Sopenharmony_ci ssize_t n; 198800b99b8Sopenharmony_ci while ((n = OHOS_TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) { 199800b99b8Sopenharmony_ci content.append(buf, n); 200800b99b8Sopenharmony_ci } 201800b99b8Sopenharmony_ci return (n == 0); 202800b99b8Sopenharmony_ci} 203800b99b8Sopenharmony_ci} // namespace HiviewDFX 204800b99b8Sopenharmony_ci} // namespace OHOS 205800b99b8Sopenharmony_ci 206800b99b8Sopenharmony_ci// this will also used for libunwinder head (out of namespace) 207800b99b8Sopenharmony_ci#if defined(is_mingw) && is_mingw 208800b99b8Sopenharmony_cistd::string GetLastErrorString() 209800b99b8Sopenharmony_ci{ 210800b99b8Sopenharmony_ci LPVOID lpMsgBuf; 211800b99b8Sopenharmony_ci FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | 212800b99b8Sopenharmony_ci FORMAT_MESSAGE_IGNORE_INSERTS, 213800b99b8Sopenharmony_ci NULL, GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, NULL); 214800b99b8Sopenharmony_ci std::string error((LPTSTR)lpMsgBuf); 215800b99b8Sopenharmony_ci LocalFree(lpMsgBuf); 216800b99b8Sopenharmony_ci return error; 217800b99b8Sopenharmony_ci} 218800b99b8Sopenharmony_ci 219800b99b8Sopenharmony_civoid *mmap(void *addr, size_t length, int prot, int flags, int fd, size_t offset) 220800b99b8Sopenharmony_ci{ 221800b99b8Sopenharmony_ci HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(fd)); 222800b99b8Sopenharmony_ci if (FileHandle == INVALID_HANDLE_VALUE) { 223800b99b8Sopenharmony_ci return MMAP_FAILED; 224800b99b8Sopenharmony_ci } 225800b99b8Sopenharmony_ci 226800b99b8Sopenharmony_ci DFXLOGD("fd is %{public}d", fd); 227800b99b8Sopenharmony_ci 228800b99b8Sopenharmony_ci HANDLE FileMappingHandle = ::CreateFileMappingW(FileHandle, 0, PAGE_READONLY, 0, 0, 0); 229800b99b8Sopenharmony_ci if (FileMappingHandle == nullptr) { 230800b99b8Sopenharmony_ci DFXLOGE("CreateFileMappingW %{public}zu Failed with %{public}ld:%{public}s", 231800b99b8Sopenharmony_ci length, GetLastError(), GetLastErrorString().c_str()); 232800b99b8Sopenharmony_ci return MMAP_FAILED; 233800b99b8Sopenharmony_ci } 234800b99b8Sopenharmony_ci 235800b99b8Sopenharmony_ci void *mapAddr = ::MapViewOfFile(FileMappingHandle, FILE_MAP_READ, 0, 0, 0); 236800b99b8Sopenharmony_ci if (mapAddr == nullptr) { 237800b99b8Sopenharmony_ci DFXLOGE("MapViewOfFile %{public}zu Failed with %{public}ld:%{public}s", 238800b99b8Sopenharmony_ci length, GetLastError(), GetLastErrorString().c_str()); 239800b99b8Sopenharmony_ci return MMAP_FAILED; 240800b99b8Sopenharmony_ci } 241800b99b8Sopenharmony_ci 242800b99b8Sopenharmony_ci // Close all the handles except for the view. It will keep the other handles 243800b99b8Sopenharmony_ci // alive. 244800b99b8Sopenharmony_ci ::CloseHandle(FileMappingHandle); 245800b99b8Sopenharmony_ci return mapAddr; 246800b99b8Sopenharmony_ci} 247800b99b8Sopenharmony_ci 248800b99b8Sopenharmony_ciint munmap(void *addr, size_t) 249800b99b8Sopenharmony_ci{ 250800b99b8Sopenharmony_ci /* 251800b99b8Sopenharmony_ci On success, munmap() returns 0. On failure, it returns -1, and 252800b99b8Sopenharmony_ci errno is set to indicate the error (probably to EINVAL). 253800b99b8Sopenharmony_ci 254800b99b8Sopenharmony_ci UnmapViewOfFile function (memoryapi.h) 255800b99b8Sopenharmony_ci 256800b99b8Sopenharmony_ci If the function succeeds, the return value is nonzero. 257800b99b8Sopenharmony_ci If the function fails, the return value is zero. To get extended error information, call 258800b99b8Sopenharmony_ci GetLastError. 259800b99b8Sopenharmony_ci */ 260800b99b8Sopenharmony_ci return !UnmapViewOfFile(addr); 261800b99b8Sopenharmony_ci} 262800b99b8Sopenharmony_ci#endif 263