• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
16 #ifdef _WIN32
17 #include <io.h>
18 #else
19 #include <unistd.h>
20 #endif
21 #include <sys/stat.h>
22 #include <ctime>
23 #include <sstream>
24 #include "ecmascript/dfx/hprof/rawheap_translate/utils.h"
25 
26 namespace rawheap_translate {
CheckVersion(const std::string & version)27 bool CheckVersion(const std::string &version)
28 {
29     std::vector<int> result {};
30     std::stringstream ss(version);
31     std::string token;
32     while (getline(ss, token, '.')) {
33         int number;
34         std::istringstream(token) >> number;
35         result.push_back(number);
36     }
37 
38     // 3: means the version format is x.x.x
39     if (result.size() != 3) {
40         LOG_ERROR("current version " + version + " is illegal!");
41         return false;
42     }
43 
44     bool majorVersionCheckFalse = result[MAJOR_VERSION_INDEX] > VERSION[MAJOR_VERSION_INDEX];
45     bool minorVersionCheckFalse = result[MAJOR_VERSION_INDEX] == VERSION[MAJOR_VERSION_INDEX] &&
46                                   result[MINOR_VERSION_INDEX] > VERSION[MINOR_VERSION_INDEX];
47     bool buildVersionCheckFalse = result[MAJOR_VERSION_INDEX] == VERSION[MAJOR_VERSION_INDEX] &&
48                                   result[MINOR_VERSION_INDEX] == VERSION[MINOR_VERSION_INDEX] &&
49                                   result[BUILD_VERSION_INDEX] > VERSION[BUILD_VERSION_INDEX];
50     if (majorVersionCheckFalse || minorVersionCheckFalse || buildVersionCheckFalse) {
51         std::ostringstream oss;
52         oss << "The rawheap file's version " << version;
53         oss << " is not matched the current rawheap translator, please use the newest version of the translator!";
54         LOG_ERROR(oss.str());
55         return false;
56     };
57     return true;
58 }
59 
RealPath(const std::string & filename,std::string & realpath)60 bool RealPath(const std::string &filename, std::string &realpath)
61 {
62     if (filename.empty() || filename.size() > PATH_MAX) {
63         LOG_ERROR("filename is illegal!");
64         return false;
65     }
66 
67 #ifdef _WIN32
68     if (_access(filename.c_str(), 0) < 0) {
69 #else
70     if (access(filename.c_str(), 0) < 0) {
71 #endif
72         LOG_ERROR("file can not access! filePath=" + filename);
73         return false;
74     }
75 
76     char resolvedPath[PATH_MAX];
77     if (strcpy_s(resolvedPath, PATH_MAX, filename.c_str()) != 0) {
78         return false;
79     }
80 
81     realpath = resolvedPath;
82     return true;
83 }
84 
85 uint64_t GetFileSize(std::string &inputFilePath)
86 {
87     if (inputFilePath.empty()) {
88         return 0;
89     }
90     struct stat fileInfo;
91     if (stat(inputFilePath.c_str(), &fileInfo) == 0) {
92         return fileInfo.st_size;
93     }
94     return 0;
95 }
96 
97 bool FileCheckAndOpenBinary(const std::string &rawheapPath, std::ifstream &file, uint32_t &fileSize)
98 {
99     std::string realpath {};
100     if (!RealPath(rawheapPath, realpath)) {
101         LOG_ERROR("file path is illegal! filePath: " + rawheapPath);
102         return false;
103     }
104 
105     uint64_t size = GetFileSize(realpath);
106     if (size == 0 || size >= MAX_FILE_SIZE) {
107         LOG_ERROR("file size >= 4GB or size = 0, unsupported!");
108         return false;
109     }
110 
111     fileSize = static_cast<uint32_t>(size);
112     file.open(realpath, std::ios::binary);
113     return true;
114 }
115 
116 bool GenerateDumpFileName(std::string &filename)
117 {
118     std::time_t t = std::time(nullptr);
119     struct tm *now = localtime(&t);
120     if (now == nullptr) {
121         LOG_ERROR("Failed to converting time to local time!");
122         return false;
123     }
124 
125     filename = "hprof_";
126     const int timeStart = 1900;  // 1900: means the start of timestamp
127     filename += std::to_string(now->tm_year + timeStart);
128     filename += '-' + std::to_string(now->tm_mon + 1);
129     filename += '-' + std::to_string(now->tm_mday);
130     filename += '-' + std::to_string(now->tm_hour);
131     filename += '-' + std::to_string(now->tm_min);
132     filename += '-' + std::to_string(now->tm_sec);
133     filename += ".heapsnapshot";
134     return true;
135 }
136 
137 bool EndsWith(const std::string &str, const std::string &suffix)
138 {
139     if (str.length() < suffix.length()) {
140         return false;
141     }
142     std::string subStr = str.substr(str.length() - suffix.length(), str.length());
143     return subStr == suffix;
144 }
145 
146 bool IsLittleEndian()
147 {
148     int i = 1;
149     return *reinterpret_cast<char *>(&i) == 1;
150 }
151 
152 uint32_t ByteToU32(char *data)
153 {
154     uint32_t value = *reinterpret_cast<uint32_t *>(data);
155     if (!IsLittleEndian()) {
156         value = (value & 0x000000FF) << 24 |
157                 (value & 0x0000FF00) << 8 |
158                 (value & 0x00FF0000) >> 8 |
159                 (value & 0xFF000000) >> 24;
160     }
161     return value;
162 }
163 
164 uint64_t ByteToU64(char *data)
165 {
166     uint64_t value = *reinterpret_cast<uint64_t *>(data);
167     if (!IsLittleEndian()) {
168         value = (value & 0x00000000000000FF) << 56 |
169                 (value & 0x000000000000FF00) << 40 |
170                 (value & 0x0000000000FF0000) << 24 |
171                 (value & 0x00000000FF000000) << 8 |
172                 (value & 0x000000FF00000000) >> 8 |
173                 (value & 0x0000FF00000000) >> 24 |
174                 (value & 0x00FF0000000000) >> 40 |
175                 (value & 0xFF000000000000) >> 56;
176     }
177     return value;
178 }
179 
180 void ByteToU32Array(char *data, uint32_t *array, uint32_t size)
181 {
182     char *num = data;
183     for (uint32_t i = 0; i < size; i++) {
184         array[i] = ByteToU32(num);
185         num += sizeof(uint32_t);
186     }
187 }
188 
189 void ByteToU64Array(char *data, uint64_t *array, uint32_t size)
190 {
191     char *num = data;
192     for (uint32_t i = 0; i < size; i++) {
193         array[i] = ByteToU64(num);
194         num += sizeof(uint64_t);
195     }
196 }
197 } // namespace rawheap_translate